Loading services/core/java/com/android/server/wm/ActivityStarter.java +83 −19 Original line number Original line Diff line number Diff line Loading @@ -160,6 +160,10 @@ class ActivityStarter { private int mCallingUid; private int mCallingUid; private ActivityOptions mOptions; private ActivityOptions mOptions; // If it is true, background activity can only be started in an existing task that contains // an activity with same uid. private boolean mRestrictedBgActivity; private int mLaunchMode; private int mLaunchMode; private boolean mLaunchTaskBehind; private boolean mLaunchTaskBehind; private int mLaunchFlags; private int mLaunchFlags; Loading Loading @@ -455,6 +459,7 @@ class ActivityStarter { mIntent = starter.mIntent; mIntent = starter.mIntent; mCallingUid = starter.mCallingUid; mCallingUid = starter.mCallingUid; mOptions = starter.mOptions; mOptions = starter.mOptions; mRestrictedBgActivity = starter.mRestrictedBgActivity; mLaunchTaskBehind = starter.mLaunchTaskBehind; mLaunchTaskBehind = starter.mLaunchTaskBehind; mLaunchFlags = starter.mLaunchFlags; mLaunchFlags = starter.mLaunchFlags; Loading Loading @@ -551,7 +556,8 @@ class ActivityStarter { mLastStartActivityTimeMs = System.currentTimeMillis(); mLastStartActivityTimeMs = System.currentTimeMillis(); mLastStartActivityRecord[0] = r; mLastStartActivityRecord[0] = r; mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor, mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, mLastStartActivityRecord); startFlags, doResume, options, inTask, mLastStartActivityRecord, false /* restrictedBgActivity */); mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult, mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult, mLastStartActivityRecord[0]); mLastStartActivityRecord[0]); return mLastStartActivityResult; return mLastStartActivityResult; Loading Loading @@ -760,22 +766,17 @@ class ActivityStarter { abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo); callingPid, resolvedType, aInfo.applicationInfo); boolean abortBackgroundStart = false; boolean restrictedBgActivity = false; if (!abort) { if (!abort) { try { try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shouldAbortBackgroundActivityStart"); "shouldAbortBackgroundActivityStart"); abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, originatingPendingIntent, allowBackgroundActivityStart, intent); originatingPendingIntent, allowBackgroundActivityStart, intent); } finally { } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } abort |= (abortBackgroundStart && !mService.isBackgroundActivityStartsEnabled()); // TODO: remove this toast after feature development is done if (abortBackgroundStart) { showBackgroundActivityBlockedToast(abort, callingPackage); } } } // Merge the two options bundles, while realCallerOptions takes precedence. // Merge the two options bundles, while realCallerOptions takes precedence. Loading Loading @@ -918,8 +919,10 @@ class ActivityStarter { || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) { || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, realCallingPid, realCallingUid, "Activity start")) { realCallingPid, realCallingUid, "Activity start")) { if (!restrictedBgActivity) { mController.addPendingActivityLaunch(new PendingActivityLaunch(r, mController.addPendingActivityLaunch(new PendingActivityLaunch(r, sourceRecord, startFlags, stack, callerApp)); sourceRecord, startFlags, stack, callerApp)); } ActivityOptions.abort(checkedOptions); ActivityOptions.abort(checkedOptions); return ActivityManager.START_SWITCHES_CANCELED; return ActivityManager.START_SWITCHES_CANCELED; } } Loading @@ -929,7 +932,7 @@ class ActivityStarter { mController.doPendingActivityLaunches(false); mController.doPendingActivityLaunches(false); final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity); mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]); mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]); return res; return res; } } Loading Loading @@ -1401,13 +1404,13 @@ class ActivityStarter { private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ActivityRecord[] outActivity, boolean restrictedBgActivity) { int result = START_CANCELED; int result = START_CANCELED; final ActivityStack startedActivityStack; final ActivityStack startedActivityStack; try { try { mService.mWindowManager.deferSurfaceLayout(); mService.mWindowManager.deferSurfaceLayout(); result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); startFlags, doResume, options, inTask, outActivity, restrictedBgActivity); } finally { } finally { final ActivityStack currentStack = r.getActivityStack(); final ActivityStack currentStack = r.getActivityStack(); startedActivityStack = currentStack != null ? currentStack : mTargetStack; startedActivityStack = currentStack != null ? currentStack : mTargetStack; Loading Loading @@ -1443,14 +1446,40 @@ class ActivityStarter { return result; return result; } } /** * Return true if background activity is really aborted. * * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere. */ private boolean handleBackgroundActivityAbort(ActivityRecord r) { // TODO(b/131747138): Remove toast and refactor related code in Q release. boolean abort = !mService.isBackgroundActivityStartsEnabled(); showBackgroundActivityBlockedToast(abort, r.launchedFromPackage); if (!abort) { return false; } ActivityRecord resultRecord = r.resultTo; String resultWho = r.resultWho; int requestCode = r.requestCode; if (resultRecord != null) { ActivityStack resultStack = resultRecord.getActivityStack(); resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null); } // We pretend to the caller that it was really started to make it backward compatible, but // they will just get a cancel result. ActivityOptions.abort(r.pendingOptions); return true; } // Note: This method should only be called from {@link startActivity}. // Note: This method should only be called from {@link startActivity}. private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ActivityRecord[] outActivity, boolean restrictedBgActivity) { setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor); voiceInteractor, restrictedBgActivity); final int preferredWindowingMode = mLaunchParams.mWindowingMode; final int preferredWindowingMode = mLaunchParams.mWindowingMode; computeLaunchingTaskFlags(); computeLaunchingTaskFlags(); Loading Loading @@ -1658,7 +1687,7 @@ class ActivityStarter { } else { } else { // This not being started from an existing activity, and not part of a new task... // This not being started from an existing activity, and not part of a new task... // just put it in the top task, though these days this case should never happen. // just put it in the top task, though these days this case should never happen. setTaskToCurrentTopOrCreateNewTask(); result = setTaskToCurrentTopOrCreateNewTask(); } } if (result != START_SUCCESS) { if (result != START_SUCCESS) { return result; return result; Loading Loading @@ -1731,6 +1760,7 @@ class ActivityStarter { mIntent = null; mIntent = null; mCallingUid = -1; mCallingUid = -1; mOptions = null; mOptions = null; mRestrictedBgActivity = false; mLaunchTaskBehind = false; mLaunchTaskBehind = false; mLaunchFlags = 0; mLaunchFlags = 0; Loading Loading @@ -1770,7 +1800,8 @@ class ActivityStarter { private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask, private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask, boolean doResume, int startFlags, ActivityRecord sourceRecord, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, boolean restrictedBgActivity) { reset(false /* clearRequest */); reset(false /* clearRequest */); mStartActivity = r; mStartActivity = r; Loading @@ -1780,6 +1811,7 @@ class ActivityStarter { mSourceRecord = sourceRecord; mSourceRecord = sourceRecord; mVoiceSession = voiceSession; mVoiceSession = voiceSession; mVoiceInteractor = voiceInteractor; mVoiceInteractor = voiceInteractor; mRestrictedBgActivity = restrictedBgActivity; mLaunchParams.reset(); mLaunchParams.reset(); Loading Loading @@ -1880,6 +1912,11 @@ class ActivityStarter { } } mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; if (restrictedBgActivity) { mAvoidMoveToFront = true; mDoResume = false; } } } private void sendNewTaskResultRequestIfNeeded() { private void sendNewTaskResultRequestIfNeeded() { Loading Loading @@ -2277,6 +2314,9 @@ class ActivityStarter { // isLockTaskModeViolation fails below. // isLockTaskModeViolation fails below. if (mReuseTask == null) { if (mReuseTask == null) { if (mRestrictedBgActivity && handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } final TaskRecord task = mTargetStack.createTaskRecord( final TaskRecord task = mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, Loading @@ -2289,6 +2329,11 @@ class ActivityStarter { if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity + " in new task " + mStartActivity.getTaskRecord()); + " in new task " + mStartActivity.getTaskRecord()); } else { } else { if (mRestrictedBgActivity && !mReuseTask.containsAppUid(mCallingUid)) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } } addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask"); addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask"); } } Loading Loading @@ -2328,6 +2373,12 @@ class ActivityStarter { final TaskRecord sourceTask = mSourceRecord.getTaskRecord(); final TaskRecord sourceTask = mSourceRecord.getTaskRecord(); final ActivityStack sourceStack = mSourceRecord.getActivityStack(); final ActivityStack sourceStack = mSourceRecord.getActivityStack(); if (mRestrictedBgActivity && !sourceTask.containsAppUid(mCallingUid)) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } return START_ABORTED; } // We only want to allow changing stack in two cases: // We only want to allow changing stack in two cases: // 1. If the target task is not the top one. Otherwise we would move the launching task to // 1. If the target task is not the top one. Otherwise we would move the launching task to // the other side, rather than show two side by side. // the other side, rather than show two side by side. Loading Loading @@ -2489,20 +2540,33 @@ class ActivityStarter { } } } } private void setTaskToCurrentTopOrCreateNewTask() { private int setTaskToCurrentTopOrCreateNewTask() { mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions); mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions); if (mDoResume) { if (mDoResume) { mTargetStack.moveToFront("addingToTopTask"); mTargetStack.moveToFront("addingToTopTask"); } } final ActivityRecord prev = mTargetStack.getTopActivity(); final ActivityRecord prev = mTargetStack.getTopActivity(); if (mRestrictedBgActivity && prev == null) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } return START_ABORTED; } final TaskRecord task = (prev != null) final TaskRecord task = (prev != null) ? prev.getTaskRecord() : mTargetStack.createTaskRecord( ? prev.getTaskRecord() : mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info, mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info, mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions); mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions); if (mRestrictedBgActivity && !task.containsAppUid(mCallingUid)) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } return START_ABORTED; } addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask"); addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask"); mTargetStack.positionChildWindowContainerAtTop(task); mTargetStack.positionChildWindowContainerAtTop(task); if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.getTaskRecord()); + " in new guessed " + mStartActivity.getTaskRecord()); return START_SUCCESS; } } private void addOrReparentStartingActivity(TaskRecord parent, String reason) { private void addOrReparentStartingActivity(TaskRecord parent, String reason) { Loading services/core/java/com/android/server/wm/TaskRecord.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -1161,6 +1161,19 @@ class TaskRecord extends ConfigurationContainer { return false; return false; } } /** * Return true if any activities in this task belongs to input uid. */ boolean containsAppUid(int uid) { for (int i = mActivities.size() - 1; i >= 0; --i) { final ActivityRecord r = mActivities.get(i); if (r.getUid() == uid) { return true; } } return false; } void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) { void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) { if (mStack != null) { if (mStack != null) { for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) { for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) { Loading Loading
services/core/java/com/android/server/wm/ActivityStarter.java +83 −19 Original line number Original line Diff line number Diff line Loading @@ -160,6 +160,10 @@ class ActivityStarter { private int mCallingUid; private int mCallingUid; private ActivityOptions mOptions; private ActivityOptions mOptions; // If it is true, background activity can only be started in an existing task that contains // an activity with same uid. private boolean mRestrictedBgActivity; private int mLaunchMode; private int mLaunchMode; private boolean mLaunchTaskBehind; private boolean mLaunchTaskBehind; private int mLaunchFlags; private int mLaunchFlags; Loading Loading @@ -455,6 +459,7 @@ class ActivityStarter { mIntent = starter.mIntent; mIntent = starter.mIntent; mCallingUid = starter.mCallingUid; mCallingUid = starter.mCallingUid; mOptions = starter.mOptions; mOptions = starter.mOptions; mRestrictedBgActivity = starter.mRestrictedBgActivity; mLaunchTaskBehind = starter.mLaunchTaskBehind; mLaunchTaskBehind = starter.mLaunchTaskBehind; mLaunchFlags = starter.mLaunchFlags; mLaunchFlags = starter.mLaunchFlags; Loading Loading @@ -551,7 +556,8 @@ class ActivityStarter { mLastStartActivityTimeMs = System.currentTimeMillis(); mLastStartActivityTimeMs = System.currentTimeMillis(); mLastStartActivityRecord[0] = r; mLastStartActivityRecord[0] = r; mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor, mLastStartActivityResult = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, mLastStartActivityRecord); startFlags, doResume, options, inTask, mLastStartActivityRecord, false /* restrictedBgActivity */); mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult, mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(mLastStartActivityResult, mLastStartActivityRecord[0]); mLastStartActivityRecord[0]); return mLastStartActivityResult; return mLastStartActivityResult; Loading Loading @@ -760,22 +766,17 @@ class ActivityStarter { abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo); callingPid, resolvedType, aInfo.applicationInfo); boolean abortBackgroundStart = false; boolean restrictedBgActivity = false; if (!abort) { if (!abort) { try { try { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "shouldAbortBackgroundActivityStart"); "shouldAbortBackgroundActivityStart"); abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, callingPid, callingPackage, realCallingUid, realCallingPid, callerApp, originatingPendingIntent, allowBackgroundActivityStart, intent); originatingPendingIntent, allowBackgroundActivityStart, intent); } finally { } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } abort |= (abortBackgroundStart && !mService.isBackgroundActivityStartsEnabled()); // TODO: remove this toast after feature development is done if (abortBackgroundStart) { showBackgroundActivityBlockedToast(abort, callingPackage); } } } // Merge the two options bundles, while realCallerOptions takes precedence. // Merge the two options bundles, while realCallerOptions takes precedence. Loading Loading @@ -918,8 +919,10 @@ class ActivityStarter { || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) { || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, realCallingPid, realCallingUid, "Activity start")) { realCallingPid, realCallingUid, "Activity start")) { if (!restrictedBgActivity) { mController.addPendingActivityLaunch(new PendingActivityLaunch(r, mController.addPendingActivityLaunch(new PendingActivityLaunch(r, sourceRecord, startFlags, stack, callerApp)); sourceRecord, startFlags, stack, callerApp)); } ActivityOptions.abort(checkedOptions); ActivityOptions.abort(checkedOptions); return ActivityManager.START_SWITCHES_CANCELED; return ActivityManager.START_SWITCHES_CANCELED; } } Loading @@ -929,7 +932,7 @@ class ActivityStarter { mController.doPendingActivityLaunches(false); mController.doPendingActivityLaunches(false); final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity); mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]); mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]); return res; return res; } } Loading Loading @@ -1401,13 +1404,13 @@ class ActivityStarter { private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ActivityRecord[] outActivity, boolean restrictedBgActivity) { int result = START_CANCELED; int result = START_CANCELED; final ActivityStack startedActivityStack; final ActivityStack startedActivityStack; try { try { mService.mWindowManager.deferSurfaceLayout(); mService.mWindowManager.deferSurfaceLayout(); result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); startFlags, doResume, options, inTask, outActivity, restrictedBgActivity); } finally { } finally { final ActivityStack currentStack = r.getActivityStack(); final ActivityStack currentStack = r.getActivityStack(); startedActivityStack = currentStack != null ? currentStack : mTargetStack; startedActivityStack = currentStack != null ? currentStack : mTargetStack; Loading Loading @@ -1443,14 +1446,40 @@ class ActivityStarter { return result; return result; } } /** * Return true if background activity is really aborted. * * TODO(b/131748165): Refactor the logic so we don't need to call this method everywhere. */ private boolean handleBackgroundActivityAbort(ActivityRecord r) { // TODO(b/131747138): Remove toast and refactor related code in Q release. boolean abort = !mService.isBackgroundActivityStartsEnabled(); showBackgroundActivityBlockedToast(abort, r.launchedFromPackage); if (!abort) { return false; } ActivityRecord resultRecord = r.resultTo; String resultWho = r.resultWho; int requestCode = r.requestCode; if (resultRecord != null) { ActivityStack resultStack = resultRecord.getActivityStack(); resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null); } // We pretend to the caller that it was really started to make it backward compatible, but // they will just get a cancel result. ActivityOptions.abort(r.pendingOptions); return true; } // Note: This method should only be called from {@link startActivity}. // Note: This method should only be called from {@link startActivity}. private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ActivityRecord[] outActivity, boolean restrictedBgActivity) { setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor); voiceInteractor, restrictedBgActivity); final int preferredWindowingMode = mLaunchParams.mWindowingMode; final int preferredWindowingMode = mLaunchParams.mWindowingMode; computeLaunchingTaskFlags(); computeLaunchingTaskFlags(); Loading Loading @@ -1658,7 +1687,7 @@ class ActivityStarter { } else { } else { // This not being started from an existing activity, and not part of a new task... // This not being started from an existing activity, and not part of a new task... // just put it in the top task, though these days this case should never happen. // just put it in the top task, though these days this case should never happen. setTaskToCurrentTopOrCreateNewTask(); result = setTaskToCurrentTopOrCreateNewTask(); } } if (result != START_SUCCESS) { if (result != START_SUCCESS) { return result; return result; Loading Loading @@ -1731,6 +1760,7 @@ class ActivityStarter { mIntent = null; mIntent = null; mCallingUid = -1; mCallingUid = -1; mOptions = null; mOptions = null; mRestrictedBgActivity = false; mLaunchTaskBehind = false; mLaunchTaskBehind = false; mLaunchFlags = 0; mLaunchFlags = 0; Loading Loading @@ -1770,7 +1800,8 @@ class ActivityStarter { private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask, private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask, boolean doResume, int startFlags, ActivityRecord sourceRecord, boolean doResume, int startFlags, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, boolean restrictedBgActivity) { reset(false /* clearRequest */); reset(false /* clearRequest */); mStartActivity = r; mStartActivity = r; Loading @@ -1780,6 +1811,7 @@ class ActivityStarter { mSourceRecord = sourceRecord; mSourceRecord = sourceRecord; mVoiceSession = voiceSession; mVoiceSession = voiceSession; mVoiceInteractor = voiceInteractor; mVoiceInteractor = voiceInteractor; mRestrictedBgActivity = restrictedBgActivity; mLaunchParams.reset(); mLaunchParams.reset(); Loading Loading @@ -1880,6 +1912,11 @@ class ActivityStarter { } } mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0; if (restrictedBgActivity) { mAvoidMoveToFront = true; mDoResume = false; } } } private void sendNewTaskResultRequestIfNeeded() { private void sendNewTaskResultRequestIfNeeded() { Loading Loading @@ -2277,6 +2314,9 @@ class ActivityStarter { // isLockTaskModeViolation fails below. // isLockTaskModeViolation fails below. if (mReuseTask == null) { if (mReuseTask == null) { if (mRestrictedBgActivity && handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } final TaskRecord task = mTargetStack.createTaskRecord( final TaskRecord task = mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info, Loading @@ -2289,6 +2329,11 @@ class ActivityStarter { if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity + " in new task " + mStartActivity.getTaskRecord()); + " in new task " + mStartActivity.getTaskRecord()); } else { } else { if (mRestrictedBgActivity && !mReuseTask.containsAppUid(mCallingUid)) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } } addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask"); addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask"); } } Loading Loading @@ -2328,6 +2373,12 @@ class ActivityStarter { final TaskRecord sourceTask = mSourceRecord.getTaskRecord(); final TaskRecord sourceTask = mSourceRecord.getTaskRecord(); final ActivityStack sourceStack = mSourceRecord.getActivityStack(); final ActivityStack sourceStack = mSourceRecord.getActivityStack(); if (mRestrictedBgActivity && !sourceTask.containsAppUid(mCallingUid)) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } return START_ABORTED; } // We only want to allow changing stack in two cases: // We only want to allow changing stack in two cases: // 1. If the target task is not the top one. Otherwise we would move the launching task to // 1. If the target task is not the top one. Otherwise we would move the launching task to // the other side, rather than show two side by side. // the other side, rather than show two side by side. Loading Loading @@ -2489,20 +2540,33 @@ class ActivityStarter { } } } } private void setTaskToCurrentTopOrCreateNewTask() { private int setTaskToCurrentTopOrCreateNewTask() { mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions); mTargetStack = computeStackFocus(mStartActivity, false, mLaunchFlags, mOptions); if (mDoResume) { if (mDoResume) { mTargetStack.moveToFront("addingToTopTask"); mTargetStack.moveToFront("addingToTopTask"); } } final ActivityRecord prev = mTargetStack.getTopActivity(); final ActivityRecord prev = mTargetStack.getTopActivity(); if (mRestrictedBgActivity && prev == null) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } return START_ABORTED; } final TaskRecord task = (prev != null) final TaskRecord task = (prev != null) ? prev.getTaskRecord() : mTargetStack.createTaskRecord( ? prev.getTaskRecord() : mTargetStack.createTaskRecord( mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info, mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId), mStartActivity.info, mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions); mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions); if (mRestrictedBgActivity && !task.containsAppUid(mCallingUid)) { if (handleBackgroundActivityAbort(mStartActivity)) { return START_ABORTED; } return START_ABORTED; } addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask"); addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask"); mTargetStack.positionChildWindowContainerAtTop(task); mTargetStack.positionChildWindowContainerAtTop(task); if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.getTaskRecord()); + " in new guessed " + mStartActivity.getTaskRecord()); return START_SUCCESS; } } private void addOrReparentStartingActivity(TaskRecord parent, String reason) { private void addOrReparentStartingActivity(TaskRecord parent, String reason) { Loading
services/core/java/com/android/server/wm/TaskRecord.java +13 −0 Original line number Original line Diff line number Diff line Loading @@ -1161,6 +1161,19 @@ class TaskRecord extends ConfigurationContainer { return false; return false; } } /** * Return true if any activities in this task belongs to input uid. */ boolean containsAppUid(int uid) { for (int i = mActivities.size() - 1; i >= 0; --i) { final ActivityRecord r = mActivities.get(i); if (r.getUid() == uid) { return true; } } return false; } void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) { void getAllRunningVisibleActivitiesLocked(ArrayList<ActivityRecord> outActivities) { if (mStack != null) { if (mStack != null) { for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) { for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) { Loading