diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index 22cefd14d4..eb1c77e97c 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 @@ import java.util.Set; */ 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 @@ public class PermissionMonitor { 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 apps = new HashMap(); - apps.put(appUid, isSystem); - update(mUsers, apps, true); - } - } - } catch (NameNotFoundException e) { - loge("NameNotFoundException in onAppAdded: " + e); + Map apps = new HashMap(); + apps.put(appUid, permission); + update(mUsers, apps, true); } } @@ -258,11 +268,33 @@ public class PermissionMonitor { loge("Invalid app in onAppRemoved: " + appUid); return; } - mApps.remove(appUid); - Map apps = new HashMap(); - 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) {