Merge "Add a quick path to start transient recents" into tm-qpr-dev
This commit is contained in:
@@ -19,7 +19,9 @@ package com.android.server.wm;
|
||||
import static android.app.ActivityManager.START_CANCELED;
|
||||
import static android.app.ActivityManager.START_SUCCESS;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
|
||||
|
||||
@@ -29,6 +31,7 @@ import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.IApplicationThread;
|
||||
import android.content.ComponentName;
|
||||
@@ -46,6 +49,7 @@ import android.provider.Settings;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
@@ -536,6 +540,42 @@ public class ActivityStartController {
|
||||
.execute();
|
||||
}
|
||||
|
||||
boolean startExistingRecentsIfPossible(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()
|
||||
.getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
|
||||
if (rootTask == null) return false;
|
||||
final ActivityRecord r = rootTask.topRunningActivity();
|
||||
if (r == null || r.mVisibleRequested || !r.attachedToProcess()
|
||||
|| !r.mActivityComponent.equals(intent.getComponent())
|
||||
// Recents keeps invisible while device is locked.
|
||||
|| r.mDisplayContent.isKeyguardLocked()) {
|
||||
return false;
|
||||
}
|
||||
mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r);
|
||||
final ActivityMetricsLogger.LaunchingState launchingState =
|
||||
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
|
||||
final Task task = r.getTask();
|
||||
mService.deferWindowLayout();
|
||||
try {
|
||||
task.mTransitionController.requestTransitionIfNeeded(WindowManager.TRANSIT_TO_FRONT,
|
||||
0 /* flags */, task, task /* readyGroupRef */,
|
||||
options.getRemoteTransition(), null /* displayChange */);
|
||||
r.mTransitionController.setTransientLaunch(r,
|
||||
TaskDisplayArea.getRootTaskAbove(rootTask));
|
||||
task.moveToFront("startExistingRecents");
|
||||
task.mInResumeTopActivity = true;
|
||||
task.resumeTopActivity(null /* prev */, options, true /* deferPause */);
|
||||
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState,
|
||||
ActivityManager.START_TASK_TO_FRONT, false, r, options);
|
||||
} finally {
|
||||
task.mInResumeTopActivity = false;
|
||||
mService.continueWindowLayout();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void registerRemoteAnimationForNextActivityStart(String packageName,
|
||||
RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
|
||||
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
|
||||
|
||||
@@ -1231,6 +1231,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
@Nullable String callingFeatureId, Intent intent, String resolvedType,
|
||||
IBinder resultTo, String resultWho, int requestCode, int startFlags,
|
||||
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
|
||||
|
||||
final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
|
||||
// A quick path (skip general intent/task resolving) to start recents animation if the
|
||||
// recents (or home) activity is available in background.
|
||||
if (opts != null && opts.getOriginalOptions().getTransientLaunch()
|
||||
&& isCallerRecents(Binder.getCallingUid())) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (mGlobalLock) {
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
|
||||
if (mActivityStartController.startExistingRecentsIfPossible(
|
||||
intent, opts.getOriginalOptions())) {
|
||||
return ActivityManager.START_TASK_TO_FRONT;
|
||||
}
|
||||
// Else follow the standard launch procedure.
|
||||
}
|
||||
} finally {
|
||||
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
|
||||
assertPackageMatchesCallingUid(callingPackage);
|
||||
enforceNotIsolatedCaller("startActivityAsUser");
|
||||
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
|
||||
@@ -1257,7 +1279,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
.setRequestCode(requestCode)
|
||||
.setStartFlags(startFlags)
|
||||
.setProfilerInfo(profilerInfo)
|
||||
.setActivityOptions(bOptions)
|
||||
.setActivityOptions(opts)
|
||||
.setUserId(userId)
|
||||
.execute();
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
||||
} else {
|
||||
mTransitionOp = OP_CHANGE;
|
||||
}
|
||||
} else if (transitionType != WindowManager.TRANSIT_NONE) {
|
||||
} else if (displayContent.mTransitionController.isShellTransitionsEnabled()) {
|
||||
mTransitionOp = OP_APP_SWITCH;
|
||||
} else {
|
||||
mTransitionOp = OP_LEGACY;
|
||||
|
||||
@@ -1687,7 +1687,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (r.isState(RESUMED) && !r.getRootTask().mInResumeTopActivity) {
|
||||
if (r.isState(RESUMED) && !r.getTask().mInResumeTopActivity) {
|
||||
// If the activity is executing or has done the lifecycle callback, use normal
|
||||
// rotation animation so the display info can be updated immediately (see
|
||||
// updateDisplayAndOrientation). This prevents a compatibility issue such as
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.wm;
|
||||
|
||||
import static android.Manifest.permission.CONTROL_KEYGUARD;
|
||||
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
|
||||
import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
|
||||
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
|
||||
import static android.Manifest.permission.STATUS_BAR_SERVICE;
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
@@ -247,6 +248,14 @@ public class SafeActivityOptions {
|
||||
throw new SecurityException(msg);
|
||||
}
|
||||
}
|
||||
if (options.getTransientLaunch() && !supervisor.mRecentTasks.isCallerRecents(callingUid)
|
||||
&& ActivityTaskManagerService.checkPermission(
|
||||
MANAGE_ACTIVITY_TASKS, callingPid, callingUid) == PERMISSION_DENIED) {
|
||||
final String msg = "Permission Denial: starting transient launch from " + callerApp
|
||||
+ ", pid=" + callingPid + ", uid=" + callingUid;
|
||||
Slog.w(TAG, msg);
|
||||
throw new SecurityException(msg);
|
||||
}
|
||||
// Check if the caller is allowed to launch on the specified display area.
|
||||
final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
|
||||
final TaskDisplayArea taskDisplayArea = daToken != null
|
||||
|
||||
Reference in New Issue
Block a user