Remove Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT for apps targeting Q.

This intent supported starting with startActivity() so we may not be
able to get caller information in the started activity, hence remove
it for apps targeting Q and later here.

Bug: 124452117
Bug: 131204827
Test: presubmit
Change-Id: I261d6b6ccd42e148789ed03f7b3e8268b2f62480
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
new file mode 100644
index 0000000..ea8616c
--- /dev/null
+++ b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.policy;
+
+import android.annotation.NonNull;
+import android.content.Intent;
+
+/**
+ * Internal calls into {@link PermissionPolicyService}.
+ */
+public abstract class PermissionPolicyInternal {
+
+    /**
+     * Check whether an activity should be started.
+     *
+     * @param intent the {@link Intent} for the activity start
+     * @param callingUid the calling uid starting the activity
+     * @param callingPackage the calling package starting the activity
+     *
+     * @return whether the activity should be started
+     */
+    public abstract boolean checkStartActivity(@NonNull Intent intent, int callingUid,
+            @NonNull String callingPackage);
+}
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index a280d83..7438ddf 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -25,6 +25,8 @@
 import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -37,6 +39,7 @@
 import android.os.UserHandle;
 import android.permission.PermissionControllerManager;
 import android.permission.PermissionManagerInternal;
+import android.provider.Telephony;
 import android.util.Slog;
 import android.util.SparseIntArray;
 
@@ -59,6 +62,8 @@
 
     public PermissionPolicyService(@NonNull Context context) {
         super(context);
+
+        LocalServices.addService(PermissionPolicyInternal.class, new Internal());
     }
 
     @Override
@@ -468,4 +473,46 @@
             }
         }
     }
+
+    private class Internal extends PermissionPolicyInternal {
+
+        @Override
+        public boolean checkStartActivity(@NonNull Intent intent, int callingUid,
+                @NonNull String callingPackage) {
+            if (isActionRemovedForCallingPackage(intent.getAction(), callingPackage)) {
+                Slog.w(LOG_TAG, "Action Removed: starting " + intent.toString() + " from "
+                        + callingPackage + " (uid=" + callingUid + ")");
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Check if the intent action is removed for the calling package (often based on target SDK
+         * version). If the action is removed, we'll silently cancel the activity launch.
+         */
+        private boolean isActionRemovedForCallingPackage(@Nullable String action,
+                @NonNull String callingPackage) {
+            if (action == null) {
+                return false;
+            }
+            switch (action) {
+                case Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT: {
+                    ApplicationInfo applicationInfo;
+                    try {
+                        applicationInfo = getContext().getPackageManager().getApplicationInfo(
+                                callingPackage, 0);
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Slog.i(LOG_TAG, "Cannot find application info for " + callingPackage);
+                        return false;
+                    }
+                    // Applications targeting Q should use RoleManager.createRequestRoleIntent()
+                    // instead.
+                    return applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q;
+                }
+                default:
+                    return false;
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 4ef8753..141ca33 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -759,6 +759,8 @@
                 inTask != null, callerApp, resultRecord, resultStack);
         abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                 callingPid, resolvedType, aInfo.applicationInfo);
+        abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
+                callingPackage);
 
         boolean abortBackgroundStart = false;
         if (!abort) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 7bc9600..8d613af 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -108,12 +108,10 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_ACTIVITY_ID;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
 import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
-import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_TASK_ID;
 import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
 import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
 import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
@@ -216,7 +214,6 @@
 import android.util.ArrayMap;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
@@ -266,6 +263,7 @@
 import com.android.server.appop.AppOpsService;
 import com.android.server.firewall.IntentFirewall;
 import com.android.server.pm.UserManagerService;
+import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.vr.VrManagerInternal;
 
@@ -348,6 +346,7 @@
     ActivityManagerInternal mAmInternal;
     UriGrantsManagerInternal mUgmInternal;
     private PackageManagerInternal mPmInternal;
+    private PermissionPolicyInternal mPermissionPolicyInternal;
     @VisibleForTesting
     final ActivityTaskManagerInternal mInternal;
     PowerManagerInternal mPowerManagerInternal;
@@ -5786,6 +5785,13 @@
         return mPmInternal;
     }
 
+    PermissionPolicyInternal getPermissionPolicyInternal() {
+        if (mPermissionPolicyInternal == null) {
+            mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
+        }
+        return mPermissionPolicyInternal;
+    }
+
     AppWarnings getAppWarningsLocked() {
         return mAppWarnings;
     }