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_CANCELED;
|
||||||
import static android.app.ActivityManager.START_SUCCESS;
|
import static android.app.ActivityManager.START_SUCCESS;
|
||||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
|
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_FULLSCREEN;
|
||||||
|
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||||
import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
|
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.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.app.IApplicationThread;
|
import android.app.IApplicationThread;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -46,6 +49,7 @@ import android.provider.Settings;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.view.RemoteAnimationAdapter;
|
import android.view.RemoteAnimationAdapter;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
@@ -536,6 +540,42 @@ public class ActivityStartController {
|
|||||||
.execute();
|
.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,
|
void registerRemoteAnimationForNextActivityStart(String packageName,
|
||||||
RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
|
RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
|
||||||
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
|
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
|
||||||
|
|||||||
@@ -1231,6 +1231,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
@Nullable String callingFeatureId, Intent intent, String resolvedType,
|
@Nullable String callingFeatureId, Intent intent, String resolvedType,
|
||||||
IBinder resultTo, String resultWho, int requestCode, int startFlags,
|
IBinder resultTo, String resultWho, int requestCode, int startFlags,
|
||||||
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
|
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);
|
assertPackageMatchesCallingUid(callingPackage);
|
||||||
enforceNotIsolatedCaller("startActivityAsUser");
|
enforceNotIsolatedCaller("startActivityAsUser");
|
||||||
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
|
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
|
||||||
@@ -1257,7 +1279,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
.setRequestCode(requestCode)
|
.setRequestCode(requestCode)
|
||||||
.setStartFlags(startFlags)
|
.setStartFlags(startFlags)
|
||||||
.setProfilerInfo(profilerInfo)
|
.setProfilerInfo(profilerInfo)
|
||||||
.setActivityOptions(bOptions)
|
.setActivityOptions(opts)
|
||||||
.setUserId(userId)
|
.setUserId(userId)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class AsyncRotationController extends FadeAnimationController implements Consume
|
|||||||
} else {
|
} else {
|
||||||
mTransitionOp = OP_CHANGE;
|
mTransitionOp = OP_CHANGE;
|
||||||
}
|
}
|
||||||
} else if (transitionType != WindowManager.TRANSIT_NONE) {
|
} else if (displayContent.mTransitionController.isShellTransitionsEnabled()) {
|
||||||
mTransitionOp = OP_APP_SWITCH;
|
mTransitionOp = OP_APP_SWITCH;
|
||||||
} else {
|
} else {
|
||||||
mTransitionOp = OP_LEGACY;
|
mTransitionOp = OP_LEGACY;
|
||||||
|
|||||||
@@ -1687,7 +1687,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
return false;
|
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
|
// If the activity is executing or has done the lifecycle callback, use normal
|
||||||
// rotation animation so the display info can be updated immediately (see
|
// rotation animation so the display info can be updated immediately (see
|
||||||
// updateDisplayAndOrientation). This prevents a compatibility issue such as
|
// 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_KEYGUARD;
|
||||||
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
|
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.START_TASKS_FROM_RECENTS;
|
||||||
import static android.Manifest.permission.STATUS_BAR_SERVICE;
|
import static android.Manifest.permission.STATUS_BAR_SERVICE;
|
||||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||||
@@ -247,6 +248,14 @@ public class SafeActivityOptions {
|
|||||||
throw new SecurityException(msg);
|
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.
|
// Check if the caller is allowed to launch on the specified display area.
|
||||||
final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
|
final WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
|
||||||
final TaskDisplayArea taskDisplayArea = daToken != null
|
final TaskDisplayArea taskDisplayArea = daToken != null
|
||||||
|
|||||||
Reference in New Issue
Block a user