Block metered APNs when app is restricted.

When an app is restricted in the background, don't allow them to
start using metered network features. With this change they can
still use network features when in foreground. This avoids situation
where apps can bring up APNs which they are unable to use.

Bug: 5838267
Change-Id: I3ac96f2a545f67cba1ef12b8536cfd0da769d955
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index dd650bf..e396a69 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -884,22 +884,25 @@
     @Override
     public boolean isActiveNetworkMetered() {
         enforceAccessPermission();
-
         final long token = Binder.clearCallingIdentity();
         try {
-            final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
-            if (state != null) {
-                try {
-                    return mPolicyManager.isNetworkMetered(state);
-                } catch (RemoteException e) {
-                }
-            }
-            return false;
+            return isNetworkMeteredUnchecked(mActiveDefaultNetwork);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
+    private boolean isNetworkMeteredUnchecked(int networkType) {
+        final NetworkState state = getNetworkStateUnchecked(networkType);
+        if (state != null) {
+            try {
+                return mPolicyManager.isNetworkMetered(state);
+            } catch (RemoteException e) {
+            }
+        }
+        return false;
+    }
+
     public boolean setRadios(boolean turnOn) {
         boolean result = true;
         enforceChangePermission();
@@ -993,7 +996,8 @@
     public int startUsingNetworkFeature(int networkType, String feature,
             IBinder binder) {
         if (VDBG) {
-            log("startUsingNetworkFeature for net " + networkType + ": " + feature);
+            log("startUsingNetworkFeature for net " + networkType + ": " + feature + ", uid="
+                    + Binder.getCallingUid());
         }
         enforceChangePermission();
         if (!ConnectivityManager.isNetworkTypeValid(networkType) ||
@@ -1010,6 +1014,16 @@
             enforceConnectivityInternalPermission();
         }
 
+        // if UID is restricted, don't allow them to bring up metered APNs
+        final boolean networkMetered = isNetworkMeteredUnchecked(usedNetworkType);
+        final int uidRules;
+        synchronized (mRulesLock) {
+            uidRules = mUidRules.get(Binder.getCallingUid(), RULE_ALLOW_ALL);
+        }
+        if (networkMetered && (uidRules & RULE_REJECT_METERED) != 0) {
+            return Phone.APN_REQUEST_FAILED;
+        }
+
         NetworkStateTracker network = mNetTrackers[usedNetworkType];
         if (network != null) {
             Integer currentPid = new Integer(getCallingPid());
@@ -1432,7 +1446,6 @@
                 mUidRules.put(uid, uidRules);
             }
 
-            // TODO: dispatch into NMS to push rules towards kernel module
             // TODO: notify UID when it has requested targeted updates
         }