Reset cross profile intent filters for call/sms

For personal managed subscriptions policy, reset cross profile call/sms
intent filters to the defaults.

Bug: 258851487
Test: btest CtsDevicePolicySimTestCases
Change-Id: I101710ba18cafed83e653901f0d852fb9528314d
diff --git a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java
index 9683469..dc5915d 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java
@@ -37,7 +37,7 @@
             Direction.TO_PROFILE
     })
     @Retention(RetentionPolicy.SOURCE)
-    @interface Direction {
+    public @interface Direction {
         int TO_PARENT = 0;
         int TO_PROFILE = 1;
     }
diff --git a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
index 9eb73aa..48ee64f 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
@@ -25,6 +25,7 @@
 import android.provider.AlarmClock;
 import android.provider.MediaStore;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -88,6 +89,23 @@
                     .addDataType("vnd.android.cursor.item/calls")
                     .build();
 
+    /** Dial intent with mime type exclusively handled by managed profile. */
+    private static final DefaultCrossProfileIntentFilter DIAL_MIME_MANAGED_PROFILE =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    SKIP_CURRENT_PROFILE,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(Intent.ACTION_DIAL)
+                    .addAction(Intent.ACTION_VIEW)
+                    .addCategory(Intent.CATEGORY_DEFAULT)
+                    .addCategory(Intent.CATEGORY_BROWSABLE)
+                    .addDataType("vnd.android.cursor.item/phone")
+                    .addDataType("vnd.android.cursor.item/phone_v2")
+                    .addDataType("vnd.android.cursor.item/person")
+                    .addDataType("vnd.android.cursor.dir/calls")
+                    .addDataType("vnd.android.cursor.item/calls")
+                    .build();
+
     /** Dial intent with data scheme can be handled by either managed profile or its parent user. */
     private static final DefaultCrossProfileIntentFilter DIAL_DATA =
             new DefaultCrossProfileIntentFilter.Builder(
@@ -103,6 +121,21 @@
                     .addDataScheme("voicemail")
                     .build();
 
+    /** Dial intent with data scheme exclusively handled by managed profile. */
+    private static final DefaultCrossProfileIntentFilter DIAL_DATA_MANAGED_PROFILE =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    SKIP_CURRENT_PROFILE,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(Intent.ACTION_DIAL)
+                    .addAction(Intent.ACTION_VIEW)
+                    .addCategory(Intent.CATEGORY_DEFAULT)
+                    .addCategory(Intent.CATEGORY_BROWSABLE)
+                    .addDataScheme("tel")
+                    .addDataScheme("sip")
+                    .addDataScheme("voicemail")
+                    .build();
+
     /**
      * Dial intent with no data scheme or type can be handled by either managed profile or its
      * parent user.
@@ -117,6 +150,19 @@
                     .addCategory(Intent.CATEGORY_BROWSABLE)
                     .build();
 
+    /**
+     * Dial intent with no data scheme or type exclusively handled by managed profile.
+     */
+    private static final DefaultCrossProfileIntentFilter DIAL_RAW_MANAGED_PROFILE =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    SKIP_CURRENT_PROFILE,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(Intent.ACTION_DIAL)
+                    .addCategory(Intent.CATEGORY_DEFAULT)
+                    .addCategory(Intent.CATEGORY_BROWSABLE)
+                    .build();
+
     /** Pressing the call button can be handled by either managed profile or its parent user. */
     private static final DefaultCrossProfileIntentFilter CALL_BUTTON =
             new DefaultCrossProfileIntentFilter.Builder(
@@ -143,6 +189,22 @@
                     .addDataScheme("mmsto")
                     .build();
 
+    /** SMS and MMS intent exclusively handled by the managed profile. */
+    private static final DefaultCrossProfileIntentFilter SMS_MMS_MANAGED_PROFILE =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    SKIP_CURRENT_PROFILE,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(Intent.ACTION_VIEW)
+                    .addAction(Intent.ACTION_SENDTO)
+                    .addCategory(Intent.CATEGORY_DEFAULT)
+                    .addCategory(Intent.CATEGORY_BROWSABLE)
+                    .addDataScheme("sms")
+                    .addDataScheme("smsto")
+                    .addDataScheme("mms")
+                    .addDataScheme("mmsto")
+                    .build();
+
     /** Mobile network settings is always shown in the primary user. */
     private static final DefaultCrossProfileIntentFilter
             MOBILE_NETWORK_SETTINGS =
@@ -297,14 +359,12 @@
                     .build();
 
     public static List<DefaultCrossProfileIntentFilter> getDefaultManagedProfileFilters() {
-        return Arrays.asList(
+        List<DefaultCrossProfileIntentFilter> filters =
+                new ArrayList<DefaultCrossProfileIntentFilter>();
+        filters.addAll(Arrays.asList(
                 EMERGENCY_CALL_MIME,
                 EMERGENCY_CALL_DATA,
-                DIAL_MIME,
-                DIAL_DATA,
-                DIAL_RAW,
                 CALL_BUTTON,
-                SMS_MMS,
                 SET_ALARM,
                 MEDIA_CAPTURE,
                 RECOGNIZE_SPEECH,
@@ -317,11 +377,13 @@
                 USB_DEVICE_ATTACHED,
                 ACTION_SEND,
                 HOME,
-                MOBILE_NETWORK_SETTINGS);
+                MOBILE_NETWORK_SETTINGS));
+        filters.addAll(getDefaultCrossProfileTelephonyIntentFilters(false));
+        return filters;
     }
 
-    /** Call intent with tel scheme */
-    private static final DefaultCrossProfileIntentFilter CALL =
+    /** Call intent with tel scheme exclusively handled my managed profile. */
+    private static final DefaultCrossProfileIntentFilter CALL_MANAGED_PROFILE =
             new DefaultCrossProfileIntentFilter.Builder(
                     DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
                     SKIP_CURRENT_PROFILE,
@@ -334,13 +396,22 @@
     /**
      * Returns default telephony related intent filters for managed profile.
      */
-    public static List<DefaultCrossProfileIntentFilter> getDefaultManagedProfileTelephonyFilters() {
-        return Arrays.asList(
-                DIAL_DATA,
-                DIAL_MIME,
-                DIAL_RAW,
-                CALL,
-                SMS_MMS);
+    public static List<DefaultCrossProfileIntentFilter>
+            getDefaultCrossProfileTelephonyIntentFilters(boolean telephonyOnlyInManagedProfile) {
+        if (telephonyOnlyInManagedProfile) {
+            return Arrays.asList(
+                    DIAL_DATA_MANAGED_PROFILE,
+                    DIAL_MIME_MANAGED_PROFILE,
+                    DIAL_RAW_MANAGED_PROFILE,
+                    CALL_MANAGED_PROFILE,
+                    SMS_MMS_MANAGED_PROFILE);
+        } else {
+            return Arrays.asList(
+                    DIAL_DATA,
+                    DIAL_MIME,
+                    DIAL_RAW,
+                    SMS_MMS);
+        }
     }
 
     /**
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ed0bcc3..3f6c7fa 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7711,30 +7711,72 @@
     private void updateTelephonyCrossProfileIntentFilters(int parentUserId, int profileUserId,
             boolean enableWorkTelephony) {
         try {
-            String packageName = mContext.getOpPackageName();
-            if (enableWorkTelephony) {
-                // Reset call/sms cross profile intent filters to be handled by managed profile.
-                for (DefaultCrossProfileIntentFilter filter :
-                        DefaultCrossProfileIntentFiltersUtils
-                                .getDefaultManagedProfileTelephonyFilters()) {
-                    IntentFilter intentFilter = filter.filter.getIntentFilter();
-                    if (!mIPackageManager.removeCrossProfileIntentFilter(intentFilter, packageName,
-                            profileUserId, parentUserId, filter.flags)) {
-                        Slogf.w(LOG_TAG,
-                                "Failed to remove cross-profile intent filter: " + intentFilter);
-                    }
-
-                    mIPackageManager.addCrossProfileIntentFilter(intentFilter, packageName,
-                            parentUserId, profileUserId, PackageManager.SKIP_CURRENT_PROFILE);
+            // This should only occur when managed profile is being removed.
+            if (!enableWorkTelephony && profileUserId == UserHandle.USER_NULL) {
+                mIPackageManager.clearCrossProfileIntentFilters(parentUserId,
+                        mContext.getPackageName());
+                return;
+            }
+            for (DefaultCrossProfileIntentFilter filter :
+                    DefaultCrossProfileIntentFiltersUtils
+                            .getDefaultCrossProfileTelephonyIntentFilters(!enableWorkTelephony)) {
+                if (removeCrossProfileIntentFilter(filter, parentUserId, profileUserId)) {
+                    Slogf.w(LOG_TAG,
+                            "Failed to remove cross-profile intent filter: "
+                                    + filter.filter.getIntentFilter() + ", enableWorkTelephony: "
+                                    + enableWorkTelephony);
                 }
-            } else {
-                mIPackageManager.clearCrossProfileIntentFilters(parentUserId, packageName);
+            }
+            for (DefaultCrossProfileIntentFilter filter :
+                    DefaultCrossProfileIntentFiltersUtils
+                            .getDefaultCrossProfileTelephonyIntentFilters(enableWorkTelephony)) {
+                addCrossProfileIntentFilter(filter, parentUserId, profileUserId);
             }
         } catch (RemoteException re) {
             Slogf.wtf(LOG_TAG, "Error updating telephony cross profile intent filters", re);
         }
     }
 
+    void addCrossProfileIntentFilter(DefaultCrossProfileIntentFilter filter, int parentUserId,
+            int profileUserId)
+            throws RemoteException {
+        if (filter.direction == DefaultCrossProfileIntentFilter.Direction.TO_PROFILE) {
+            mIPackageManager.addCrossProfileIntentFilter(
+                    filter.filter.getIntentFilter(),
+                    mContext.getOpPackageName(),
+                    parentUserId,
+                    profileUserId,
+                    filter.flags);
+        } else {
+            mIPackageManager.addCrossProfileIntentFilter(
+                    filter.filter.getIntentFilter(),
+                    mContext.getOpPackageName(),
+                    profileUserId,
+                    parentUserId,
+                    filter.flags);
+        }
+    }
+
+    boolean removeCrossProfileIntentFilter(DefaultCrossProfileIntentFilter filter, int parentUserId,
+            int profileUserId)
+            throws RemoteException {
+        if (filter.direction == DefaultCrossProfileIntentFilter.Direction.TO_PROFILE) {
+            return mIPackageManager.removeCrossProfileIntentFilter(
+                    filter.filter.getIntentFilter(),
+                    mContext.getOpPackageName(),
+                    parentUserId,
+                    profileUserId,
+                    filter.flags);
+        } else {
+            return mIPackageManager.removeCrossProfileIntentFilter(
+                    filter.filter.getIntentFilter(),
+                    mContext.getOpPackageName(),
+                    profileUserId,
+                    parentUserId,
+                    filter.flags);
+        }
+    }
+
     /**
      * @param factoryReset null: legacy behaviour, false: attempt to remove user, true: attempt to
      *                     factory reset
@@ -23356,14 +23398,16 @@
         applyManagedSubscriptionsPolicyIfRequired();
 
         int policyType = getManagedSubscriptionsPolicy().getPolicyType();
-        if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
-            final long id = mInjector.binderClearCallingIdentity();
-            try {
+        final long id = mInjector.binderClearCallingIdentity();
+        try {
+            if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
                 installOemDefaultDialerAndSmsApp(caller.getUserId());
                 updateTelephonyCrossProfileIntentFilters(parentUserId, caller.getUserId(), true);
-            } finally {
-                mInjector.binderRestoreCallingIdentity(id);
+            } else if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_PERSONAL_SUBSCRIPTIONS) {
+                updateTelephonyCrossProfileIntentFilters(parentUserId, caller.getUserId(), false);
             }
+        } finally {
+            mInjector.binderRestoreCallingIdentity(id);
         }
     }