diff options
3 files changed, 35 insertions, 21 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java index bfe298653584..a6e50405e7d9 100644 --- a/services/core/java/com/android/server/wm/ActivityStartController.java +++ b/services/core/java/com/android/server/wm/ActivityStartController.java @@ -45,6 +45,7 @@ import android.content.pm.ResolveInfo; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; +import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; import android.util.Slog; @@ -554,7 +555,25 @@ public class ActivityStartController { .execute(); } + /** + * A quick path (skip general intent/task resolving) to start recents animation if the recents + * (or home) activity is available in background. + * @return {@code true} if the recents activity is moved to front. + */ boolean startExistingRecentsIfPossible(Intent intent, ActivityOptions options) { + try { + Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startExistingRecents"); + if (startExistingRecents(intent, options)) { + return true; + } + // Else follow the standard launch procedure. + } finally { + Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); + } + return false; + } + + private boolean startExistingRecents(Intent intent, ActivityOptions options) { final int activityType = mService.getRecentTasks().getRecentsComponent() .equals(intent.getComponent()) ? ACTIVITY_TYPE_RECENTS : ACTIVITY_TYPE_HOME; final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea() @@ -563,6 +582,7 @@ public class ActivityStartController { final ActivityRecord r = rootTask.topRunningActivity(); if (r == null || r.isVisibleRequested() || !r.attachedToProcess() || !r.mActivityComponent.equals(intent.getComponent()) + || !mService.isCallerRecents(r.getUid()) // Recents keeps invisible while device is locked. || r.mDisplayContent.isKeyguardLocked()) { return false; diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 1f4606b09396..a0ea1c3dbdbf 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -5753,23 +5753,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent, BackgroundStartPrivileges backgroundStartPrivileges) { assertPackageMatchesCallingUid(callingPackage); - // A quick path (skip general intent/task resolving) to start recents animation if the - // recents (or home) activity is available in background. - if (options != null && options.getOriginalOptions() != null - && options.getOriginalOptions().getTransientLaunch() && isCallerRecents(uid)) { - try { - synchronized (mGlobalLock) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents"); - if (mActivityStartController.startExistingRecentsIfPossible( - intent, options.getOriginalOptions())) { - return ActivityManager.START_TASK_TO_FRONT; - } - // Else follow the standard launch procedure. - } - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - } return getActivityStartController().startActivityInPackage(uid, realCallingPid, realCallingUid, callingPackage, callingFeatureId, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, options, userId, inTask, diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index d5aa520e1b6e..09312bac593f 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -972,19 +972,30 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub switch (type) { case HIERARCHY_OP_TYPE_PENDING_INTENT: { + final Bundle launchOpts = hop.getLaunchOptions(); + ActivityOptions activityOptions = launchOpts != null + ? new ActivityOptions(launchOpts) : null; + if (activityOptions != null && activityOptions.getTransientLaunch() + && mService.isCallerRecents(hop.getPendingIntent().getCreatorUid())) { + if (mService.getActivityStartController().startExistingRecentsIfPossible( + hop.getActivityIntent(), activityOptions)) { + // Start recents successfully. + break; + } + } + String resolvedType = hop.getActivityIntent() != null ? hop.getActivityIntent().resolveTypeIfNeeded( mService.mContext.getContentResolver()) : null; - ActivityOptions activityOptions = null; if (hop.getPendingIntent().isActivity()) { // Set the context display id as preferred for this activity launches, so that // it can land on caller's display. Or just brought the task to front at the // display where it was on since it has higher preference. - activityOptions = hop.getLaunchOptions() != null - ? new ActivityOptions(hop.getLaunchOptions()) - : ActivityOptions.makeBasic(); + if (activityOptions == null) { + activityOptions = ActivityOptions.makeBasic(); + } activityOptions.setCallerDisplayId(DEFAULT_DISPLAY); } final Bundle options = activityOptions != null ? activityOptions.toBundle() : null; |