Introducing removable and non-removable ForwardingIntentFilters.

clearForwardingIntentFilters removes only non-removable IntentFilters.
The ForwardingIntentFilters set by the profile owner are always removable.

Change-Id: If950ccd7e69261b86360ea647fdb501c92f5440b
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index cf9a296..03eb50f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -247,7 +247,8 @@
 
     void clearPackagePersistentPreferredActivities(String packageName, int userId);
 
-    void addForwardingIntentFilter(in IntentFilter filter, int userIdOrig, int userIdDest);
+    void addForwardingIntentFilter(in IntentFilter filter, boolean removable, int userIdOrig,
+            int userIdDest);
 
     void clearForwardingIntentFilters(int userIdOrig);
 
diff --git a/services/core/java/com/android/server/pm/ForwardingIntentFilter.java b/services/core/java/com/android/server/pm/ForwardingIntentFilter.java
index aba796b..85bde98 100644
--- a/services/core/java/com/android/server/pm/ForwardingIntentFilter.java
+++ b/services/core/java/com/android/server/pm/ForwardingIntentFilter.java
@@ -32,22 +32,29 @@
  */
 class ForwardingIntentFilter extends IntentFilter {
     private static final String ATTR_USER_ID_DEST = "userIdDest";
+    private static final String ATTR_REMOVABLE = "removable";
     private static final String ATTR_FILTER = "filter";
 
     private static final String TAG = "ForwardingIntentFilter";
 
     // If the intent matches the IntentFilter, then it can be forwarded to this userId.
     final int mUserIdDest;
+    boolean mRemovable;
 
-    ForwardingIntentFilter(IntentFilter filter, int userIdDest) {
+    ForwardingIntentFilter(IntentFilter filter, boolean removable, int userIdDest) {
         super(filter);
         mUserIdDest = userIdDest;
+        mRemovable = removable;
     }
 
     public int getUserIdDest() {
         return mUserIdDest;
     }
 
+    public boolean isRemovable() {
+        return mRemovable;
+    }
+
     ForwardingIntentFilter(XmlPullParser parser) throws XmlPullParserException, IOException {
         String userIdDestString = parser.getAttributeValue(null, ATTR_USER_ID_DEST);
         if (userIdDestString == null) {
@@ -58,6 +65,10 @@
         } else {
             mUserIdDest = Integer.parseInt(userIdDestString);
         }
+        String removableString = parser.getAttributeValue(null, ATTR_REMOVABLE);
+        if (removableString != null) {
+            mRemovable = Boolean.parseBoolean(removableString);
+        }
         int outerDepth = parser.getDepth();
         String tagName = parser.getName();
         int type;
@@ -89,6 +100,7 @@
 
     public void writeToXml(XmlSerializer serializer) throws IOException {
         serializer.attribute(null, ATTR_USER_ID_DEST, Integer.toString(mUserIdDest));
+        serializer.attribute(null, ATTR_REMOVABLE, Boolean.toString(mRemovable));
         serializer.startTag(null, ATTR_FILTER);
             super.writeToXml(serializer);
         serializer.endTag(null, ATTR_FILTER);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a133d42..b6812ea0 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11112,13 +11112,9 @@
         }
     }
 
-    /*
-     * For filters that are added with this method:
-     * if an intent for the user whose id is userIdOrig matches the filter, then this intent can
-     * also be resolved in the user whose id is userIdDest.
-     */
     @Override
-    public void addForwardingIntentFilter(IntentFilter filter, int userIdOrig, int userIdDest) {
+    public void addForwardingIntentFilter(IntentFilter filter, boolean removable, int userIdOrig,
+            int userIdDest) {
         int callingUid = Binder.getCallingUid();
         if (callingUid != Process.SYSTEM_UID) {
             throw new SecurityException(
@@ -11130,7 +11126,7 @@
         }
         synchronized (mPackages) {
             mSettings.editForwardingIntentResolverLPw(userIdOrig).addFilter(
-                    new ForwardingIntentFilter(filter, userIdDest));
+                    new ForwardingIntentFilter(filter, removable, userIdDest));
             mSettings.writePackageRestrictionsLPr(userIdOrig);
         }
     }
@@ -11147,7 +11143,7 @@
             HashSet<ForwardingIntentFilter> set =
                     new HashSet<ForwardingIntentFilter>(fir.filterSet());
             for (ForwardingIntentFilter fif : set) {
-                fir.removeFilter(fif);
+                if (fif.isRemovable()) fir.removeFilter(fif);
             }
             mSettings.writePackageRestrictionsLPr(userIdOrig);
         }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d0a6db1..ae2dcf9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3094,10 +3094,12 @@
             long id = Binder.clearCallingIdentity();
             try {
                 if ((flags & DevicePolicyManager.FLAG_TO_PRIMARY_USER) != 0) {
-                    pm.addForwardingIntentFilter(filter, callingUserId, UserHandle.USER_OWNER);
+                    pm.addForwardingIntentFilter(filter, true /*removable*/, callingUserId,
+                            UserHandle.USER_OWNER);
                 }
                 if ((flags & DevicePolicyManager.FLAG_TO_MANAGED_PROFILE) != 0) {
-                    pm.addForwardingIntentFilter(filter, UserHandle.USER_OWNER, callingUserId);
+                    pm.addForwardingIntentFilter(filter, true /*removable*/, UserHandle.USER_OWNER,
+                            callingUserId);
                 }
             } catch (RemoteException re) {
                 // Shouldn't happen