diff options
| author | 2023-02-22 18:46:08 +0000 | |
|---|---|---|
| committer | 2023-02-24 15:20:10 +0000 | |
| commit | 2903f3d591b56cc9a931ae0ebbf4853c5fc8a50b (patch) | |
| tree | dd668ea18430dc6affd2f28f904437db6e92640e | |
| parent | edb6afcae72509db63c0f02e7d78409b8196b9d6 (diff) | |
Update ASM clear task to only conisder present DisplayArea
If a task is not associated with a DisplayArea, that could throw a NPE.
We now exit early if that is the case.
Extrated the ASM logic to a separate method to make it easier to follow,
and minor updates to logging to match activity starts.
Bug: 270118065
Test: atest CtsAppTestCases
Change-Id: Iabd7c7c3ca503c354014e4fe73d449570cf4ceb5
(cherry picked from commit 6e9e524b568286fd4d3bb8f669834aef1aab9340)
Merged-In: Iabd7c7c3ca503c354014e4fe73d449570cf4ceb5
| -rw-r--r-- | services/core/java/com/android/server/wm/ActivityStarter.java | 15 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/ActivityTaskSupervisor.java | 175 |
2 files changed, 109 insertions, 81 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 48e5f79013d5..e99046041056 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -74,6 +74,7 @@ import static com.android.server.wm.ActivityTaskManagerService.ANIMATE; import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME; import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP; import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; +import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_COMPONENT; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_UID; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_DEFAULT; @@ -2017,7 +2018,8 @@ class ActivityStarter { if (ActivitySecurityModelFeatureFlags.shouldShowToast(mCallingUid)) { String toastText = ActivitySecurityModelFeatureFlags.DOC_LINK + (blockActivityStartAndFeatureEnabled ? " blocked " : " would block ") - + getApplicationLabel(launchedFromPackageName); + + getApplicationLabel(mService.mContext.getPackageManager(), + launchedFromPackageName); UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, toastText, Toast.LENGTH_LONG).show()); @@ -2039,17 +2041,6 @@ class ActivityStarter { return true; } - private CharSequence getApplicationLabel(String packageName) { - try { - PackageManager packageManager = mService.mContext.getPackageManager(); - ApplicationInfo launchedFromPackageInfo = packageManager.getApplicationInfo( - packageName, PackageManager.ApplicationInfoFlags.of(0)); - return packageManager.getApplicationLabel(launchedFromPackageInfo); - } catch (PackageManager.NameNotFoundException e) { - return packageName; - } - } - /** Only called when an activity launch may be blocked, which should happen very rarely */ private void logDebugInfoForActivitySecurity(String action, ActivityRecord r, Task targetTask, ActivityRecord targetTopActivity, boolean blockActivityStartAndFeatureEnabled, diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index abe71658ca23..65007002cf58 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1635,50 +1635,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Prevent recursion. return; } - boolean shouldBlockActivitySwitchIfFeatureEnabled = false; - boolean wouldBlockActivitySwitchIgnoringFlags = false; - // We may have already checked that the callingUid has additional clearTask privileges, and - // cleared the calling identify. If so, we infer we do not need further restrictions here. - // TODO(b/263368846) Move to live with the rest of the ASM logic. - if (callingUid != SYSTEM_UID) { - Pair<Boolean, Boolean> pair = doesTopActivityMatchingUidExistForAsm(task, - callingUid, - null); - shouldBlockActivitySwitchIfFeatureEnabled = !pair.first; - wouldBlockActivitySwitchIgnoringFlags = !pair.second; - if (wouldBlockActivitySwitchIgnoringFlags) { - ActivityRecord topActivity = task.getActivity(ar -> - !ar.finishing && !ar.isAlwaysOnTop()); - FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, - /* caller_uid */ - callingUid, - /* caller_activity_class_name */ - callerActivityClassName, - /* target_task_top_activity_uid */ - topActivity == null ? -1 : topActivity.getUid(), - /* target_task_top_activity_class_name */ - topActivity == null ? null : topActivity.info.name, - /* target_task_is_different */ - false, - /* target_activity_uid */ - -1, - /* target_activity_class_name */ - null, - /* target_intent_action */ - null, - /* target_intent_flags */ - 0, - /* action */ - FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__FINISH_TASK, - /* version */ - ActivitySecurityModelFeatureFlags.ASM_VERSION, - /* multi_window */ - false, - /* bal_code */ - -1 - ); - } - } task.mTransitionController.requestCloseTransitionIfNeeded(task); task.mInRemoveTask = true; try { @@ -1689,36 +1645,107 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { if (task.isPersistable) { mService.notifyTaskPersisterLocked(null, true); } - if (wouldBlockActivitySwitchIgnoringFlags) { - boolean restrictActivitySwitch = ActivitySecurityModelFeatureFlags - .shouldRestrictActivitySwitch(callingUid) - && shouldBlockActivitySwitchIfFeatureEnabled; - if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) { - UiThread.getHandler().post(() -> Toast.makeText(mService.mContext, - (restrictActivitySwitch - ? "Returning home due to " - : "Would return home due to ") - + ActivitySecurityModelFeatureFlags.DOC_LINK, - Toast.LENGTH_LONG).show()); - } - - // If the activity switch should be restricted, return home rather than the - // previously top task, to prevent users from being confused which app they're - // viewing - if (restrictActivitySwitch) { - Slog.w(TAG, "[ASM] Return to home as source uid: " + callingUid - + "is not on top of task t: " + task); - task.getTaskDisplayArea().moveHomeActivityToTop("taskRemoved"); - } else { - Slog.i(TAG, "[ASM] Would return to home as source uid: " + callingUid - + "is not on top of task t: " + task); - } - } + checkActivitySecurityForTaskClear(callingUid, task, callerActivityClassName); } finally { task.mInRemoveTask = false; } } + // TODO(b/263368846) Move to live with the rest of the ASM logic. + /** + * Returns home if the passed in callingUid is not top of the stack, rather than returning to + * previous task. + */ + private void checkActivitySecurityForTaskClear(int callingUid, Task task, + String callerActivityClassName) { + // We may have already checked that the callingUid has additional clearTask privileges, and + // cleared the calling identify. If so, we infer we do not need further restrictions here. + if (callingUid == SYSTEM_UID) { + return; + } + + TaskDisplayArea displayArea = task.getTaskDisplayArea(); + if (displayArea == null) { + // If there is no associated display area, we can not return home. + return; + } + + Pair<Boolean, Boolean> pair = doesTopActivityMatchingUidExistForAsm(task, callingUid, null); + boolean shouldBlockActivitySwitchIfFeatureEnabled = !pair.first; + boolean wouldBlockActivitySwitchIgnoringFlags = !pair.second; + + if (!wouldBlockActivitySwitchIgnoringFlags) { + return; + } + + ActivityRecord topActivity = task.getActivity(ar -> !ar.finishing && !ar.isAlwaysOnTop()); + FrameworkStatsLog.write(FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED, + /* caller_uid */ + callingUid, + /* caller_activity_class_name */ + callerActivityClassName, + /* target_task_top_activity_uid */ + topActivity == null ? -1 : topActivity.getUid(), + /* target_task_top_activity_class_name */ + topActivity == null ? null : topActivity.info.name, + /* target_task_is_different */ + false, + /* target_activity_uid */ + -1, + /* target_activity_class_name */ + null, + /* target_intent_action */ + null, + /* target_intent_flags */ + 0, + /* action */ + FrameworkStatsLog.ACTIVITY_ACTION_BLOCKED__ACTION__FINISH_TASK, + /* version */ + ActivitySecurityModelFeatureFlags.ASM_VERSION, + /* multi_window */ + false, + /* bal_code */ + -1 + ); + + boolean restrictActivitySwitch = ActivitySecurityModelFeatureFlags + .shouldRestrictActivitySwitch(callingUid) + && shouldBlockActivitySwitchIfFeatureEnabled; + + PackageManager pm = mService.mContext.getPackageManager(); + String callingPackage = pm.getNameForUid(callingUid); + final CharSequence callingLabel; + if (callingPackage == null) { + callingPackage = String.valueOf(callingUid); + callingLabel = callingPackage; + } else { + callingLabel = getApplicationLabel(pm, callingPackage); + } + + if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) { + Toast toast = Toast.makeText(mService.mContext, + (ActivitySecurityModelFeatureFlags.DOC_LINK + + (restrictActivitySwitch + ? "returned home due to " + : "would return home due to ") + + callingLabel), + Toast.LENGTH_LONG); + UiThread.getHandler().post(toast::show); + } + + // If the activity switch should be restricted, return home rather than the + // previously top task, to prevent users from being confused which app they're + // viewing + if (restrictActivitySwitch) { + Slog.w(TAG, "[ASM] Return to home as source: " + callingPackage + + " is not on top of task t: " + task); + displayArea.moveHomeActivityToTop("taskRemoved"); + } else { + Slog.i(TAG, "[ASM] Would return to home as source: " + callingPackage + + " is not on top of task t: " + task); + } + } + /** * For the purpose of ASM, ‘Top UID” for a task is defined as an activity UID * 1. Which is top of the stack in z-order @@ -1779,6 +1806,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { return topActivity.allowCrossUidActivitySwitchFromBelow(uid); } + static CharSequence getApplicationLabel(PackageManager pm, String packageName) { + try { + ApplicationInfo launchedFromPackageInfo = pm.getApplicationInfo( + packageName, PackageManager.ApplicationInfoFlags.of(0)); + return pm.getApplicationLabel(launchedFromPackageInfo); + } catch (PackageManager.NameNotFoundException e) { + return packageName; + } + } + void cleanUpRemovedTaskLocked(Task task, boolean killProcess, boolean removeFromRecents) { if (removeFromRecents) { mRecentTasks.remove(task); |