Merge "DHCPv4: lease expiration is fatal, renew failures are not" into nyc-dev
am: 42a5755916

* commit '42a5755916a21f01d264bdb58d2213dacf221cdf':
  DHCPv4: lease expiration is fatal, renew failures are not

Change-Id: Ic99edb732d532da27c042824e5ca07c4b35ccfa1
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 2364787..f79254d 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -25,11 +25,8 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <linux/filter.h>
-#include <linux/if.h>
 #include <linux/if_arp.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <net/if_ether.h>
+#include <netinet/ether.h>
 #include <netinet/icmp6.h>
 #include <netinet/ip.h>
 #include <netinet/ip6.h>
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 22cefd1..eb1c77e 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -54,9 +54,9 @@
  */
 public class PermissionMonitor {
     private static final String TAG = "PermissionMonitor";
-    private static final boolean DBG = false;
-    private static final boolean SYSTEM = true;
-    private static final boolean NETWORK = false;
+    private static final boolean DBG = true;
+    private static final Boolean SYSTEM = Boolean.TRUE;
+    private static final Boolean NETWORK = Boolean.FALSE;
 
     private final Context mContext;
     private final PackageManager mPackageManager;
@@ -226,30 +226,40 @@
         update(users, mApps, false);
     }
 
+
+    private Boolean highestPermissionForUid(Boolean currentPermission, String name) {
+        if (currentPermission == SYSTEM) {
+            return currentPermission;
+        }
+        try {
+            final PackageInfo app = mPackageManager.getPackageInfo(name, GET_PERMISSIONS);
+            final boolean isNetwork = hasNetworkPermission(app);
+            final boolean isSystem = hasSystemPermission(app);
+            if (isNetwork || isSystem) {
+                currentPermission = isSystem;
+            }
+        } catch (NameNotFoundException e) {
+            // App not found.
+            loge("NameNotFoundException " + name);
+        }
+        return currentPermission;
+    }
+
     private synchronized void onAppAdded(String appName, int appUid) {
         if (TextUtils.isEmpty(appName) || appUid < 0) {
             loge("Invalid app in onAppAdded: " + appName + " | " + appUid);
             return;
         }
 
-        try {
-            PackageInfo app = mPackageManager.getPackageInfo(appName, GET_PERMISSIONS);
-            boolean isNetwork = hasNetworkPermission(app);
-            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, isSystem);
+        // 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).
+        final Boolean permission = highestPermissionForUid(mApps.get(appUid), appName);
+        if (permission != mApps.get(appUid)) {
+            mApps.put(appUid, permission);
 
-                    Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
-                    apps.put(appUid, isSystem);
-                    update(mUsers, apps, true);
-                }
-            }
-        } catch (NameNotFoundException e) {
-            loge("NameNotFoundException in onAppAdded: " + e);
+            Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
+            apps.put(appUid, permission);
+            update(mUsers, apps, true);
         }
     }
 
@@ -258,11 +268,33 @@
             loge("Invalid app in onAppRemoved: " + appUid);
             return;
         }
-        mApps.remove(appUid);
-
         Map<Integer, Boolean> apps = new HashMap<Integer, Boolean>();
-        apps.put(appUid, NETWORK);  // doesn't matter which permission we pick here
-        update(mUsers, apps, false);
+
+        Boolean permission = null;
+        String[] packages = mPackageManager.getPackagesForUid(appUid);
+        if (packages != null && packages.length > 0) {
+            for (String name : packages) {
+                permission = highestPermissionForUid(permission, name);
+                if (permission == SYSTEM) {
+                    // An app with this UID still has the SYSTEM permission.
+                    // Therefore, this UID must already have the SYSTEM permission.
+                    // Nothing to do.
+                    return;
+                }
+            }
+        }
+        if (permission == mApps.get(appUid)) {
+            // The permissions of this UID have not changed. Nothing to do.
+            return;
+        } else if (permission != null) {
+            mApps.put(appUid, permission);
+            apps.put(appUid, permission);
+            update(mUsers, apps, true);
+        } else {
+            mApps.remove(appUid);
+            apps.put(appUid, NETWORK);  // doesn't matter which permission we pick here
+            update(mUsers, apps, false);
+        }
     }
 
     private static void log(String s) {