diff options
3 files changed, 128 insertions, 46 deletions
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java index 713b6888376e..e1ef8b5ea5c9 100644 --- a/core/java/android/net/NetworkState.java +++ b/core/java/android/net/NetworkState.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.NonNull; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; @@ -30,7 +31,8 @@ import android.util.Slog; public class NetworkState implements Parcelable { private static final boolean VALIDATE_ROAMING_STATE = false; - public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null); + // TODO: remove and make members @NonNull. + public static final NetworkState EMPTY = new NetworkState(); public final NetworkInfo networkInfo; public final LinkProperties linkProperties; @@ -40,9 +42,18 @@ public class NetworkState implements Parcelable { public final String subscriberId; public final String networkId; - public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, Network network, String subscriberId, - String networkId) { + private NetworkState() { + networkInfo = null; + linkProperties = null; + networkCapabilities = null; + network = null; + subscriberId = null; + networkId = null; + } + + public NetworkState(@NonNull NetworkInfo networkInfo, @NonNull LinkProperties linkProperties, + @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network, + String subscriberId, String networkId) { this.networkInfo = networkInfo; this.linkProperties = linkProperties; this.networkCapabilities = networkCapabilities; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 554edc6d74bd..4f0efb4406e7 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1329,31 +1329,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return mNextNetworkRequestId++; } - private NetworkState getFilteredNetworkState(int networkType, int uid) { - if (mLegacyTypeTracker.isTypeSupported(networkType)) { - final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); - final NetworkState state; - if (nai != null) { - state = nai.getNetworkState(); - state.networkInfo.setType(networkType); - } else { - final NetworkInfo info = new NetworkInfo(networkType, 0, - getNetworkTypeName(networkType), ""); - info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null); - info.setIsAvailable(true); - final NetworkCapabilities capabilities = new NetworkCapabilities(); - capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, - !info.isRoaming()); - state = new NetworkState(info, new LinkProperties(), capabilities, - null, null, null); - } - filterNetworkStateForUid(state, uid, false); - return state; - } else { - return NetworkState.EMPTY; - } - } - @VisibleForTesting protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { if (network == null) { @@ -1464,6 +1439,18 @@ public class ConnectivityService extends IConnectivityManager.Stub "%s %d(%d) on netId %d", action, nri.mUid, requestId, net.getNetId())); } + private void filterNetworkInfo(@NonNull NetworkInfo networkInfo, + @NonNull NetworkCapabilities nc, int uid, boolean ignoreBlocked) { + if (isNetworkWithCapabilitiesBlocked(nc, uid, ignoreBlocked)) { + networkInfo.setDetailedState(DetailedState.BLOCKED, null, null); + } + synchronized (mVpns) { + if (mLockdownTracker != null) { + mLockdownTracker.augmentNetworkInfo(networkInfo); + } + } + } + /** * Apply any relevant filters to {@link NetworkState} for the given UID. For * example, this may mark the network as {@link DetailedState#BLOCKED} based @@ -1471,16 +1458,7 @@ public class ConnectivityService extends IConnectivityManager.Stub */ private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) { if (state == null || state.networkInfo == null || state.linkProperties == null) return; - - if (isNetworkWithCapabilitiesBlocked(state.networkCapabilities, uid, - ignoreBlocked)) { - state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null); - } - synchronized (mVpns) { - if (mLockdownTracker != null) { - mLockdownTracker.augmentNetworkInfo(state.networkInfo); - } - } + filterNetworkInfo(state.networkInfo, state.networkCapabilities, uid, ignoreBlocked); } /** @@ -1545,6 +1523,27 @@ public class ConnectivityService extends IConnectivityManager.Stub return state.networkInfo; } + private NetworkInfo getFilteredNetworkInfo(int networkType, int uid) { + if (!mLegacyTypeTracker.isTypeSupported(networkType)) { + return null; + } + final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); + final NetworkInfo info; + final NetworkCapabilities nc; + if (nai != null) { + info = new NetworkInfo(nai.networkInfo); + info.setType(networkType); + nc = nai.networkCapabilities; + } else { + info = new NetworkInfo(networkType, 0, getNetworkTypeName(networkType), ""); + info.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null); + info.setIsAvailable(true); + nc = new NetworkCapabilities(); + } + filterNetworkInfo(info, nc, uid, false); + return info; + } + @Override public NetworkInfo getNetworkInfo(int networkType) { enforceAccessPermission(); @@ -1559,8 +1558,7 @@ public class ConnectivityService extends IConnectivityManager.Stub return state.networkInfo; } } - final NetworkState state = getFilteredNetworkState(networkType, uid); - return state.networkInfo; + return getFilteredNetworkInfo(networkType, uid); } @Override @@ -1593,10 +1591,16 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public Network getNetworkForType(int networkType) { enforceAccessPermission(); + if (!mLegacyTypeTracker.isTypeSupported(networkType)) { + return null; + } + final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType); + if (nai == null) { + return null; + } final int uid = mDeps.getCallingUid(); - NetworkState state = getFilteredNetworkState(networkType, uid); - if (!isNetworkWithCapabilitiesBlocked(state.networkCapabilities, uid, false)) { - return state.network; + if (!isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) { + return nai.network; } return null; } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 6523accf20e0..4f13dc3d3e94 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -380,6 +380,10 @@ public class ConnectivityServiceTest { private QosCallbackMockHelper mQosCallbackMockHelper; private QosCallbackTracker mQosCallbackTracker; + // State variables required to emulate NetworkPolicyManagerService behaviour. + private int mUidRules = RULE_NONE; + private boolean mRestrictBackground = false; + @Mock DeviceIdleInternal mDeviceIdleInternal; @Mock INetworkManagementService mNetworkManagementService; @Mock INetworkStatsService mStatsService; @@ -1278,12 +1282,45 @@ public class ConnectivityServiceTest { } } + private void updateUidNetworkingBlocked() { + // Changes the return value of the mock NetworkPolicyManager's isUidNetworkingBlocked method + // based on the current UID rules and restrict background setting. Note that the test never + // pretends to be a foreground app, so always declare no connectivity if background + // networking is not allowed. + switch (mUidRules) { + case RULE_REJECT_ALL: + when(mNetworkPolicyManager.isUidNetworkingBlocked(anyInt(), anyBoolean())) + .thenReturn(true); + break; + + case RULE_REJECT_METERED: + when(mNetworkPolicyManager.isUidNetworkingBlocked(anyInt(), eq(true))) + .thenReturn(true); + when(mNetworkPolicyManager.isUidNetworkingBlocked(anyInt(), eq(false))) + .thenReturn(mRestrictBackground); + break; + + case RULE_ALLOW_METERED: + case RULE_NONE: + when(mNetworkPolicyManager.isUidNetworkingBlocked(anyInt(), anyBoolean())) + .thenReturn(mRestrictBackground); + break; + + default: + fail("Unknown policy rule " + mUidRules); + } + } + private void setUidRulesChanged(int uidRules) throws RemoteException { - mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules); + mUidRules = uidRules; + updateUidNetworkingBlocked(); + mPolicyListener.onUidRulesChanged(Process.myUid(), mUidRules); } private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException { - mPolicyListener.onRestrictBackgroundChanged(restrictBackground); + mRestrictBackground = restrictBackground; + updateUidNetworkingBlocked(); + mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground); } private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { @@ -6842,9 +6879,15 @@ public class ConnectivityServiceTest { mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent.connect(true); cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); setUidRulesChanged(RULE_REJECT_ALL); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); + assertNull(mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); // ConnectivityService should cache it not to invoke the callback again. setUidRulesChanged(RULE_REJECT_METERED); @@ -6852,20 +6895,37 @@ public class ConnectivityServiceTest { setUidRulesChanged(RULE_NONE); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); + assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); setUidRulesChanged(RULE_REJECT_METERED); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); + assertNull(mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); // Restrict the network based on UID rule and NOT_METERED capability change. mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); + assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); + mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED); cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); + assertEquals(null, mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); + setUidRulesChanged(RULE_ALLOW_METERED); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); + assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); setUidRulesChanged(RULE_NONE); cellNetworkCallback.assertNoCallback(); @@ -6873,11 +6933,18 @@ public class ConnectivityServiceTest { // Restrict the network based on BackgroundRestricted. setRestrictBackgroundChanged(true); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); + assertEquals(null, mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED); + setRestrictBackgroundChanged(true); cellNetworkCallback.assertNoCallback(); setRestrictBackgroundChanged(false); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.assertNoCallback(); + assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); + assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED); mCm.unregisterNetworkCallback(cellNetworkCallback); } |