Merge "Move back networking policy logic into NetworkPolicyManagerService" into oc-dev
am: 1173ec5bbb
Change-Id: I7d7b66cc1dc6888ea28e2b4d83d570fa440c29f2
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_RESTRICTED;
|
||||
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.app.BroadcastOptions;
|
||||
@@ -103,7 +96,6 @@ import android.security.Credentials;
|
||||
import android.security.KeyStore;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.LocalLog;
|
||||
import android.util.LocalLog.ReadOnlyLocalLog;
|
||||
import android.util.Log;
|
||||
@@ -129,6 +121,7 @@ import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.MessageUtils;
|
||||
import com.android.internal.util.WakeupMessage;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.am.BatteryStatsService;
|
||||
import com.android.server.connectivity.DataConnectionStats;
|
||||
import com.android.server.connectivity.KeepaliveTracker;
|
||||
@@ -146,6 +139,7 @@ import com.android.server.connectivity.Tethering;
|
||||
import com.android.server.connectivity.Vpn;
|
||||
import com.android.server.net.BaseNetworkObserver;
|
||||
import com.android.server.net.LockdownVpnTracker;
|
||||
import com.android.server.net.NetworkPolicyManagerInternal;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
@@ -222,18 +216,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private boolean mLockdownEnabled;
|
||||
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;
|
||||
private int mNetworkPreference;
|
||||
// 0 is full bad, 100 is full good
|
||||
@@ -247,6 +229,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private INetworkManagementService mNetd;
|
||||
private INetworkStatsService mStatsService;
|
||||
private INetworkPolicyManager mPolicyManager;
|
||||
private NetworkPolicyManagerInternal mPolicyManagerInternal;
|
||||
|
||||
private String mCurrentTcpBufferSizes;
|
||||
|
||||
@@ -718,12 +701,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mNetd = checkNotNull(netManager, "missing INetworkManagementService");
|
||||
mStatsService = checkNotNull(statsService, "missing INetworkStatsService");
|
||||
mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager");
|
||||
mPolicyManagerInternal = checkNotNull(
|
||||
LocalServices.getService(NetworkPolicyManagerInternal.class),
|
||||
"missing NetworkPolicyManagerInternal");
|
||||
|
||||
mKeyStore = KeyStore.getInstance();
|
||||
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
||||
try {
|
||||
mPolicyManager.setConnectivityListener(mPolicyListener);
|
||||
mRestrictBackground = mPolicyManager.getRestrictBackground();
|
||||
mPolicyManager.registerListener(mPolicyListener);
|
||||
} catch (RemoteException e) {
|
||||
// ouch, no rules updates means some processes may never get network
|
||||
loge("unable to register INetworkPolicyListener" + e);
|
||||
@@ -990,51 +976,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
|
||||
boolean ignoreBlocked) {
|
||||
// Networks aren't blocked when ignoring blocked status
|
||||
if (ignoreBlocked) return false;
|
||||
if (ignoreBlocked) {
|
||||
return false;
|
||||
}
|
||||
// Networks are never blocked for system services
|
||||
if (isSystem(uid)) return false;
|
||||
|
||||
final boolean networkMetered;
|
||||
final int uidRules;
|
||||
|
||||
// TODO: consider moving this check to NetworkPolicyManagerInternal.isUidNetworkingBlocked.
|
||||
if (isSystem(uid)) {
|
||||
return false;
|
||||
}
|
||||
synchronized (mVpns) {
|
||||
final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
|
||||
if (vpn != null && vpn.isBlockingUid(uid)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
final String iface = (lp == null ? "" : lp.getInterfaceName());
|
||||
synchronized (mRulesLock) {
|
||||
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;
|
||||
return mPolicyManagerInternal.isUidNetworkingBlocked(uid, iface);
|
||||
}
|
||||
|
||||
private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
|
||||
@@ -1477,67 +1434,24 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return true;
|
||||
}
|
||||
|
||||
private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
|
||||
private final INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
|
||||
@Override
|
||||
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
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
public void onRestrictBackgroundChanged(boolean restrictBackground) {
|
||||
// caller is NPMS, since we only register with them
|
||||
if (LOGD_RULES) {
|
||||
log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
|
||||
}
|
||||
|
||||
synchronized (mRulesLock) {
|
||||
mRestrictBackground = restrictBackground;
|
||||
}
|
||||
|
||||
// TODO: relocate this specific callback in Tethering.
|
||||
if (restrictBackground) {
|
||||
log("onRestrictBackgroundChanged(true): disabling tethering");
|
||||
mTethering.untetherAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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 + ")");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1973,33 +1887,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
pw.decreaseIndent();
|
||||
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.increaseIndent();
|
||||
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
|
||||
@@ -3427,6 +3314,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
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) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException(message);
|
||||
@@ -4176,22 +4067,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
|
||||
final int uid = Binder.getCallingUid();
|
||||
if (isSystem(uid)) {
|
||||
// Exemption for system uid.
|
||||
return;
|
||||
}
|
||||
// if UID is restricted, don't allow them to bring up metered APNs
|
||||
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED) == false) {
|
||||
final int uidRules;
|
||||
synchronized(mRulesLock) {
|
||||
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
|
||||
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)) {
|
||||
// Policy already enforced.
|
||||
return;
|
||||
}
|
||||
if (mRestrictBackground && (uidRules & RULE_ALLOW_METERED) == 0
|
||||
&& (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.
|
||||
if (mPolicyManagerInternal.isUidRestrictedOnMeteredNetworks(uid)) {
|
||||
// If UID is restricted, don't allow them to bring up metered APNs.
|
||||
networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
|
||||
|
||||
@@ -87,6 +87,7 @@ import com.android.server.connectivity.NetworkAgentInfo;
|
||||
import com.android.server.connectivity.NetworkMonitor;
|
||||
import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
|
||||
import com.android.server.net.NetworkPinner;
|
||||
import com.android.server.net.NetworkPolicyManagerInternal;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
@@ -750,6 +751,9 @@ public class ConnectivityServiceTest extends AndroidTestCase {
|
||||
}
|
||||
|
||||
mServiceContext = new MockContext(getContext());
|
||||
LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
|
||||
LocalServices.addService(
|
||||
NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
|
||||
mService = new WrappedConnectivityService(mServiceContext,
|
||||
mock(INetworkManagementService.class),
|
||||
mock(INetworkStatsService.class),
|
||||
|
||||
Reference in New Issue
Block a user