Merge "Add new callback to inform blocking of network on specific uid."
This commit is contained in:
@@ -2816,10 +2816,11 @@ public class ConnectivityManager {
|
|||||||
* @param network The {@link Network} of the satisfying network.
|
* @param network The {@link Network} of the satisfying network.
|
||||||
* @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
|
* @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
|
||||||
* @param linkProperties The {@link LinkProperties} of the satisfying network.
|
* @param linkProperties The {@link LinkProperties} of the satisfying network.
|
||||||
|
* @param blocked Whether access to the {@link Network} is blocked due to system policy.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
|
public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
|
||||||
LinkProperties linkProperties) {
|
LinkProperties linkProperties, boolean 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.
|
||||||
@@ -2830,6 +2831,7 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
onCapabilitiesChanged(network, networkCapabilities);
|
onCapabilitiesChanged(network, networkCapabilities);
|
||||||
onLinkPropertiesChanged(network, linkProperties);
|
onLinkPropertiesChanged(network, linkProperties);
|
||||||
|
onBlockedStatusChanged(network, blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2837,7 +2839,8 @@ public class ConnectivityManager {
|
|||||||
* This callback may be called more than once if the {@link Network} that is
|
* This callback may be called more than once if the {@link Network} that is
|
||||||
* satisfying the request changes. This will always immediately be followed by a
|
* satisfying the request changes. This will always immediately be followed by a
|
||||||
* call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
|
* call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
|
||||||
* call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
|
* call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call to
|
||||||
|
* {@link #onBlockedStatusChanged(Network, boolean)}.
|
||||||
*
|
*
|
||||||
* @param network The {@link Network} of the satisfying network.
|
* @param network The {@link Network} of the satisfying network.
|
||||||
*/
|
*/
|
||||||
@@ -2916,6 +2919,14 @@ public class ConnectivityManager {
|
|||||||
*/
|
*/
|
||||||
public void onNetworkResumed(Network network) {}
|
public void onNetworkResumed(Network network) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when access to the specified network is blocked or unblocked.
|
||||||
|
*
|
||||||
|
* @param network The {@link Network} whose blocked status has changed.
|
||||||
|
* @param blocked The blocked status of this {@link Network}.
|
||||||
|
*/
|
||||||
|
public void onBlockedStatusChanged(Network network, boolean blocked) {}
|
||||||
|
|
||||||
private NetworkRequest networkRequest;
|
private NetworkRequest networkRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2962,6 +2973,8 @@ public class ConnectivityManager {
|
|||||||
public static final int CALLBACK_SUSPENDED = BASE + 9;
|
public static final int CALLBACK_SUSPENDED = BASE + 9;
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static final int CALLBACK_RESUMED = BASE + 10;
|
public static final int CALLBACK_RESUMED = BASE + 10;
|
||||||
|
/** @hide */
|
||||||
|
public static final int CALLBACK_BLK_CHANGED = BASE + 11;
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static String getCallbackName(int whichCallback) {
|
public static String getCallbackName(int whichCallback) {
|
||||||
@@ -2976,6 +2989,7 @@ public class ConnectivityManager {
|
|||||||
case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
|
case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
|
||||||
case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED";
|
case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED";
|
||||||
case CALLBACK_RESUMED: return "CALLBACK_RESUMED";
|
case CALLBACK_RESUMED: return "CALLBACK_RESUMED";
|
||||||
|
case CALLBACK_BLK_CHANGED: return "CALLBACK_BLK_CHANGED";
|
||||||
default:
|
default:
|
||||||
return Integer.toString(whichCallback);
|
return Integer.toString(whichCallback);
|
||||||
}
|
}
|
||||||
@@ -3022,7 +3036,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);
|
callback.onAvailable(network, cap, lp, message.arg1 != 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CALLBACK_LOSING: {
|
case CALLBACK_LOSING: {
|
||||||
@@ -3055,6 +3069,10 @@ public class ConnectivityManager {
|
|||||||
callback.onNetworkResumed(network);
|
callback.onNetworkResumed(network);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CALLBACK_BLK_CHANGED: {
|
||||||
|
boolean blocked = message.arg1 != 0;
|
||||||
|
callback.onBlockedStatusChanged(network, blocked);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1589,4 +1589,14 @@ public final class NetworkCapabilities implements Parcelable {
|
|||||||
Preconditions.checkArgument(isValidCapability(capability),
|
Preconditions.checkArgument(isValidCapability(capability),
|
||||||
"NetworkCapability " + capability + "out of range");
|
"NetworkCapability " + capability + "out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this {@code NetworkCapability} instance is metered.
|
||||||
|
*
|
||||||
|
* @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean isMetered() {
|
||||||
|
return !hasCapability(NET_CAPABILITY_NOT_METERED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,7 +202,9 @@ public class NetworkInfo implements Parcelable {
|
|||||||
* Return a network-type-specific integer describing the subtype
|
* Return a network-type-specific integer describing the subtype
|
||||||
* of the network.
|
* of the network.
|
||||||
* @return the network subtype
|
* @return the network subtype
|
||||||
|
* @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public int getSubtype() {
|
public int getSubtype() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return mSubtype;
|
return mSubtype;
|
||||||
@@ -243,7 +245,9 @@ public class NetworkInfo implements Parcelable {
|
|||||||
/**
|
/**
|
||||||
* Return a human-readable name describing the subtype of the network.
|
* Return a human-readable name describing the subtype of the network.
|
||||||
* @return the name of the network subtype
|
* @return the name of the network subtype
|
||||||
|
* @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getSubtypeName() {
|
public String getSubtypeName() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return mSubtypeName;
|
return mSubtypeName;
|
||||||
@@ -278,7 +282,15 @@ public class NetworkInfo implements Parcelable {
|
|||||||
* connections and pass data.
|
* connections and pass data.
|
||||||
* <p>Always call this before attempting to perform data transactions.
|
* <p>Always call this before attempting to perform data transactions.
|
||||||
* @return {@code true} if network connectivity exists, {@code false} otherwise.
|
* @return {@code true} if network connectivity exists, {@code false} otherwise.
|
||||||
|
* @deprecated Apps should instead use the
|
||||||
|
* {@link android.net.ConnectivityManager.NetworkCallback} API to
|
||||||
|
* learn about connectivity changes. See
|
||||||
|
* {@link ConnectivityManager#registerDefaultNetworkCallback} and
|
||||||
|
* {@link ConnectivityManager#registerNetworkCallback}. These will
|
||||||
|
* give a more accurate picture of the connectivity state of
|
||||||
|
* the device and let apps react more easily and quickly to changes.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return mState == State.CONNECTED;
|
return mState == State.CONNECTED;
|
||||||
@@ -411,7 +423,15 @@ public class NetworkInfo implements Parcelable {
|
|||||||
/**
|
/**
|
||||||
* Reports the current fine-grained state of the network.
|
* Reports the current fine-grained state of the network.
|
||||||
* @return the fine-grained state
|
* @return the fine-grained state
|
||||||
|
* @deprecated Apps should instead use the
|
||||||
|
* {@link android.net.ConnectivityManager.NetworkCallback} API to
|
||||||
|
* learn about connectivity changes. See
|
||||||
|
* {@link ConnectivityManager#registerDefaultNetworkCallback} and
|
||||||
|
* {@link ConnectivityManager#registerNetworkCallback}. These will
|
||||||
|
* give a more accurate picture of the connectivity state of
|
||||||
|
* the device and let apps react more easily and quickly to changes.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public DetailedState getDetailedState() {
|
public DetailedState getDetailedState() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
return mDetailedState;
|
return mDetailedState;
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
|
import static android.net.NetworkPolicyManager.RULE_NONE;
|
||||||
|
import static android.net.NetworkPolicyManager.uidRulesToString;
|
||||||
import static android.os.Process.INVALID_UID;
|
import static android.os.Process.INVALID_UID;
|
||||||
import static android.system.OsConstants.IPPROTO_TCP;
|
import static android.system.OsConstants.IPPROTO_TCP;
|
||||||
import static android.system.OsConstants.IPPROTO_UDP;
|
import static android.system.OsConstants.IPPROTO_UDP;
|
||||||
@@ -189,6 +191,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.ConcurrentModificationException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -257,6 +260,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
@GuardedBy("mVpns")
|
@GuardedBy("mVpns")
|
||||||
private LockdownVpnTracker mLockdownTracker;
|
private LockdownVpnTracker mLockdownTracker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
|
||||||
|
* handler thread, they don't need a lock.
|
||||||
|
*/
|
||||||
|
private SparseIntArray mUidRules = new SparseIntArray();
|
||||||
|
/** Flag indicating if background data is restricted. */
|
||||||
|
private boolean mRestrictBackground;
|
||||||
|
|
||||||
final private Context mContext;
|
final private Context mContext;
|
||||||
// 0 is full bad, 100 is full good
|
// 0 is full bad, 100 is full good
|
||||||
private int mDefaultInetConditionPublished = 0;
|
private int mDefaultInetConditionPublished = 0;
|
||||||
@@ -419,6 +430,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// Handle private DNS validation status updates.
|
// Handle private DNS validation status updates.
|
||||||
private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
|
private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
|
||||||
|
*/
|
||||||
|
private static final int EVENT_UID_RULES_CHANGED = 39;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
|
||||||
|
*/
|
||||||
|
private static final int EVENT_DATA_SAVER_CHANGED = 40;
|
||||||
|
|
||||||
private static String eventName(int what) {
|
private static String eventName(int what) {
|
||||||
return sMagicDecoderRing.get(what, Integer.toString(what));
|
return sMagicDecoderRing.get(what, Integer.toString(what));
|
||||||
}
|
}
|
||||||
@@ -780,6 +801,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mKeyStore = KeyStore.getInstance();
|
mKeyStore = KeyStore.getInstance();
|
||||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
|
||||||
|
// To ensure uid rules are synchronized with Network Policy, register for
|
||||||
|
// NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
|
||||||
|
// reading existing policy from disk.
|
||||||
try {
|
try {
|
||||||
mPolicyManager.registerListener(mPolicyListener);
|
mPolicyManager.registerListener(mPolicyListener);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1116,11 +1140,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (ignoreBlocked) {
|
if (ignoreBlocked) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Networks are never blocked for system services
|
|
||||||
// TODO: consider moving this check to NetworkPolicyManagerInternal.isUidNetworkingBlocked.
|
|
||||||
if (isSystem(uid)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
synchronized (mVpns) {
|
synchronized (mVpns) {
|
||||||
final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
|
final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
|
||||||
if (vpn != null && vpn.isBlockingUid(uid)) {
|
if (vpn != null && vpn.isBlockingUid(uid)) {
|
||||||
@@ -1150,6 +1169,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mNetworkInfoBlockingLogs.log(action + " " + uid);
|
mNetworkInfoBlockingLogs.log(action + " " + uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
|
||||||
|
boolean blocked) {
|
||||||
|
if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String action = blocked ? "BLOCKED" : "UNBLOCKED";
|
||||||
|
log(String.format("Blocked status changed to %s for %d(%d) on netId %d", blocked,
|
||||||
|
nri.mUid, nri.request.requestId, net.netId));
|
||||||
|
mNetworkInfoBlockingLogs.log(action + " " + nri.mUid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@@ -1651,10 +1681,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
|
private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onUidRulesChanged(int uid, int uidRules) {
|
public void onUidRulesChanged(int uid, int uidRules) {
|
||||||
// TODO: notify UID when it has requested targeted updates
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onRestrictBackgroundChanged(boolean restrictBackground) {
|
public void onRestrictBackgroundChanged(boolean restrictBackground) {
|
||||||
|
// caller is NPMS, since we only register with them
|
||||||
|
if (LOGD_BLOCKED_NETWORKINFO) {
|
||||||
|
log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
|
||||||
|
}
|
||||||
|
mHandler.sendMessage(mHandler.obtainMessage(
|
||||||
|
EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
|
||||||
|
|
||||||
// TODO: relocate this specific callback in Tethering.
|
// TODO: relocate this specific callback in Tethering.
|
||||||
if (restrictBackground) {
|
if (restrictBackground) {
|
||||||
log("onRestrictBackgroundChanged(true): disabling tethering");
|
log("onRestrictBackgroundChanged(true): disabling tethering");
|
||||||
@@ -1663,6 +1700,50 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void handleUidRulesChanged(int uid, int newRules) {
|
||||||
|
// skip update when we've already applied rules
|
||||||
|
final int oldRules = mUidRules.get(uid, RULE_NONE);
|
||||||
|
if (oldRules == newRules) return;
|
||||||
|
|
||||||
|
maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
|
||||||
|
|
||||||
|
if (newRules == RULE_NONE) {
|
||||||
|
mUidRules.delete(uid);
|
||||||
|
} else {
|
||||||
|
mUidRules.put(uid, newRules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRestrictBackgroundChanged(boolean restrictBackground) {
|
||||||
|
if (mRestrictBackground == restrictBackground) return;
|
||||||
|
|
||||||
|
for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
||||||
|
final boolean curMetered = nai.networkCapabilities.isMetered();
|
||||||
|
maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
|
||||||
|
restrictBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
mRestrictBackground = restrictBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered,
|
||||||
|
boolean isBackgroundRestricted) {
|
||||||
|
synchronized (mVpns) {
|
||||||
|
final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
|
||||||
|
// Because the return value of this function depends on the list of UIDs the
|
||||||
|
// always-on VPN blocks when in lockdown mode, when the always-on VPN changes that
|
||||||
|
// list all state depending on the return value of this function has to be recomputed.
|
||||||
|
// TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and
|
||||||
|
// send the necessary onBlockedStatusChanged callbacks.
|
||||||
|
if (vpn != null && vpn.isBlockingUid(uid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
|
||||||
|
isNetworkMetered, isBackgroundRestricted);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Require that the caller is either in the same user or has appropriate permission to interact
|
* Require that the caller is either in the same user or has appropriate permission to interact
|
||||||
* across users.
|
* across users.
|
||||||
@@ -2118,6 +2199,28 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|
||||||
|
pw.print("Restrict background: ");
|
||||||
|
pw.println(mRestrictBackground);
|
||||||
|
pw.println();
|
||||||
|
|
||||||
|
pw.println("Status for known UIDs:");
|
||||||
|
pw.increaseIndent();
|
||||||
|
final int size = mUidRules.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
// Don't crash if the array is modified while dumping in bugreports.
|
||||||
|
try {
|
||||||
|
final int uid = mUidRules.keyAt(i);
|
||||||
|
final int uidRules = mUidRules.get(uid, RULE_NONE);
|
||||||
|
pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
pw.println(" ArrayIndexOutOfBoundsException");
|
||||||
|
} catch (ConcurrentModificationException e) {
|
||||||
|
pw.println(" ConcurrentModificationException");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pw.println();
|
||||||
|
pw.decreaseIndent();
|
||||||
|
|
||||||
pw.println("Network Requests:");
|
pw.println("Network Requests:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
dumpNetworkRequests(pw);
|
dumpNetworkRequests(pw);
|
||||||
@@ -3195,6 +3298,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
handlePrivateDnsValidationUpdate(
|
handlePrivateDnsValidationUpdate(
|
||||||
(PrivateDnsValidationUpdate) msg.obj);
|
(PrivateDnsValidationUpdate) msg.obj);
|
||||||
break;
|
break;
|
||||||
|
case EVENT_UID_RULES_CHANGED:
|
||||||
|
handleUidRulesChanged(msg.arg1, msg.arg2);
|
||||||
|
break;
|
||||||
|
case EVENT_DATA_SAVER_CHANGED:
|
||||||
|
handleRestrictBackgroundChanged(toBool(msg.arg1));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3783,6 +3892,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private void setLockdownTracker(LockdownVpnTracker tracker) {
|
private void setLockdownTracker(LockdownVpnTracker tracker) {
|
||||||
// Shutdown any existing tracker
|
// Shutdown any existing tracker
|
||||||
final LockdownVpnTracker existing = mLockdownTracker;
|
final LockdownVpnTracker existing = mLockdownTracker;
|
||||||
|
// TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
|
||||||
|
// necessary onBlockedStatusChanged callbacks.
|
||||||
mLockdownTracker = null;
|
mLockdownTracker = null;
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
existing.shutdown();
|
existing.shutdown();
|
||||||
@@ -4893,12 +5004,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
|
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report changes that are interesting for network statistics tracking.
|
|
||||||
if (prevNc != null) {
|
if (prevNc != null) {
|
||||||
final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) !=
|
final boolean oldMetered = prevNc.isMetered();
|
||||||
newNc.hasCapability(NET_CAPABILITY_NOT_METERED);
|
final boolean newMetered = newNc.isMetered();
|
||||||
|
final boolean meteredChanged = oldMetered != newMetered;
|
||||||
|
|
||||||
|
if (meteredChanged) {
|
||||||
|
maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
|
||||||
|
mRestrictBackground);
|
||||||
|
}
|
||||||
|
|
||||||
final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
|
final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
|
||||||
newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
|
newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
|
||||||
|
|
||||||
|
// Report changes that are interesting for network statistics tracking.
|
||||||
if (meteredChanged || roamingChanged) {
|
if (meteredChanged || roamingChanged) {
|
||||||
notifyIfacesChangedForNetworkStats();
|
notifyIfacesChangedForNetworkStats();
|
||||||
}
|
}
|
||||||
@@ -5028,6 +5147,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
case ConnectivityManager.CALLBACK_AVAILABLE: {
|
case ConnectivityManager.CALLBACK_AVAILABLE: {
|
||||||
putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
|
putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
|
||||||
putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
|
putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
|
||||||
|
// For this notification, arg1 contains the blocked status.
|
||||||
|
msg.arg1 = arg1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ConnectivityManager.CALLBACK_LOSING: {
|
case ConnectivityManager.CALLBACK_LOSING: {
|
||||||
@@ -5045,6 +5166,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
|
putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ConnectivityManager.CALLBACK_BLK_CHANGED: {
|
||||||
|
msg.arg1 = arg1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
msg.what = notificationType;
|
msg.what = notificationType;
|
||||||
msg.setData(bundle);
|
msg.setData(bundle);
|
||||||
@@ -5600,7 +5725,76 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
|
final boolean metered = nai.networkCapabilities.isMetered();
|
||||||
|
final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid),
|
||||||
|
metered, mRestrictBackground);
|
||||||
|
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify of the blocked state apps with a registered callback matching a given NAI.
|
||||||
|
*
|
||||||
|
* Unlike other callbacks, blocked status is different between each individual uid. So for
|
||||||
|
* any given nai, all requests need to be considered according to the uid who filed it.
|
||||||
|
*
|
||||||
|
* @param nai The target NetworkAgentInfo.
|
||||||
|
* @param oldMetered True if the previous network capabilities is metered.
|
||||||
|
* @param newRestrictBackground True if data saver is enabled.
|
||||||
|
*/
|
||||||
|
private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
|
||||||
|
boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) {
|
||||||
|
|
||||||
|
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
||||||
|
NetworkRequest nr = nai.requestAt(i);
|
||||||
|
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
||||||
|
final int uidRules = mUidRules.get(nri.mUid);
|
||||||
|
final boolean oldBlocked, newBlocked;
|
||||||
|
// mVpns lock needs to be hold here to ensure that the active VPN cannot be changed
|
||||||
|
// between these two calls.
|
||||||
|
synchronized (mVpns) {
|
||||||
|
oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered,
|
||||||
|
oldRestrictBackground);
|
||||||
|
newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered,
|
||||||
|
newRestrictBackground);
|
||||||
|
}
|
||||||
|
if (oldBlocked != newBlocked) {
|
||||||
|
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
|
||||||
|
encodeBool(newBlocked));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify apps with a given UID of the new blocked state according to new uid rules.
|
||||||
|
* @param uid The uid for which the rules changed.
|
||||||
|
* @param newRules The new rules to apply.
|
||||||
|
*/
|
||||||
|
private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
|
||||||
|
for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
|
||||||
|
final boolean metered = nai.networkCapabilities.isMetered();
|
||||||
|
final boolean oldBlocked, newBlocked;
|
||||||
|
// TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
|
||||||
|
// rules changed event. And this function actually loop through all connected nai and
|
||||||
|
// its requests. It seems that mVpns lock will be grabbed frequently in this case.
|
||||||
|
// Reduce the number of locking or optimize the use of lock are likely needed in future.
|
||||||
|
synchronized (mVpns) {
|
||||||
|
oldBlocked = isUidNetworkingWithVpnBlocked(
|
||||||
|
uid, mUidRules.get(uid), metered, mRestrictBackground);
|
||||||
|
newBlocked = isUidNetworkingWithVpnBlocked(
|
||||||
|
uid, newRules, metered, mRestrictBackground);
|
||||||
|
}
|
||||||
|
if (oldBlocked == newBlocked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int arg = encodeBool(newBlocked);
|
||||||
|
for (int i = 0; i < nai.numNetworkRequests(); i++) {
|
||||||
|
NetworkRequest nr = nai.requestAt(i);
|
||||||
|
NetworkRequestInfo nri = mNetworkRequests.get(nr);
|
||||||
|
if (nri != null && nri.mUid == uid) {
|
||||||
|
callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
|
private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
|
||||||
|
|||||||
Reference in New Issue
Block a user