Add systemOnly attribute for role.

Roles such as the emergency role requires a system app, so add an
attribute for it. Also made the emergency role system-only.

Bug: 110557011
Bug: 123293861
Test: manual
Change-Id: I4d4951b363317b01a11e646808f2f0cd695b9644
diff --git a/PermissionController/res/xml/roles.xml b/PermissionController/res/xml/roles.xml
index 22ea3c1..9b9577f 100644
--- a/PermissionController/res/xml/roles.xml
+++ b/PermissionController/res/xml/roles.xml
@@ -265,7 +265,11 @@
       ~ @see com.android.settings.applications.defaultapps.DefaultEmergencyPicker
       ~ @see com.android.phone.EmergencyAssistanceHelper
       -->
-    <role name="android.app.role.EMERGENCY" exclusive="true" label="@string/role_label_emergency">
+    <role
+        name="android.app.role.EMERGENCY"
+        exclusive="true"
+        label="@string/role_label_emergency"
+        systemOnly="true">
         <required-components>
             <activity>
                 <intent-filter>
diff --git a/PermissionController/src/com/android/packageinstaller/role/model/Role.java b/PermissionController/src/com/android/packageinstaller/role/model/Role.java
index ff66e99..24b1e36 100644
--- a/PermissionController/src/com/android/packageinstaller/role/model/Role.java
+++ b/PermissionController/src/com/android/packageinstaller/role/model/Role.java
@@ -95,6 +95,11 @@
     private final boolean mShowNone;
 
     /**
+     * Whether this role only accepts system apps as its holders.
+     */
+    private final boolean mSystemOnly;
+
+    /**
      * The required components for an application to qualify for this role.
      */
     @NonNull
@@ -119,7 +124,7 @@
     private final List<PreferredActivity> mPreferredActivities;
 
     public Role(@NonNull String name, @Nullable RoleBehavior behavior, boolean exclusive,
-            @StringRes int labelResource, boolean showNone,
+            @StringRes int labelResource, boolean showNone, boolean systemOnly,
             @NonNull List<RequiredComponent> requiredComponents, @NonNull List<String> permissions,
             @NonNull List<AppOp> appOps, @NonNull List<PreferredActivity> preferredActivities) {
         mName = name;
@@ -127,6 +132,7 @@
         mExclusive = exclusive;
         mLabelResource = labelResource;
         mShowNone = showNone;
+        mSystemOnly = systemOnly;
         mRequiredComponents = requiredComponents;
         mPermissions = permissions;
         mAppOps = appOps;
@@ -390,6 +396,10 @@
             return false;
         }
 
+        if (mSystemOnly && (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+            return false;
+        }
+
         // TODO: STOPSHIP: Check for disabled packages?
 
         // TODO: STOPSHIP: Add and check PackageManager.getSharedLibraryInfo().
@@ -553,6 +563,8 @@
                 + ", mBehavior=" + mBehavior
                 + ", mExclusive=" + mExclusive
                 + ", mLabelResource=" + mLabelResource
+                + ", mShowNone=" + mShowNone
+                + ", mSystemOnly=" + mSystemOnly
                 + ", mRequiredComponents=" + mRequiredComponents
                 + ", mPermissions=" + mPermissions
                 + ", mAppOps=" + mAppOps
@@ -568,20 +580,22 @@
         if (object == null || getClass() != object.getClass()) {
             return false;
         }
-        Role role = (Role) object;
-        return mExclusive == role.mExclusive
-                && mLabelResource == role.mLabelResource
-                && Objects.equals(mName, role.mName)
-                && Objects.equals(mBehavior, role.mBehavior)
-                && Objects.equals(mRequiredComponents, role.mRequiredComponents)
-                && Objects.equals(mPermissions, role.mPermissions)
-                && Objects.equals(mAppOps, role.mAppOps)
-                && Objects.equals(mPreferredActivities, role.mPreferredActivities);
+        Role that = (Role) object;
+        return mExclusive == that.mExclusive
+                && mLabelResource == that.mLabelResource
+                && mShowNone == that.mShowNone
+                && mSystemOnly == that.mSystemOnly
+                && mName.equals(that.mName)
+                && Objects.equals(mBehavior, that.mBehavior)
+                && mRequiredComponents.equals(that.mRequiredComponents)
+                && mPermissions.equals(that.mPermissions)
+                && mAppOps.equals(that.mAppOps)
+                && mPreferredActivities.equals(that.mPreferredActivities);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mName, mBehavior, mExclusive, mLabelResource,
+        return Objects.hash(mName, mBehavior, mExclusive, mLabelResource, mShowNone, mSystemOnly,
                 mRequiredComponents, mPermissions, mAppOps, mPreferredActivities);
     }
 }
diff --git a/PermissionController/src/com/android/packageinstaller/role/model/Roles.java b/PermissionController/src/com/android/packageinstaller/role/model/Roles.java
index 18e404c..61245c3 100644
--- a/PermissionController/src/com/android/packageinstaller/role/model/Roles.java
+++ b/PermissionController/src/com/android/packageinstaller/role/model/Roles.java
@@ -75,6 +75,7 @@
     private static final String ATTRIBUTE_EXCLUSIVE = "exclusive";
     private static final String ATTRIBUTE_LABEL = "label";
     private static final String ATTRIBUTE_SHOW_NONE = "showNone";
+    private static final String ATTRIBUTE_SYSTEM_ONLY = "systemOnly";
     private static final String ATTRIBUTE_PERMISSION = "permission";
     private static final String ATTRIBUTE_SCHEME = "scheme";
     private static final String ATTRIBUTE_MIME_TYPE = "mimeType";
@@ -324,6 +325,8 @@
             return null;
         }
 
+        boolean systemOnly = getAttributeBooleanValue(parser, ATTRIBUTE_SYSTEM_ONLY, false);
+
         List<RequiredComponent> requiredComponents = null;
         List<String> permissions = null;
         List<AppOp> appOps = null;
@@ -390,8 +393,8 @@
         if (preferredActivities == null) {
             preferredActivities = Collections.emptyList();
         }
-        return new Role(name, behavior, exclusive, labelResource, showNone, requiredComponents,
-                permissions, appOps, preferredActivities);
+        return new Role(name, behavior, exclusive, labelResource, showNone, systemOnly,
+                requiredComponents, permissions, appOps, preferredActivities);
     }
 
     @NonNull