Add ConnectivityManager.getActiveNetwork().
Rework NetID allocation in ConnectivityService so registerNetworkAgent() can return the allocated NetID. Bug: 19416463 Change-Id: I68e395552cf27422c80b4dfae5db5d56a0d68f5d
This commit is contained in:
@ -16955,6 +16955,7 @@ package android.net {
|
|||||||
public class ConnectivityManager {
|
public class ConnectivityManager {
|
||||||
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
|
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
|
||||||
method public boolean bindProcessToNetwork(android.net.Network);
|
method public boolean bindProcessToNetwork(android.net.Network);
|
||||||
|
method public android.net.Network getActiveNetwork();
|
||||||
method public android.net.NetworkInfo getActiveNetworkInfo();
|
method public android.net.NetworkInfo getActiveNetworkInfo();
|
||||||
method public android.net.NetworkInfo[] getAllNetworkInfo();
|
method public android.net.NetworkInfo[] getAllNetworkInfo();
|
||||||
method public android.net.Network[] getAllNetworks();
|
method public android.net.Network[] getAllNetworks();
|
||||||
|
@ -18216,6 +18216,7 @@ package android.net {
|
|||||||
public class ConnectivityManager {
|
public class ConnectivityManager {
|
||||||
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
|
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
|
||||||
method public boolean bindProcessToNetwork(android.net.Network);
|
method public boolean bindProcessToNetwork(android.net.Network);
|
||||||
|
method public android.net.Network getActiveNetwork();
|
||||||
method public android.net.NetworkInfo getActiveNetworkInfo();
|
method public android.net.NetworkInfo getActiveNetworkInfo();
|
||||||
method public android.net.NetworkInfo[] getAllNetworkInfo();
|
method public android.net.NetworkInfo[] getAllNetworkInfo();
|
||||||
method public android.net.Network[] getAllNetworks();
|
method public android.net.Network[] getAllNetworks();
|
||||||
|
@ -601,6 +601,27 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link Network} object corresponding to the currently active
|
||||||
|
* default data network. In the event that the current active default data
|
||||||
|
* network disconnects, the returned {@code Network} object will no longer
|
||||||
|
* be usable. This will return {@code null} when there is no default
|
||||||
|
* network.
|
||||||
|
*
|
||||||
|
* @return a {@link Network} object for the current default network or
|
||||||
|
* {@code null} if no default network is currently active
|
||||||
|
*
|
||||||
|
* <p>This method requires the caller to hold the permission
|
||||||
|
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
|
||||||
|
*/
|
||||||
|
public Network getActiveNetwork() {
|
||||||
|
try {
|
||||||
|
return mService.getActiveNetwork();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns details about the currently active default data network
|
* Returns details about the currently active default data network
|
||||||
* for a given uid. This is for internal use only to avoid spying
|
* for a given uid. This is for internal use only to avoid spying
|
||||||
@ -1927,12 +1948,18 @@ public class ConnectivityManager {
|
|||||||
} catch (RemoteException e) { }
|
} catch (RemoteException e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@hide} */
|
/**
|
||||||
public void registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
|
* @hide
|
||||||
|
* Register a NetworkAgent with ConnectivityService.
|
||||||
|
* @return NetID corresponding to NetworkAgent.
|
||||||
|
*/
|
||||||
|
public int registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
|
||||||
NetworkCapabilities nc, int score, NetworkMisc misc) {
|
NetworkCapabilities nc, int score, NetworkMisc misc) {
|
||||||
try {
|
try {
|
||||||
mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
|
return mService.registerNetworkAgent(messenger, ni, lp, nc, score, misc);
|
||||||
} catch (RemoteException e) { }
|
} catch (RemoteException e) {
|
||||||
|
return NETID_UNSET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +42,7 @@ import com.android.internal.net.VpnProfile;
|
|||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
interface IConnectivityManager
|
interface IConnectivityManager
|
||||||
{
|
{
|
||||||
|
Network getActiveNetwork();
|
||||||
NetworkInfo getActiveNetworkInfo();
|
NetworkInfo getActiveNetworkInfo();
|
||||||
NetworkInfo getActiveNetworkInfoForUid(int uid);
|
NetworkInfo getActiveNetworkInfoForUid(int uid);
|
||||||
NetworkInfo getNetworkInfo(int networkType);
|
NetworkInfo getNetworkInfo(int networkType);
|
||||||
@ -132,7 +133,7 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
void unregisterNetworkFactory(in Messenger messenger);
|
void unregisterNetworkFactory(in Messenger messenger);
|
||||||
|
|
||||||
void registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
|
int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
|
||||||
in NetworkCapabilities nc, int score, in NetworkMisc misc);
|
in NetworkCapabilities nc, int score, in NetworkMisc misc);
|
||||||
|
|
||||||
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
|
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
|
||||||
|
@ -42,6 +42,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public abstract class NetworkAgent extends Handler {
|
public abstract class NetworkAgent extends Handler {
|
||||||
|
// Guaranteed to be valid (not NETID_UNSET), otherwise registerNetworkAgent() would have thrown
|
||||||
|
// an exception.
|
||||||
|
public final int netId;
|
||||||
|
|
||||||
private volatile AsyncChannel mAsyncChannel;
|
private volatile AsyncChannel mAsyncChannel;
|
||||||
private final String LOG_TAG;
|
private final String LOG_TAG;
|
||||||
private static final boolean DBG = true;
|
private static final boolean DBG = true;
|
||||||
@ -142,7 +146,7 @@ public abstract class NetworkAgent extends Handler {
|
|||||||
if (VDBG) log("Registering NetworkAgent");
|
if (VDBG) log("Registering NetworkAgent");
|
||||||
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
|
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
|
||||||
Context.CONNECTIVITY_SERVICE);
|
Context.CONNECTIVITY_SERVICE);
|
||||||
cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
|
netId = cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
|
||||||
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);
|
new LinkProperties(lp), new NetworkCapabilities(nc), score, misc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
|
|||||||
import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
|
import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
|
||||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
|
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
|
||||||
|
import static android.net.ConnectivityManager.NETID_UNSET;
|
||||||
import static android.net.ConnectivityManager.TYPE_NONE;
|
import static android.net.ConnectivityManager.TYPE_NONE;
|
||||||
import static android.net.ConnectivityManager.TYPE_VPN;
|
import static android.net.ConnectivityManager.TYPE_VPN;
|
||||||
import static android.net.ConnectivityManager.getNetworkTypeName;
|
import static android.net.ConnectivityManager.getNetworkTypeName;
|
||||||
@ -89,6 +90,7 @@ import android.telephony.TelephonyManager;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
|
import android.util.SparseBooleanArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
import android.util.Xml;
|
import android.util.Xml;
|
||||||
|
|
||||||
@ -691,16 +693,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return mNextNetworkRequestId++;
|
return mNextNetworkRequestId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignNextNetId(NetworkAgentInfo nai) {
|
private int reserveNetId() {
|
||||||
synchronized (mNetworkForNetId) {
|
synchronized (mNetworkForNetId) {
|
||||||
for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) {
|
for (int i = MIN_NET_ID; i <= MAX_NET_ID; i++) {
|
||||||
int netId = mNextNetId;
|
int netId = mNextNetId;
|
||||||
if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
|
if (++mNextNetId > MAX_NET_ID) mNextNetId = MIN_NET_ID;
|
||||||
// Make sure NetID unused. http://b/16815182
|
// Make sure NetID unused. http://b/16815182
|
||||||
if (mNetworkForNetId.get(netId) == null) {
|
if (!mNetIdInUse.get(netId)) {
|
||||||
nai.network = new Network(netId);
|
mNetIdInUse.put(netId, true);
|
||||||
mNetworkForNetId.put(netId, nai);
|
return netId;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -859,6 +860,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
|
return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Network getActiveNetwork() {
|
||||||
|
enforceAccessPermission();
|
||||||
|
final int uid = Binder.getCallingUid();
|
||||||
|
final int user = UserHandle.getUserId(uid);
|
||||||
|
int vpnNetId = NETID_UNSET;
|
||||||
|
synchronized (mVpns) {
|
||||||
|
final Vpn vpn = mVpns.get(user);
|
||||||
|
if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId();
|
||||||
|
}
|
||||||
|
NetworkAgentInfo nai;
|
||||||
|
if (vpnNetId != NETID_UNSET) {
|
||||||
|
synchronized (mNetworkForNetId) {
|
||||||
|
nai = mNetworkForNetId.get(vpnNetId);
|
||||||
|
}
|
||||||
|
if (nai != null) return nai.network;
|
||||||
|
}
|
||||||
|
nai = getDefaultNetwork();
|
||||||
|
if (nai != null && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) nai = null;
|
||||||
|
return nai != null ? nai.network : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the first Provisioning network.
|
* Find the first Provisioning network.
|
||||||
*
|
*
|
||||||
@ -1942,6 +1965,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (nai != null) {
|
if (nai != null) {
|
||||||
synchronized (mNetworkForNetId) {
|
synchronized (mNetworkForNetId) {
|
||||||
mNetworkForNetId.remove(nai.network.netId);
|
mNetworkForNetId.remove(nai.network.netId);
|
||||||
|
mNetIdInUse.delete(nai.network.netId);
|
||||||
}
|
}
|
||||||
// Just in case.
|
// Just in case.
|
||||||
mLegacyTypeTracker.remove(nai);
|
mLegacyTypeTracker.remove(nai);
|
||||||
@ -1985,6 +2009,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mLegacyTypeTracker.remove(nai);
|
mLegacyTypeTracker.remove(nai);
|
||||||
synchronized (mNetworkForNetId) {
|
synchronized (mNetworkForNetId) {
|
||||||
mNetworkForNetId.remove(nai.network.netId);
|
mNetworkForNetId.remove(nai.network.netId);
|
||||||
|
mNetIdInUse.delete(nai.network.netId);
|
||||||
}
|
}
|
||||||
// Since we've lost the network, go through all the requests that
|
// Since we've lost the network, go through all the requests that
|
||||||
// it was satisfying and see if any other factory can satisfy them.
|
// it was satisfying and see if any other factory can satisfy them.
|
||||||
@ -3369,14 +3394,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
* and the are the highest scored network available.
|
* and the are the highest scored network available.
|
||||||
* the are keyed off the Requests requestId.
|
* the are keyed off the Requests requestId.
|
||||||
*/
|
*/
|
||||||
|
// TODO: Yikes, this is accessed on multiple threads: add synchronization.
|
||||||
private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
|
private final SparseArray<NetworkAgentInfo> mNetworkForRequestId =
|
||||||
new SparseArray<NetworkAgentInfo>();
|
new SparseArray<NetworkAgentInfo>();
|
||||||
|
|
||||||
|
// NOTE: Accessed on multiple threads, must be synchronized on itself.
|
||||||
|
@GuardedBy("mNetworkForNetId")
|
||||||
private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
|
private final SparseArray<NetworkAgentInfo> mNetworkForNetId =
|
||||||
new SparseArray<NetworkAgentInfo>();
|
new SparseArray<NetworkAgentInfo>();
|
||||||
|
// NOTE: Accessed on multiple threads, synchronized with mNetworkForNetId.
|
||||||
|
// An entry is first added to mNetIdInUse, prior to mNetworkForNetId, so
|
||||||
|
// there may not be a strict 1:1 correlation between the two.
|
||||||
|
@GuardedBy("mNetworkForNetId")
|
||||||
|
private final SparseBooleanArray mNetIdInUse = new SparseBooleanArray();
|
||||||
|
|
||||||
// NetworkAgentInfo keyed off its connecting messenger
|
// NetworkAgentInfo keyed off its connecting messenger
|
||||||
// TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
|
// TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
|
||||||
|
// NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
|
||||||
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
|
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
|
||||||
new HashMap<Messenger, NetworkAgentInfo>();
|
new HashMap<Messenger, NetworkAgentInfo>();
|
||||||
|
|
||||||
@ -3391,7 +3425,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return nai == getDefaultNetwork();
|
return nai == getDefaultNetwork();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
|
public int registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
|
||||||
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
|
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
|
||||||
int currentScore, NetworkMisc networkMisc) {
|
int currentScore, NetworkMisc networkMisc) {
|
||||||
enforceConnectivityInternalPermission();
|
enforceConnectivityInternalPermission();
|
||||||
@ -3399,20 +3433,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
|
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
|
||||||
// satisfies mDefaultRequest.
|
// satisfies mDefaultRequest.
|
||||||
NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
|
NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
|
||||||
new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
|
new Network(reserveNetId()), new NetworkInfo(networkInfo), new LinkProperties(
|
||||||
new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler,
|
linkProperties), new NetworkCapabilities(networkCapabilities), currentScore,
|
||||||
new NetworkMisc(networkMisc), mDefaultRequest);
|
mContext, mTrackerHandler, new NetworkMisc(networkMisc), mDefaultRequest);
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
nai.networkMonitor.systemReady = mSystemReady;
|
nai.networkMonitor.systemReady = mSystemReady;
|
||||||
}
|
}
|
||||||
if (DBG) log("registerNetworkAgent " + nai);
|
if (DBG) log("registerNetworkAgent " + nai);
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
|
||||||
|
return nai.network.netId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
|
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
|
||||||
if (VDBG) log("Got NetworkAgent Messenger");
|
if (VDBG) log("Got NetworkAgent Messenger");
|
||||||
mNetworkAgentInfos.put(na.messenger, na);
|
mNetworkAgentInfos.put(na.messenger, na);
|
||||||
assignNextNetId(na);
|
synchronized (mNetworkForNetId) {
|
||||||
|
mNetworkForNetId.put(na.network.netId, na);
|
||||||
|
}
|
||||||
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
|
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
|
||||||
NetworkInfo networkInfo = na.networkInfo;
|
NetworkInfo networkInfo = na.networkInfo;
|
||||||
na.networkInfo = null;
|
na.networkInfo = null;
|
||||||
|
@ -40,7 +40,10 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public class NetworkAgentInfo {
|
public class NetworkAgentInfo {
|
||||||
public NetworkInfo networkInfo;
|
public NetworkInfo networkInfo;
|
||||||
public Network network;
|
// This Network object should always be used if possible, so as to encourage reuse of the
|
||||||
|
// enclosed socket factory and connection pool. Avoid creating other Network objects.
|
||||||
|
// This Network object is always valid.
|
||||||
|
public final Network network;
|
||||||
public LinkProperties linkProperties;
|
public LinkProperties linkProperties;
|
||||||
public NetworkCapabilities networkCapabilities;
|
public NetworkCapabilities networkCapabilities;
|
||||||
public final NetworkMonitor networkMonitor;
|
public final NetworkMonitor networkMonitor;
|
||||||
@ -83,12 +86,12 @@ public class NetworkAgentInfo {
|
|||||||
// Used by ConnectivityService to keep track of 464xlat.
|
// Used by ConnectivityService to keep track of 464xlat.
|
||||||
public Nat464Xlat clatd;
|
public Nat464Xlat clatd;
|
||||||
|
|
||||||
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, NetworkInfo info,
|
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
|
||||||
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
|
LinkProperties lp, NetworkCapabilities nc, int score, Context context, Handler handler,
|
||||||
NetworkMisc misc, NetworkRequest defaultRequest) {
|
NetworkMisc misc, NetworkRequest defaultRequest) {
|
||||||
this.messenger = messenger;
|
this.messenger = messenger;
|
||||||
asyncChannel = ac;
|
asyncChannel = ac;
|
||||||
network = null;
|
network = net;
|
||||||
networkInfo = info;
|
networkInfo = info;
|
||||||
linkProperties = lp;
|
linkProperties = lp;
|
||||||
networkCapabilities = nc;
|
networkCapabilities = nc;
|
||||||
|
@ -17,9 +17,10 @@
|
|||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
import static android.Manifest.permission.BIND_VPN_SERVICE;
|
import static android.Manifest.permission.BIND_VPN_SERVICE;
|
||||||
import static android.os.UserHandle.PER_USER_RANGE;
|
import static android.net.ConnectivityManager.NETID_UNSET;
|
||||||
import static android.net.RouteInfo.RTN_THROW;
|
import static android.net.RouteInfo.RTN_THROW;
|
||||||
import static android.net.RouteInfo.RTN_UNREACHABLE;
|
import static android.net.RouteInfo.RTN_UNREACHABLE;
|
||||||
|
import static android.os.UserHandle.PER_USER_RANGE;
|
||||||
import static android.system.OsConstants.AF_INET;
|
import static android.system.OsConstants.AF_INET;
|
||||||
import static android.system.OsConstants.AF_INET6;
|
import static android.system.OsConstants.AF_INET6;
|
||||||
|
|
||||||
@ -339,6 +340,10 @@ public class Vpn {
|
|||||||
return mNetworkInfo;
|
return mNetworkInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getNetId() {
|
||||||
|
return mNetworkAgent != null ? mNetworkAgent.netId : NETID_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
private LinkProperties makeLinkProperties() {
|
private LinkProperties makeLinkProperties() {
|
||||||
boolean allowIPv4 = mConfig.allowIPv4;
|
boolean allowIPv4 = mConfig.allowIPv4;
|
||||||
boolean allowIPv6 = mConfig.allowIPv6;
|
boolean allowIPv6 = mConfig.allowIPv6;
|
||||||
|
Reference in New Issue
Block a user