Move mPermissionGroups

Bug: 63539144
Test: Manual. Builds and runs
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.PermissionsHostTest
Test: cts-tradefed run commandAndExit cts-dev -m CtsPermissionTestCases
Test: cts-tradefed run commandAndExit cts-dev -m CtsPermission2TestCases
Test: bit FrameworksServicesTests:com.android.server.pm.PackageManagerSettingsTests
Change-Id: I3b019babc81997d1d70c14675a34b6a8bec5387d
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index d2d857c..6b5ec43 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -27,7 +27,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PackageParser;
-import android.content.pm.ParceledListSlice;
+import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
 import android.content.pm.PackageParser.Package;
 import android.os.Binder;
@@ -230,14 +230,40 @@
         return PackageManager.PERMISSION_DENIED;
     }
 
-    private PermissionInfo getPermissionInfo(String name, String packageName, int flags,
+    private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
+            int callingUid) {
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            return PackageParser.generatePermissionGroupInfo(
+                    mSettings.mPermissionGroups.get(groupName), flags);
+        }
+    }
+
+    private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
+        if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
+            return null;
+        }
+        synchronized (mLock) {
+            final int N = mSettings.mPermissionGroups.size();
+            final ArrayList<PermissionGroupInfo> out
+                    = new ArrayList<PermissionGroupInfo>(N);
+            for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
+                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
+            }
+            return out;
+        }
+    }
+
+    private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
             int callingUid) {
         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
             return null;
         }
         // reader
         synchronized (mLock) {
-            final BasePermission bp = mSettings.getPermissionLocked(name);
+            final BasePermission bp = mSettings.getPermissionLocked(permName);
             if (bp == null) {
                 return null;
             }
@@ -252,14 +278,10 @@
         if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
             return null;
         }
-        // reader
         synchronized (mLock) {
-            // TODO Uncomment when mPermissionGroups moves to this class
-//            if (groupName != null && !mPermissionGroups.containsKey(groupName)) {
-//                // This is thrown as NameNotFoundException
-//                return null;
-//            }
-
+            if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
+                return null;
+            }
             final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
             for (BasePermission bp : mSettings.mPermissions.values()) {
                 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
@@ -314,21 +336,21 @@
             // Assume by default that we did not install this permission into the system.
             p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
 
-            // Now that permission groups have a special meaning, we ignore permission
-            // groups for legacy apps to prevent unexpected behavior. In particular,
-            // permissions for one app being granted to someone just because they happen
-            // to be in a group defined by another app (before this had no implications).
-            if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
-                p.group = mPackageManagerInt.getPermissionGroupTEMP(p.info.group);
-                // Warn for a permission in an unknown group.
-                if (PackageManagerService.DEBUG_PERMISSIONS
-                        && p.info.group != null && p.group == null) {
-                    Slog.i(TAG, "Permission " + p.info.name + " from package "
-                            + p.info.packageName + " in an unknown group " + p.info.group);
-                }
-            }
-
             synchronized (PermissionManagerService.this.mLock) {
+                // Now that permission groups have a special meaning, we ignore permission
+                // groups for legacy apps to prevent unexpected behavior. In particular,
+                // permissions for one app being granted to someone just because they happen
+                // to be in a group defined by another app (before this had no implications).
+                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
+                    p.group = mSettings.mPermissionGroups.get(p.info.group);
+                    // Warn for a permission in an unknown group.
+                    if (PackageManagerService.DEBUG_PERMISSIONS
+                            && p.info.group != null && p.group == null) {
+                        Slog.i(TAG, "Permission " + p.info.name + " from package "
+                                + p.info.packageName + " in an unknown group " + p.info.group);
+                    }
+                }
+
                 if (p.tree) {
                     final BasePermission bp = BasePermission.createOrUpdate(
                             mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
@@ -344,6 +366,48 @@
         }
     }
 
+    private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
+        final int N = pkg.permissionGroups.size();
+        StringBuilder r = null;
+        for (int i=0; i<N; i++) {
+            final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
+            final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
+            final String curPackageName = (cur == null) ? null : cur.info.packageName;
+            final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
+            if (cur == null || isPackageUpdate) {
+                mSettings.mPermissionGroups.put(pg.info.name, pg);
+                if (chatty && PackageManagerService.DEBUG_PACKAGE_SCANNING) {
+                    if (r == null) {
+                        r = new StringBuilder(256);
+                    } else {
+                        r.append(' ');
+                    }
+                    if (isPackageUpdate) {
+                        r.append("UPD:");
+                    }
+                    r.append(pg.info.name);
+                }
+            } else {
+                Slog.w(TAG, "Permission group " + pg.info.name + " from package "
+                        + pg.info.packageName + " ignored: original from "
+                        + cur.info.packageName);
+                if (chatty && PackageManagerService.DEBUG_PACKAGE_SCANNING) {
+                    if (r == null) {
+                        r = new StringBuilder(256);
+                    } else {
+                        r.append(' ');
+                    }
+                    r.append("DUP:");
+                    r.append(pg.info.name);
+                }
+            }
+        }
+        if (r != null && PackageManagerService.DEBUG_PACKAGE_SCANNING) {
+            Log.d(TAG, "  Permission Groups: " + r);
+        }
+
+    }
+
     private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
         synchronized (mLock) {
             int N = pkg.permissions.size();
@@ -1158,6 +1222,10 @@
             PermissionManagerService.this.addAllPermissions(pkg, chatty);
         }
         @Override
+        public void addAllPermissionGroups(Package pkg, boolean chatty) {
+            PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
+        }
+        @Override
         public void removeAllPermissions(Package pkg, boolean chatty) {
             PermissionManagerService.this.removeAllPermissions(pkg, chatty);
         }
@@ -1252,6 +1320,16 @@
                     permName, packageName, callingUid, userId);
         }
         @Override
+        public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
+                int callingUid) {
+            return PermissionManagerService.this.getPermissionGroupInfo(
+                    groupName, flags, callingUid);
+        }
+        @Override
+        public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
+            return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
+        }
+        @Override
         public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
                 int callingUid) {
             return PermissionManagerService.this.getPermissionInfo(