Merge changes Idcc9e32c,I58769bb7

* changes:
  Remove getFilteredNetworkState and add @NonNull in NetworkState.
  Add test coverage for get*NetworkInfo on metered networks.
This commit is contained in:
Lorenzo Colitti
2021-02-01 10:56:19 +00:00
committed by Gerrit Code Review
3 changed files with 128 additions and 46 deletions

View File

@@ -16,6 +16,7 @@
package android.net; package android.net;
import android.annotation.NonNull;
import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build; import android.os.Build;
import android.os.Parcel; import android.os.Parcel;
@@ -30,7 +31,8 @@ import android.util.Slog;
public class NetworkState implements Parcelable { public class NetworkState implements Parcelable {
private static final boolean VALIDATE_ROAMING_STATE = false; 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 NetworkInfo networkInfo;
public final LinkProperties linkProperties; public final LinkProperties linkProperties;
@@ -40,9 +42,18 @@ public class NetworkState implements Parcelable {
public final String subscriberId; public final String subscriberId;
public final String networkId; public final String networkId;
public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties, private NetworkState() {
NetworkCapabilities networkCapabilities, Network network, String subscriberId, networkInfo = null;
String networkId) { 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.networkInfo = networkInfo;
this.linkProperties = linkProperties; this.linkProperties = linkProperties;
this.networkCapabilities = networkCapabilities; this.networkCapabilities = networkCapabilities;

View File

@@ -1329,31 +1329,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
return mNextNetworkRequestId++; 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 @VisibleForTesting
protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) { protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
if (network == null) { 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())); "%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 * Apply any relevant filters to {@link NetworkState} for the given UID. For
* example, this may mark the network as {@link DetailedState#BLOCKED} based * 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) { private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) {
if (state == null || state.networkInfo == null || state.linkProperties == null) return; if (state == null || state.networkInfo == null || state.linkProperties == null) return;
filterNetworkInfo(state.networkInfo, state.networkCapabilities, uid, ignoreBlocked);
if (isNetworkWithCapabilitiesBlocked(state.networkCapabilities, uid,
ignoreBlocked)) {
state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
}
synchronized (mVpns) {
if (mLockdownTracker != null) {
mLockdownTracker.augmentNetworkInfo(state.networkInfo);
}
}
} }
/** /**
@@ -1545,6 +1523,27 @@ public class ConnectivityService extends IConnectivityManager.Stub
return state.networkInfo; 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 @Override
public NetworkInfo getNetworkInfo(int networkType) { public NetworkInfo getNetworkInfo(int networkType) {
enforceAccessPermission(); enforceAccessPermission();
@@ -1559,8 +1558,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
return state.networkInfo; return state.networkInfo;
} }
} }
final NetworkState state = getFilteredNetworkState(networkType, uid); return getFilteredNetworkInfo(networkType, uid);
return state.networkInfo;
} }
@Override @Override
@@ -1593,10 +1591,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override @Override
public Network getNetworkForType(int networkType) { public Network getNetworkForType(int networkType) {
enforceAccessPermission(); enforceAccessPermission();
if (!mLegacyTypeTracker.isTypeSupported(networkType)) {
return null;
}
final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
if (nai == null) {
return null;
}
final int uid = mDeps.getCallingUid(); final int uid = mDeps.getCallingUid();
NetworkState state = getFilteredNetworkState(networkType, uid); if (!isNetworkWithCapabilitiesBlocked(nai.networkCapabilities, uid, false)) {
if (!isNetworkWithCapabilitiesBlocked(state.networkCapabilities, uid, false)) { return nai.network;
return state.network;
} }
return null; return null;
} }

View File

@@ -380,6 +380,10 @@ public class ConnectivityServiceTest {
private QosCallbackMockHelper mQosCallbackMockHelper; private QosCallbackMockHelper mQosCallbackMockHelper;
private QosCallbackTracker mQosCallbackTracker; private QosCallbackTracker mQosCallbackTracker;
// State variables required to emulate NetworkPolicyManagerService behaviour.
private int mUidRules = RULE_NONE;
private boolean mRestrictBackground = false;
@Mock DeviceIdleInternal mDeviceIdleInternal; @Mock DeviceIdleInternal mDeviceIdleInternal;
@Mock INetworkManagementService mNetworkManagementService; @Mock INetworkManagementService mNetworkManagementService;
@Mock INetworkStatsService mStatsService; @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 { 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 { private void setRestrictBackgroundChanged(boolean restrictBackground) throws RemoteException {
mPolicyListener.onRestrictBackgroundChanged(restrictBackground); mRestrictBackground = restrictBackground;
updateUidNetworkingBlocked();
mPolicyListener.onRestrictBackgroundChanged(mRestrictBackground);
} }
private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) { private Nat464Xlat getNat464Xlat(NetworkAgentWrapper mna) {
@@ -6842,9 +6879,15 @@ public class ConnectivityServiceTest {
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true); mCellNetworkAgent.connect(true);
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
setUidRulesChanged(RULE_REJECT_ALL); setUidRulesChanged(RULE_REJECT_ALL);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 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. // ConnectivityService should cache it not to invoke the callback again.
setUidRulesChanged(RULE_REJECT_METERED); setUidRulesChanged(RULE_REJECT_METERED);
@@ -6852,20 +6895,37 @@ public class ConnectivityServiceTest {
setUidRulesChanged(RULE_NONE); setUidRulesChanged(RULE_NONE);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
setUidRulesChanged(RULE_REJECT_METERED); setUidRulesChanged(RULE_REJECT_METERED);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); 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. // Restrict the network based on UID rule and NOT_METERED capability change.
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED); mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent); cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
cellNetworkCallback.expectBlockedStatusCallback(false, 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); mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
mCellNetworkAgent); mCellNetworkAgent);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertEquals(null, mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
setUidRulesChanged(RULE_ALLOW_METERED); setUidRulesChanged(RULE_ALLOW_METERED);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
setUidRulesChanged(RULE_NONE); setUidRulesChanged(RULE_NONE);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
@@ -6873,11 +6933,18 @@ public class ConnectivityServiceTest {
// Restrict the network based on BackgroundRestricted. // Restrict the network based on BackgroundRestricted.
setRestrictBackgroundChanged(true); setRestrictBackgroundChanged(true);
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
assertEquals(null, mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
setRestrictBackgroundChanged(true); setRestrictBackgroundChanged(true);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
setRestrictBackgroundChanged(false); setRestrictBackgroundChanged(false);
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent); cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback(); cellNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
mCm.unregisterNetworkCallback(cellNetworkCallback); mCm.unregisterNetworkCallback(cellNetworkCallback);
} }