Merge changes from topic "blocked-reasons-callback-tests" am: 2108a92452 am: 6456359a0e am: 8afa9811c7
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1652214 Change-Id: I4d69b1ce096d83c311620950650460024ae348c0
This commit is contained in:
@@ -18,6 +18,7 @@ package android.net;
|
|||||||
|
|
||||||
import static android.app.ActivityManager.procStateToString;
|
import static android.app.ActivityManager.procStateToString;
|
||||||
import static android.content.pm.PackageManager.GET_SIGNATURES;
|
import static android.content.pm.PackageManager.GET_SIGNATURES;
|
||||||
|
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
|
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
@@ -204,9 +205,6 @@ public class NetworkPolicyManager {
|
|||||||
})
|
})
|
||||||
public @interface SubscriptionOverrideMask {}
|
public @interface SubscriptionOverrideMask {}
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate that app is not exempt from any network restrictions.
|
* Flag to indicate that app is not exempt from any network restrictions.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -31,10 +31,12 @@ package android.net {
|
|||||||
field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
|
field public static final String ACTION_PROMPT_UNVALIDATED = "android.net.action.PROMPT_UNVALIDATED";
|
||||||
field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
|
field public static final int BLOCKED_METERED_REASON_ADMIN_DISABLED = 262144; // 0x40000
|
||||||
field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
|
field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000
|
||||||
|
field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000
|
||||||
field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
|
field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000
|
||||||
field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
|
field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4
|
||||||
field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
|
field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1
|
||||||
field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
|
field public static final int BLOCKED_REASON_DOZE = 2; // 0x2
|
||||||
|
field public static final int BLOCKED_REASON_LOCKDOWN_VPN = 16; // 0x10
|
||||||
field public static final int BLOCKED_REASON_NONE = 0; // 0x0
|
field public static final int BLOCKED_REASON_NONE = 0; // 0x0
|
||||||
field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
|
field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8
|
||||||
field public static final String PRIVATE_DNS_MODE_OFF = "off";
|
field public static final String PRIVATE_DNS_MODE_OFF = "off";
|
||||||
@@ -44,6 +46,10 @@ package android.net {
|
|||||||
field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
|
field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ConnectivityManager.NetworkCallback {
|
||||||
|
method public void onBlockedStatusChanged(@NonNull android.net.Network, int);
|
||||||
|
}
|
||||||
|
|
||||||
public class ConnectivitySettingsManager {
|
public class ConnectivitySettingsManager {
|
||||||
method public static void clearGlobalProxy(@NonNull android.content.Context);
|
method public static void clearGlobalProxy(@NonNull android.content.Context);
|
||||||
method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
|
method @Nullable public static String getCaptivePortalHttpUrl(@NonNull android.content.Context);
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import android.annotation.SuppressLint;
|
|||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
import android.annotation.SystemService;
|
import android.annotation.SystemService;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.compat.annotation.UnsupportedAppUsage;
|
import android.compat.annotation.UnsupportedAppUsage;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -874,6 +876,17 @@ public class ConnectivityManager {
|
|||||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
|
public static final int BLOCKED_REASON_RESTRICTED_MODE = 1 << 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to indicate that an app is blocked because it is subject to an always-on VPN but the VPN
|
||||||
|
* is not currently connected.
|
||||||
|
*
|
||||||
|
* @see DevicePolicyManager#setAlwaysOnVpnPackage(ComponentName, String, boolean)
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final int BLOCKED_REASON_LOCKDOWN_VPN = 1 << 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag to indicate that an app is subject to Data saver restrictions that would
|
* Flag to indicate that an app is subject to Data saver restrictions that would
|
||||||
* result in its metered network access being blocked.
|
* result in its metered network access being blocked.
|
||||||
@@ -917,6 +930,14 @@ public class ConnectivityManager {
|
|||||||
})
|
})
|
||||||
public @interface BlockedReason {}
|
public @interface BlockedReason {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of blocked reasons that are only applicable on metered networks.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||||
|
public static final int BLOCKED_METERED_REASON_MASK = 0xffff0000;
|
||||||
|
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 130143562)
|
||||||
private final IConnectivityManager mService;
|
private final IConnectivityManager mService;
|
||||||
|
|
||||||
@@ -3498,12 +3519,30 @@ public class ConnectivityManager {
|
|||||||
* @param blocked Whether access to the {@link Network} is blocked due to system policy.
|
* @param blocked Whether access to the {@link Network} is blocked due to system policy.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void onAvailable(@NonNull Network network,
|
public final void onAvailable(@NonNull Network network,
|
||||||
@NonNull NetworkCapabilities networkCapabilities,
|
@NonNull NetworkCapabilities networkCapabilities,
|
||||||
@NonNull LinkProperties linkProperties, boolean blocked) {
|
@NonNull LinkProperties linkProperties, @BlockedReason int blocked) {
|
||||||
// Internally only this method is called when a new network is available, and
|
// Internally only this method is called when a new network is available, and
|
||||||
// it calls the callback in the same way and order that older versions used
|
// it calls the callback in the same way and order that older versions used
|
||||||
// to call so as not to change the behavior.
|
// to call so as not to change the behavior.
|
||||||
|
onAvailable(network, networkCapabilities, linkProperties, blocked != 0);
|
||||||
|
onBlockedStatusChanged(network, blocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legacy variant of onAvailable that takes a boolean blocked reason.
|
||||||
|
*
|
||||||
|
* This method has never been public API, but it's not final, so there may be apps that
|
||||||
|
* implemented it and rely on it being called. Do our best not to break them.
|
||||||
|
* Note: such apps will also get a second call to onBlockedStatusChanged immediately after
|
||||||
|
* this method is called. There does not seem to be a way to avoid this.
|
||||||
|
* TODO: add a compat check to move apps off this method, and eventually stop calling it.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void onAvailable(@NonNull Network network,
|
||||||
|
@NonNull NetworkCapabilities networkCapabilities,
|
||||||
|
@NonNull LinkProperties linkProperties, boolean blocked) {
|
||||||
onAvailable(network);
|
onAvailable(network);
|
||||||
if (!networkCapabilities.hasCapability(
|
if (!networkCapabilities.hasCapability(
|
||||||
NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
|
NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)) {
|
||||||
@@ -3511,7 +3550,7 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
onCapabilitiesChanged(network, networkCapabilities);
|
onCapabilitiesChanged(network, networkCapabilities);
|
||||||
onLinkPropertiesChanged(network, linkProperties);
|
onLinkPropertiesChanged(network, linkProperties);
|
||||||
onBlockedStatusChanged(network, blocked);
|
// No call to onBlockedStatusChanged here. That is done by the caller.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3675,6 +3714,26 @@ public class ConnectivityManager {
|
|||||||
*/
|
*/
|
||||||
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
|
public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when access to the specified network is blocked or unblocked.
|
||||||
|
*
|
||||||
|
* If a NetworkCallback object implements this method,
|
||||||
|
* {@link #onBlockedStatusChanged(Network, boolean)} will not be called.
|
||||||
|
*
|
||||||
|
* <p>Do NOT call {@link #getNetworkCapabilities(Network)} or
|
||||||
|
* {@link #getLinkProperties(Network)} or other synchronous ConnectivityManager methods in
|
||||||
|
* this callback as this is prone to race conditions : calling these methods while in a
|
||||||
|
* callback may return an outdated or even a null object.
|
||||||
|
*
|
||||||
|
* @param network The {@link Network} whose blocked status has changed.
|
||||||
|
* @param blocked The blocked status of this {@link Network}.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi(client = MODULE_LIBRARIES)
|
||||||
|
public void onBlockedStatusChanged(@NonNull Network network, @BlockedReason int blocked) {
|
||||||
|
onBlockedStatusChanged(network, blocked != 0);
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkRequest networkRequest;
|
private NetworkRequest networkRequest;
|
||||||
private final int mFlags;
|
private final int mFlags;
|
||||||
}
|
}
|
||||||
@@ -3789,7 +3848,7 @@ public class ConnectivityManager {
|
|||||||
case CALLBACK_AVAILABLE: {
|
case CALLBACK_AVAILABLE: {
|
||||||
NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
|
NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
|
||||||
LinkProperties lp = getObject(message, LinkProperties.class);
|
LinkProperties lp = getObject(message, LinkProperties.class);
|
||||||
callback.onAvailable(network, cap, lp, message.arg1 != 0);
|
callback.onAvailable(network, cap, lp, message.arg1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CALLBACK_LOSING: {
|
case CALLBACK_LOSING: {
|
||||||
@@ -3823,8 +3882,7 @@ public class ConnectivityManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CALLBACK_BLK_CHANGED: {
|
case CALLBACK_BLK_CHANGED: {
|
||||||
boolean blocked = message.arg1 != 0;
|
callback.onBlockedStatusChanged(network, message.arg1);
|
||||||
callback.onBlockedStatusChanged(network, blocked);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import static android.net.ConnectivityDiagnosticsManager.DataStallReport.DETECTI
|
|||||||
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
|
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_DNS_CONSECUTIVE_TIMEOUTS;
|
||||||
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
|
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS;
|
||||||
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
|
import static android.net.ConnectivityDiagnosticsManager.DataStallReport.KEY_TCP_PACKET_FAIL_RATE;
|
||||||
|
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
|
||||||
|
import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
|
import static android.net.ConnectivityManager.BLOCKED_REASON_NONE;
|
||||||
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
|
||||||
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||||
@@ -106,6 +108,7 @@ import android.net.ConnectionInfo;
|
|||||||
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
|
import android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
|
||||||
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
|
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.ConnectivityManager.BlockedReason;
|
||||||
import android.net.ConnectivityManager.NetworkCallback;
|
import android.net.ConnectivityManager.NetworkCallback;
|
||||||
import android.net.ConnectivityManager.RestrictBackgroundStatus;
|
import android.net.ConnectivityManager.RestrictBackgroundStatus;
|
||||||
import android.net.ConnectivityResources;
|
import android.net.ConnectivityResources;
|
||||||
@@ -2357,15 +2360,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
|
private final NetworkPolicyCallback mPolicyCallback = new NetworkPolicyCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onUidBlockedReasonChanged(int uid, int blockedReasons) {
|
public void onUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_BLOCKED_REASON_CHANGED,
|
||||||
uid, blockedReasons));
|
uid, blockedReasons));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void handleUidBlockedReasonChanged(int uid, int blockedReasons) {
|
private void handleUidBlockedReasonChanged(int uid, @BlockedReason int blockedReasons) {
|
||||||
maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
|
maybeNotifyNetworkBlockedForNewState(uid, blockedReasons);
|
||||||
mUidBlockedReasons.put(uid, blockedReasons);
|
setUidBlockedReasons(uid, blockedReasons);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkAnyPermissionOf(String... permissions) {
|
private boolean checkAnyPermissionOf(String... permissions) {
|
||||||
@@ -8190,12 +8193,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
|
||||||
final boolean metered = nai.networkCapabilities.isMetered();
|
final boolean metered = nai.networkCapabilities.isMetered();
|
||||||
boolean blocked;
|
final boolean vpnBlocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
|
||||||
blocked = isUidBlockedByVpn(nri.mAsUid, mVpnBlockedUidRanges);
|
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE,
|
||||||
blocked |= NetworkPolicyManager.isUidBlocked(
|
getBlockedState(blockedReasons, metered, vpnBlocked));
|
||||||
mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE), metered);
|
|
||||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the requests on this NAI that the network is now lingered.
|
// Notify the requests on this NAI that the network is now lingered.
|
||||||
@@ -8204,6 +8206,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
|
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING, lingerTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getBlockedState(int reasons, boolean metered, boolean vpnBlocked) {
|
||||||
|
if (!metered) reasons &= ~BLOCKED_METERED_REASON_MASK;
|
||||||
|
return vpnBlocked
|
||||||
|
? reasons | BLOCKED_REASON_LOCKDOWN_VPN
|
||||||
|
: reasons & ~BLOCKED_REASON_LOCKDOWN_VPN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUidBlockedReasons(int uid, @BlockedReason int blockedReasons) {
|
||||||
|
if (blockedReasons == BLOCKED_REASON_NONE) {
|
||||||
|
mUidBlockedReasons.delete(uid);
|
||||||
|
} else {
|
||||||
|
mUidBlockedReasons.put(uid, blockedReasons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify of the blocked state apps with a registered callback matching a given NAI.
|
* Notify of the blocked state apps with a registered callback matching a given NAI.
|
||||||
*
|
*
|
||||||
@@ -8211,7 +8228,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
* any given nai, all requests need to be considered according to the uid who filed it.
|
* any given nai, all requests need to be considered according to the uid who filed it.
|
||||||
*
|
*
|
||||||
* @param nai The target NetworkAgentInfo.
|
* @param nai The target NetworkAgentInfo.
|
||||||
* @param oldMetered True if the previous network capabilities is metered.
|
* @param oldMetered True if the previous network capabilities were metered.
|
||||||
|
* @param newMetered True if the current network capabilities are metered.
|
||||||
|
* @param oldBlockedUidRanges list of UID ranges previously blocked by lockdown VPN.
|
||||||
|
* @param newBlockedUidRanges list of UID ranges blocked by lockdown VPN.
|
||||||
*/
|
*/
|
||||||
private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
|
private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
|
||||||
boolean newMetered, List<UidRange> oldBlockedUidRanges,
|
boolean newMetered, List<UidRange> oldBlockedUidRanges,
|
||||||
@@ -8220,22 +8240,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
||||||
NetworkRequest nr = nai.requestAt(i);
|
NetworkRequest nr = nai.requestAt(i);
|
||||||
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
||||||
final boolean oldBlocked, newBlocked, oldVpnBlocked, newVpnBlocked;
|
|
||||||
|
|
||||||
oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
|
final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
|
||||||
newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
|
final boolean oldVpnBlocked = isUidBlockedByVpn(nri.mAsUid, oldBlockedUidRanges);
|
||||||
|
final boolean newVpnBlocked = (oldBlockedUidRanges != newBlockedUidRanges)
|
||||||
? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
|
? isUidBlockedByVpn(nri.mAsUid, newBlockedUidRanges)
|
||||||
: oldVpnBlocked;
|
: oldVpnBlocked;
|
||||||
|
|
||||||
final int blockedReasons = mUidBlockedReasons.get(nri.mAsUid, BLOCKED_REASON_NONE);
|
final int oldBlockedState = getBlockedState(blockedReasons, oldMetered, oldVpnBlocked);
|
||||||
oldBlocked = oldVpnBlocked || NetworkPolicyManager.isUidBlocked(
|
final int newBlockedState = getBlockedState(blockedReasons, newMetered, newVpnBlocked);
|
||||||
blockedReasons, oldMetered);
|
if (oldBlockedState != newBlockedState) {
|
||||||
newBlocked = newVpnBlocked || NetworkPolicyManager.isUidBlocked(
|
|
||||||
blockedReasons, newMetered);
|
|
||||||
|
|
||||||
if (oldBlocked != newBlocked) {
|
|
||||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
|
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
|
||||||
encodeBool(newBlocked));
|
newBlockedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8245,25 +8261,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
* @param uid The uid for which the rules changed.
|
* @param uid The uid for which the rules changed.
|
||||||
* @param blockedReasons The reasons for why an uid is blocked.
|
* @param blockedReasons The reasons for why an uid is blocked.
|
||||||
*/
|
*/
|
||||||
private void maybeNotifyNetworkBlockedForNewState(int uid, int blockedReasons) {
|
private void maybeNotifyNetworkBlockedForNewState(int uid, @BlockedReason int blockedReasons) {
|
||||||
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
|
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
|
||||||
final boolean metered = nai.networkCapabilities.isMetered();
|
final boolean metered = nai.networkCapabilities.isMetered();
|
||||||
final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
|
final boolean vpnBlocked = isUidBlockedByVpn(uid, mVpnBlockedUidRanges);
|
||||||
final boolean oldBlocked, newBlocked;
|
|
||||||
|
|
||||||
oldBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
|
final int oldBlockedState = getBlockedState(
|
||||||
mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered);
|
mUidBlockedReasons.get(uid, BLOCKED_REASON_NONE), metered, vpnBlocked);
|
||||||
newBlocked = vpnBlocked || NetworkPolicyManager.isUidBlocked(
|
final int newBlockedState = getBlockedState(blockedReasons, metered, vpnBlocked);
|
||||||
blockedReasons, metered);
|
if (oldBlockedState == newBlockedState) {
|
||||||
if (oldBlocked == newBlocked) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final int arg = encodeBool(newBlocked);
|
|
||||||
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
||||||
NetworkRequest nr = nai.requestAt(i);
|
NetworkRequest nr = nai.requestAt(i);
|
||||||
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
||||||
if (nri != null && nri.mAsUid == uid) {
|
if (nri != null && nri.mAsUid == uid) {
|
||||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
|
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
|
||||||
|
newBlockedState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
|
|||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
|
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
|
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER;
|
||||||
|
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
|
import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
|
import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY;
|
||||||
import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
|
import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER;
|
||||||
@@ -76,7 +77,6 @@ import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_ALLOWLI
|
|||||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
|
import static android.net.NetworkPolicyManager.ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST;
|
||||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
|
import static android.net.NetworkPolicyManager.ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
|
||||||
import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
|
import static android.net.NetworkPolicyManager.ALLOWED_REASON_SYSTEM;
|
||||||
import static android.net.NetworkPolicyManager.BLOCKED_METERED_REASON_MASK;
|
|
||||||
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
|
||||||
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
|
||||||
import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
|
import static android.net.NetworkPolicyManager.MASK_ALL_NETWORKS;
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.ArgumentMatchers.nullable;
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
|
||||||
import static org.mockito.Mockito.anyInt;
|
import static org.mockito.Mockito.anyInt;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
|||||||
@@ -7367,6 +7367,20 @@ public class ConnectivityServiceTest {
|
|||||||
mMockVpn.disconnect();
|
mMockVpn.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DetailedBlockedStatusCallback extends TestNetworkCallback {
|
||||||
|
public void expectAvailableThenValidatedCallbacks(HasNetwork n, int blockedStatus) {
|
||||||
|
super.expectAvailableThenValidatedCallbacks(n.getNetwork(), blockedStatus, TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
public void expectBlockedStatusCallback(HasNetwork n, int blockedStatus) {
|
||||||
|
// This doesn't work:
|
||||||
|
// super.expectBlockedStatusCallback(blockedStatus, n.getNetwork());
|
||||||
|
super.expectBlockedStatusCallback(blockedStatus, n.getNetwork(), TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
public void onBlockedStatusChanged(Network network, int blockedReasons) {
|
||||||
|
getHistory().add(new CallbackEntry.BlockedStatusInt(network, blockedReasons));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNetworkBlockedStatus() throws Exception {
|
public void testNetworkBlockedStatus() throws Exception {
|
||||||
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
|
final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
|
||||||
@@ -7374,11 +7388,16 @@ public class ConnectivityServiceTest {
|
|||||||
.addTransportType(TRANSPORT_CELLULAR)
|
.addTransportType(TRANSPORT_CELLULAR)
|
||||||
.build();
|
.build();
|
||||||
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
|
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
|
||||||
|
final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback();
|
||||||
|
mCm.registerNetworkCallback(cellRequest, detailedCallback);
|
||||||
|
|
||||||
mockUidNetworkingBlocked();
|
mockUidNetworkingBlocked();
|
||||||
|
|
||||||
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
|
||||||
mCellNetworkAgent.connect(true);
|
mCellNetworkAgent.connect(true);
|
||||||
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
|
||||||
|
detailedCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent,
|
||||||
|
BLOCKED_REASON_NONE);
|
||||||
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
@@ -7386,17 +7405,23 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
|
setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
|
||||||
|
BLOCKED_REASON_BATTERY_SAVER);
|
||||||
assertNull(mCm.getActiveNetwork());
|
assertNull(mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
assertExtraInfoFromCmBlocked(mCellNetworkAgent);
|
assertExtraInfoFromCmBlocked(mCellNetworkAgent);
|
||||||
|
|
||||||
// ConnectivityService should cache it not to invoke the callback again.
|
// If blocked state does not change but blocked reason does, the boolean callback is called.
|
||||||
|
// TODO: investigate de-duplicating.
|
||||||
setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED);
|
setBlockedReasonChanged(BLOCKED_METERED_REASON_USER_RESTRICTED);
|
||||||
cellNetworkCallback.assertNoCallback();
|
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
|
||||||
|
BLOCKED_METERED_REASON_USER_RESTRICTED);
|
||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
|
||||||
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
@@ -7404,6 +7429,8 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
|
setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
|
||||||
|
BLOCKED_METERED_REASON_DATA_SAVER);
|
||||||
assertNull(mCm.getActiveNetwork());
|
assertNull(mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
@@ -7413,6 +7440,8 @@ public class ConnectivityServiceTest {
|
|||||||
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);
|
||||||
|
detailedCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
|
||||||
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
@@ -7422,6 +7451,10 @@ public class ConnectivityServiceTest {
|
|||||||
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
|
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
|
||||||
mCellNetworkAgent);
|
mCellNetworkAgent);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
|
||||||
|
mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
|
||||||
|
BLOCKED_METERED_REASON_DATA_SAVER);
|
||||||
assertNull(mCm.getActiveNetwork());
|
assertNull(mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
@@ -7429,6 +7462,7 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
|
||||||
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
@@ -7436,10 +7470,13 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
||||||
cellNetworkCallback.assertNoCallback();
|
cellNetworkCallback.assertNoCallback();
|
||||||
|
detailedCallback.assertNoCallback();
|
||||||
|
|
||||||
// Restrict background data. Networking is not blocked because the network is unmetered.
|
// Restrict background data. Networking is not blocked because the network is unmetered.
|
||||||
setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
|
setBlockedReasonChanged(BLOCKED_METERED_REASON_DATA_SAVER);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent,
|
||||||
|
BLOCKED_METERED_REASON_DATA_SAVER);
|
||||||
assertNull(mCm.getActiveNetwork());
|
assertNull(mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.BLOCKED);
|
||||||
@@ -7449,12 +7486,14 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
||||||
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
|
cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
|
||||||
|
detailedCallback.expectBlockedStatusCallback(mCellNetworkAgent, BLOCKED_REASON_NONE);
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertExtraInfoFromCmPresent(mCellNetworkAgent);
|
assertExtraInfoFromCmPresent(mCellNetworkAgent);
|
||||||
|
|
||||||
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
setBlockedReasonChanged(BLOCKED_REASON_NONE);
|
||||||
cellNetworkCallback.assertNoCallback();
|
cellNetworkCallback.assertNoCallback();
|
||||||
|
detailedCallback.assertNoCallback();
|
||||||
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
|
||||||
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertActiveNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
assertNetworkInfo(TYPE_MOBILE, DetailedState.CONNECTED);
|
||||||
|
|||||||
Reference in New Issue
Block a user