DO NOT MERGE ANYWHERE Add CONNECTIVITY_USE_RESTRICTED_NETWORKS permission
am: 849682f5a0  -s ours

Change-Id: I2ba3b591df623298f41e92e6f0d067a6fcf30533
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2d7e6b0..75f5c15 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -169,6 +169,7 @@
     private static final boolean VDBG = false;
 
     private static final boolean LOGD_RULES = false;
+    private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
 
     // TODO: create better separation between radio types and network types
 
@@ -955,6 +956,21 @@
         }
     }
 
+    private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
+        if (ni == null || !LOGD_BLOCKED_NETWORKINFO) return;
+        boolean removed = false;
+        boolean added = false;
+        synchronized (mBlockedAppUids) {
+            if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
+                added = true;
+            } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
+                removed = true;
+            }
+        }
+        if (added) log("Returning blocked NetworkInfo to uid=" + uid);
+        else if (removed) log("Returning unblocked NetworkInfo to uid=" + uid);
+    }
+
     /**
      * Return a filtered {@link NetworkInfo}, potentially marked
      * {@link DetailedState#BLOCKED} based on
@@ -965,10 +981,6 @@
             // network is blocked; clone and override state
             info = new NetworkInfo(info);
             info.setDetailedState(DetailedState.BLOCKED, null, null);
-            if (VDBG) {
-                log("returning Blocked NetworkInfo for ifname=" +
-                        lp.getInterfaceName() + ", uid=" + uid);
-            }
         }
         if (info != null && mLockdownTracker != null) {
             info = mLockdownTracker.augmentNetworkInfo(info);
@@ -989,7 +1001,9 @@
         enforceAccessPermission();
         final int uid = Binder.getCallingUid();
         NetworkState state = getUnfilteredActiveNetworkState(uid);
-        return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+        NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+        maybeLogBlockedNetworkInfo(ni, uid);
+        return ni;
     }
 
     @Override
@@ -1462,16 +1476,6 @@
                 "ConnectivityService");
     }
 
-    private void enforceConnectivityRestrictedNetworksPermission() {
-        try {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS,
-                    "ConnectivityService");
-            return;
-        } catch (SecurityException e) { /* fallback to ConnectivityInternalPermission */ }
-        enforceConnectivityInternalPermission();
-    }
-
     private void enforceKeepalivePermission() {
         mContext.enforceCallingOrSelfPermission(KeepaliveTracker.PERMISSION, "ConnectivityService");
     }
@@ -3704,7 +3708,7 @@
 
     private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
         if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
-            enforceConnectivityRestrictedNetworksPermission();
+            enforceConnectivityInternalPermission();
         } else {
             enforceChangePermission();
         }
@@ -3892,6 +3896,9 @@
     private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
             new HashMap<Messenger, NetworkAgentInfo>();
 
+    @GuardedBy("mBlockedAppUids")
+    private final HashSet<Integer> mBlockedAppUids = new HashSet();
+
     // Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
     private final NetworkRequest mDefaultRequest;
 
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 94e9f70..debda14 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.CHANGE_NETWORK_STATE;
 import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
-import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
 import static android.content.pm.ApplicationInfo.FLAG_SYSTEM;
 import static android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
@@ -66,10 +65,10 @@
     private final BroadcastReceiver mIntentReceiver;
 
     // Values are User IDs.
-    private final Set<Integer> mUsers = new HashSet<>();
+    private final Set<Integer> mUsers = new HashSet<Integer>();
 
     // Keys are App IDs. Values are true for SYSTEM permission and false for NETWORK permission.
-    private final Map<Integer, Boolean> mApps = new HashMap<>();
+    private final Map<Integer, Boolean> mApps = new HashMap<Integer, Boolean>();
 
     public PermissionMonitor(Context context, INetworkManagementService netd) {
         mContext = context;
@@ -127,14 +126,14 @@
             }
 
             boolean isNetwork = hasNetworkPermission(app);
-            boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
+            boolean isSystem = hasSystemPermission(app);
 
-            if (isNetwork || hasRestrictedPermission) {
+            if (isNetwork || isSystem) {
                 Boolean permission = mApps.get(uid);
                 // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
                 // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
                 if (permission == null || permission == NETWORK) {
-                    mApps.put(uid, hasRestrictedPermission);
+                    mApps.put(uid, isSystem);
                 }
             }
         }
@@ -165,13 +164,12 @@
         return hasPermission(app, CHANGE_NETWORK_STATE);
     }
 
-    private boolean hasRestrictedNetworkPermission(PackageInfo app) {
+    private boolean hasSystemPermission(PackageInfo app) {
         int flags = app.applicationInfo != null ? app.applicationInfo.flags : 0;
         if ((flags & FLAG_SYSTEM) != 0 || (flags & FLAG_UPDATED_SYSTEM_APP) != 0) {
             return true;
         }
-        return hasPermission(app, CONNECTIVITY_INTERNAL)
-                || hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
+        return hasPermission(app, CONNECTIVITY_INTERNAL);
     }
 
     private int[] toIntArray(List<Integer> list) {
@@ -183,8 +181,8 @@
     }
 
     private void update(Set<Integer> users, Map<Integer, Boolean> apps, boolean add) {
-        List<Integer> network = new ArrayList<>();
-        List<Integer> system = new ArrayList<>();
+        List<Integer> network = new ArrayList<Integer>();
+        List<Integer> system = new ArrayList<Integer>();
         for (Entry<Integer, Boolean> app : apps.entrySet()) {
             List<Integer> list = app.getValue() ? system : network;
             for (int user : users) {
@@ -211,7 +209,7 @@
         }
         mUsers.add(user);
 
-        Set<Integer> users = new HashSet<>();
+        Set<Integer> users = new HashSet<Integer>();
         users.add(user);
         update(users, mApps, true);
     }
@@ -223,7 +221,7 @@
         }
         mUsers.remove(user);
 
-        Set<Integer> users = new HashSet<>();
+        Set<Integer> users = new HashSet<Integer>();
         users.add(user);
         update(users, mApps, false);
     }
@@ -237,16 +235,16 @@
         try {
             PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS);
             boolean isNetwork = hasNetworkPermission(app);
-            boolean hasRestrictedPermission = hasRestrictedNetworkPermission(app);
-            if (isNetwork || hasRestrictedPermission) {
+            boolean isSystem = hasSystemPermission(app);
+            if (isNetwork || isSystem) {
                 Boolean permission = mApps.get(appUid);
                 // If multiple packages share a UID (cf: android:sharedUserId) and ask for different
                 // permissions, don't downgrade (i.e., if it's already SYSTEM, leave it as is).
                 if (permission == null || permission == NETWORK) {
-                    mApps.put(appUid, hasRestrictedPermission);
+                    mApps.put(appUid, isSystem);
 
-                    Map<Integer, Boolean> apps = new HashMap<>();
-                    apps.put(appUid, hasRestrictedPermission);
+                    Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
+                    apps.put(appUid, isSystem);
                     update(mUsers, apps, true);
                 }
             }
@@ -262,7 +260,7 @@
         }
         mApps.remove(appUid);
 
-        Map<Integer, Boolean> apps = new HashMap<>();
+        Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
         apps.put(appUid, NETWORK);  // doesn't matter which permission we pick here
         update(mUsers, apps, false);
     }