Merge "Move back networking policy logic into NetworkPolicyManagerService" into oc-dev
This commit is contained in:
@@ -29,13 +29,6 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
|||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||||
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
|
|
||||||
import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
|
|
||||||
import static android.net.NetworkPolicyManager.RULE_NONE;
|
|
||||||
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
|
|
||||||
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
|
|
||||||
import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
|
|
||||||
import static android.net.NetworkPolicyManager.uidRulesToString;
|
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.BroadcastOptions;
|
import android.app.BroadcastOptions;
|
||||||
@@ -104,7 +97,6 @@ import android.security.Credentials;
|
|||||||
import android.security.KeyStore;
|
import android.security.KeyStore;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
|
||||||
import android.util.LocalLog;
|
import android.util.LocalLog;
|
||||||
import android.util.LocalLog.ReadOnlyLocalLog;
|
import android.util.LocalLog.ReadOnlyLocalLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -130,6 +122,7 @@ import com.android.internal.util.IndentingPrintWriter;
|
|||||||
import com.android.internal.util.MessageUtils;
|
import com.android.internal.util.MessageUtils;
|
||||||
import com.android.internal.util.WakeupMessage;
|
import com.android.internal.util.WakeupMessage;
|
||||||
import com.android.internal.util.XmlUtils;
|
import com.android.internal.util.XmlUtils;
|
||||||
|
import com.android.server.LocalServices;
|
||||||
import com.android.server.am.BatteryStatsService;
|
import com.android.server.am.BatteryStatsService;
|
||||||
import com.android.server.connectivity.DataConnectionStats;
|
import com.android.server.connectivity.DataConnectionStats;
|
||||||
import com.android.server.connectivity.KeepaliveTracker;
|
import com.android.server.connectivity.KeepaliveTracker;
|
||||||
@@ -147,6 +140,7 @@ import com.android.server.connectivity.Tethering;
|
|||||||
import com.android.server.connectivity.Vpn;
|
import com.android.server.connectivity.Vpn;
|
||||||
import com.android.server.net.BaseNetworkObserver;
|
import com.android.server.net.BaseNetworkObserver;
|
||||||
import com.android.server.net.LockdownVpnTracker;
|
import com.android.server.net.LockdownVpnTracker;
|
||||||
|
import com.android.server.net.NetworkPolicyManagerInternal;
|
||||||
|
|
||||||
import com.google.android.collect.Lists;
|
import com.google.android.collect.Lists;
|
||||||
|
|
||||||
@@ -221,18 +215,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private boolean mLockdownEnabled;
|
private boolean mLockdownEnabled;
|
||||||
private LockdownVpnTracker mLockdownTracker;
|
private LockdownVpnTracker mLockdownTracker;
|
||||||
|
|
||||||
/** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
|
|
||||||
private Object mRulesLock = new Object();
|
|
||||||
/** Currently active network rules by UID. */
|
|
||||||
@GuardedBy("mRulesLock")
|
|
||||||
private SparseIntArray mUidRules = new SparseIntArray();
|
|
||||||
/** Set of ifaces that are costly. */
|
|
||||||
@GuardedBy("mRulesLock")
|
|
||||||
private ArraySet<String> mMeteredIfaces = new ArraySet<>();
|
|
||||||
/** Flag indicating if background data is restricted. */
|
|
||||||
@GuardedBy("mRulesLock")
|
|
||||||
private boolean mRestrictBackground;
|
|
||||||
|
|
||||||
final private Context mContext;
|
final private Context mContext;
|
||||||
private int mNetworkPreference;
|
private int mNetworkPreference;
|
||||||
// 0 is full bad, 100 is full good
|
// 0 is full bad, 100 is full good
|
||||||
@@ -246,6 +228,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private INetworkManagementService mNetd;
|
private INetworkManagementService mNetd;
|
||||||
private INetworkStatsService mStatsService;
|
private INetworkStatsService mStatsService;
|
||||||
private INetworkPolicyManager mPolicyManager;
|
private INetworkPolicyManager mPolicyManager;
|
||||||
|
private NetworkPolicyManagerInternal mPolicyManagerInternal;
|
||||||
|
|
||||||
private String mCurrentTcpBufferSizes;
|
private String mCurrentTcpBufferSizes;
|
||||||
|
|
||||||
@@ -715,12 +698,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mNetd = checkNotNull(netManager, "missing INetworkManagementService");
|
mNetd = checkNotNull(netManager, "missing INetworkManagementService");
|
||||||
mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
|
mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
|
||||||
mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
|
mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
|
||||||
|
mPolicyManagerInternal = checkNotNull(
|
||||||
|
LocalServices.getService(NetworkPolicyManagerInternal.class),
|
||||||
|
"missing NetworkPolicyManagerInternal");
|
||||||
|
|
||||||
mKeyStore = KeyStore.getInstance();
|
mKeyStore = KeyStore.getInstance();
|
||||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mPolicyManager.setConnectivityListener(mPolicyListener);
|
mPolicyManager.registerListener(mPolicyListener);
|
||||||
mRestrictBackground = mPolicyManager.getRestrictBackground();
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// ouch, no rules updates means some processes may never get network
|
// ouch, no rules updates means some processes may never get network
|
||||||
loge("unable to register INetworkPolicyListener" + e);
|
loge("unable to register INetworkPolicyListener" + e);
|
||||||
@@ -991,51 +977,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
|
private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
|
||||||
boolean ignoreBlocked) {
|
boolean ignoreBlocked) {
|
||||||
// Networks aren't blocked when ignoring blocked status
|
// Networks aren't blocked when ignoring blocked status
|
||||||
if (ignoreBlocked) return false;
|
if (ignoreBlocked) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Networks are never blocked for system services
|
// Networks are never blocked for system services
|
||||||
if (isSystem(uid)) return false;
|
// TODO: consider moving this check to NetworkPolicyManagerInternal.isUidNetworkingBlocked.
|
||||||
|
if (isSystem(uid)) {
|
||||||
final boolean networkMetered;
|
return false;
|
||||||
final int uidRules;
|
}
|
||||||
|
|
||||||
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)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final String iface = (lp == null ? "" : lp.getInterfaceName());
|
final String iface = (lp == null ? "" : lp.getInterfaceName());
|
||||||
synchronized (mRulesLock) {
|
return mPolicyManagerInternal.isUidNetworkingBlocked(uid, iface);
|
||||||
networkMetered = mMeteredIfaces.contains(iface);
|
|
||||||
uidRules = mUidRules.get(uid, RULE_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean allowed = true;
|
|
||||||
// Check Data Saver Mode first...
|
|
||||||
if (networkMetered) {
|
|
||||||
if ((uidRules & RULE_REJECT_METERED) != 0) {
|
|
||||||
if (LOGD_RULES) Log.d(TAG, "uid " + uid + " is blacklisted");
|
|
||||||
// Explicitly blacklisted.
|
|
||||||
allowed = false;
|
|
||||||
} else {
|
|
||||||
allowed = !mRestrictBackground
|
|
||||||
|| (uidRules & RULE_ALLOW_METERED) != 0
|
|
||||||
|| (uidRules & RULE_TEMPORARY_ALLOW_METERED) != 0;
|
|
||||||
if (LOGD_RULES) Log.d(TAG, "allowed status for uid " + uid + " when"
|
|
||||||
+ " mRestrictBackground=" + mRestrictBackground
|
|
||||||
+ ", whitelisted=" + ((uidRules & RULE_ALLOW_METERED) != 0)
|
|
||||||
+ ", tempWhitelist= + ((uidRules & RULE_TEMPORARY_ALLOW_METERED) != 0)"
|
|
||||||
+ ": " + allowed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ...then power restrictions.
|
|
||||||
if (allowed) {
|
|
||||||
allowed = (uidRules & RULE_REJECT_ALL) == 0;
|
|
||||||
if (LOGD_RULES) Log.d(TAG, "allowed status for uid " + uid + " when"
|
|
||||||
+ " rule is " + uidRulesToString(uidRules) + ": " + allowed);
|
|
||||||
}
|
|
||||||
return !allowed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
|
private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
|
||||||
@@ -1481,67 +1438,24 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
|
private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onUidRulesChanged(int uid, int uidRules) {
|
public void onUidRulesChanged(int uid, int uidRules) {
|
||||||
// caller is NPMS, since we only register with them
|
|
||||||
if (LOGD_RULES) {
|
|
||||||
log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mRulesLock) {
|
|
||||||
// skip update when we've already applied rules
|
|
||||||
final int oldRules = mUidRules.get(uid, RULE_NONE);
|
|
||||||
if (oldRules == uidRules) return;
|
|
||||||
|
|
||||||
if (uidRules == RULE_NONE) {
|
|
||||||
mUidRules.delete(uid);
|
|
||||||
} else {
|
|
||||||
mUidRules.put(uid, uidRules);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: notify UID when it has requested targeted updates
|
// TODO: notify UID when it has requested targeted updates
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMeteredIfacesChanged(String[] meteredIfaces) {
|
public void onMeteredIfacesChanged(String[] meteredIfaces) {
|
||||||
// caller is NPMS, since we only register with them
|
|
||||||
if (LOGD_RULES) {
|
|
||||||
log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mRulesLock) {
|
|
||||||
mMeteredIfaces.clear();
|
|
||||||
for (String iface : meteredIfaces) {
|
|
||||||
mMeteredIfaces.add(iface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRestrictBackgroundChanged(boolean restrictBackground) {
|
public void onRestrictBackgroundChanged(boolean restrictBackground) {
|
||||||
// caller is NPMS, since we only register with them
|
// TODO: relocate this specific callback in Tethering.
|
||||||
if (LOGD_RULES) {
|
|
||||||
log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (mRulesLock) {
|
|
||||||
mRestrictBackground = restrictBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (restrictBackground) {
|
if (restrictBackground) {
|
||||||
log("onRestrictBackgroundChanged(true): disabling tethering");
|
log("onRestrictBackgroundChanged(true): disabling tethering");
|
||||||
mTethering.untetherAll();
|
mTethering.untetherAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUidPoliciesChanged(int uid, int uidPolicies) {
|
public void onUidPoliciesChanged(int uid, int uidPolicies) {
|
||||||
// caller is NPMS, since we only register with them
|
|
||||||
if (LOGD_RULES) {
|
|
||||||
log("onUidRulesChanged(uid=" + uid + ", uidPolicies=" + uidPolicies + ")");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1976,33 +1890,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
pw.println();
|
pw.println();
|
||||||
|
|
||||||
pw.println("Metered Interfaces:");
|
|
||||||
pw.increaseIndent();
|
|
||||||
for (String value : mMeteredIfaces) {
|
|
||||||
pw.println(value);
|
|
||||||
}
|
|
||||||
pw.decreaseIndent();
|
|
||||||
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++) {
|
|
||||||
final int uid = mUidRules.keyAt(i);
|
|
||||||
pw.print("UID=");
|
|
||||||
pw.print(uid);
|
|
||||||
final int uidRules = mUidRules.get(uid, RULE_NONE);
|
|
||||||
pw.print(" rules=");
|
|
||||||
pw.print(uidRulesToString(uidRules));
|
|
||||||
pw.println();
|
|
||||||
}
|
|
||||||
pw.println();
|
|
||||||
pw.decreaseIndent();
|
|
||||||
|
|
||||||
pw.println("Network Requests:");
|
pw.println("Network Requests:");
|
||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||||
@@ -3437,6 +3324,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
Slog.e(TAG, s);
|
Slog.e(TAG, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loge(String s, Throwable t) {
|
||||||
|
Slog.e(TAG, s, t);
|
||||||
|
}
|
||||||
|
|
||||||
private static <T> T checkNotNull(T value, String message) {
|
private static <T> T checkNotNull(T value, String message) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new NullPointerException(message);
|
throw new NullPointerException(message);
|
||||||
@@ -4197,20 +4088,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
|
private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
|
||||||
final int uid = Binder.getCallingUid();
|
final int uid = Binder.getCallingUid();
|
||||||
if (isSystem(uid)) {
|
if (isSystem(uid)) {
|
||||||
|
// Exemption for system uid.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if UID is restricted, don't allow them to bring up metered APNs
|
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
|
||||||
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED) == false) {
|
// Policy already enforced.
|
||||||
final int uidRules;
|
return;
|
||||||
synchronized(mRulesLock) {
|
}
|
||||||
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
|
if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) {
|
||||||
}
|
// If UID is restricted, don't allow them to bring up metered APNs.
|
||||||
if (mRestrictBackground && (uidRules & RULE_ALLOW_METERED) == 0
|
networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||||
&& (uidRules & RULE_TEMPORARY_ALLOW_METERED) == 0) {
|
|
||||||
// we could silently fail or we can filter the available nets to only give
|
|
||||||
// them those they have access to. Chose the more useful option.
|
|
||||||
networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ import com.android.server.connectivity.NetworkAgentInfo;
|
|||||||
import com.android.server.connectivity.NetworkMonitor;
|
import com.android.server.connectivity.NetworkMonitor;
|
||||||
import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
|
import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
|
||||||
import com.android.server.net.NetworkPinner;
|
import com.android.server.net.NetworkPinner;
|
||||||
|
import com.android.server.net.NetworkPolicyManagerInternal;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -713,6 +714,9 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mServiceContext = new MockContext(getContext());
|
mServiceContext = new MockContext(getContext());
|
||||||
|
LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
|
||||||
|
LocalServices.addService(
|
||||||
|
NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
|
||||||
mService = new WrappedConnectivityService(mServiceContext,
|
mService = new WrappedConnectivityService(mServiceContext,
|
||||||
mock(INetworkManagementService.class),
|
mock(INetworkManagementService.class),
|
||||||
mock(INetworkStatsService.class),
|
mock(INetworkStatsService.class),
|
||||||
|
|||||||
Reference in New Issue
Block a user