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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user