diff options
7 files changed, 85 insertions, 17 deletions
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index d701a5d81304..e2b1b8664d75 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -405,6 +405,14 @@ interface IActivityTaskManager { void setDisablePreviewScreenshots(IBinder token, boolean disable); /** + * It should only be called from home activity to remove its outdated snapshot. The home + * snapshot is used to speed up entering home from screen off. If the content of home activity + * is significantly different from before taking the snapshot, then the home activity can use + * this method to avoid inconsistent transition. + */ + void invalidateHomeTaskSnapshot(IBinder homeToken); + + /** * Return the user id of last resumed activity. */ int getLastResumedActivityUserId(); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index 70f8e15eb83d..deaafca7a98c 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -28,6 +28,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECOND import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import android.annotation.NonNull; +import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; @@ -161,6 +162,23 @@ public class ActivityManagerWrapper { } /** + * Removes the outdated snapshot of home task. + */ + public void invalidateHomeTaskSnapshot(final Activity homeActivity) { + mBackgroundExecutor.submit(new Runnable() { + @Override + public void run() { + try { + ActivityTaskManager.getService().invalidateHomeTaskSnapshot( + homeActivity.getActivityToken()); + } catch (RemoteException e) { + Log.w(TAG, "Failed to invalidate home snapshot", e); + } + } + }); + } + + /** * @return the activity label, badging if necessary. */ public String getBadgedActivityLabel(ActivityInfo info, int userId) { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 8435a8202762..c05b70413a40 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -157,6 +157,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.Trace; import android.os.UEventObserver; import android.os.UserHandle; import android.os.VibrationEffect; @@ -4603,6 +4604,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void screenTurningOn(final ScreenOnListener screenOnListener) { if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on..."); + Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */); updateScreenOffSleepToken(false); mDefaultDisplayPolicy.screenTurnedOn(screenOnListener); @@ -4665,6 +4667,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (!mDefaultDisplayPolicy.finishScreenTurningOn()) { return; // Spurious or not ready yet. } + Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn", 0 /* cookie */); final boolean enableScreen; final boolean awake = mDefaultDisplayPolicy.isAwake(); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 69c3967d8806..6de9dbd001d7 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1640,6 +1640,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A allowTaskSnapshot, activityCreated, fromRecents, snapshot); if (type == STARTING_WINDOW_TYPE_SNAPSHOT) { + if (isActivityTypeHome()) { + // The snapshot of home is only used once because it won't be updated while screen + // is on (see {@link TaskSnapshotController#screenTurningOff}). + mWmService.mTaskSnapshotController.removeSnapshotCache(task.mTaskId); + // TODO(b/9684093): Use more general condition to specify the case. + if (mDisplayContent.mAppTransition + .getAppTransition() != WindowManager.TRANSIT_KEYGUARD_GOING_AWAY) { + // Only use snapshot of home as starting window when unlocking. + return false; + } + } return createSnapshot(snapshot); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 9213e05042e0..f0bc4129f4ef 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -4572,6 +4572,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + @Override + public void invalidateHomeTaskSnapshot(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null || !r.isActivityTypeHome()) { + return; + } + mWindowManager.mTaskSnapshotController.removeSnapshotCache(r.getTask().mTaskId); + } + } + /** Return the user id of the last resumed activity. */ @Override public @UserIdInt diff --git a/services/core/java/com/android/server/wm/TaskSnapshotCache.java b/services/core/java/com/android/server/wm/TaskSnapshotCache.java index 5cbab5d1b1f5..7b0d841483bb 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotCache.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotCache.java @@ -109,7 +109,7 @@ class TaskSnapshotCache { removeRunningEntry(taskId); } - private void removeRunningEntry(int taskId) { + void removeRunningEntry(int taskId) { final CacheEntry entry = mRunningCache.get(taskId); if (entry != null) { mAppTaskMap.remove(entry.topApp); diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index c1a36c49fc1a..12b2845e9d71 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -171,22 +171,30 @@ class TaskSnapshotController { } void snapshotTasks(ArraySet<Task> tasks) { + snapshotTasks(mTmpTasks, false /* allowSnapshotHome */); + } + + private void snapshotTasks(ArraySet<Task> tasks, boolean allowSnapshotHome) { for (int i = tasks.size() - 1; i >= 0; i--) { final Task task = tasks.valueAt(i); - final int mode = getSnapshotMode(task); final TaskSnapshot snapshot; - switch (mode) { - case SNAPSHOT_MODE_NONE: - continue; - case SNAPSHOT_MODE_APP_THEME: - snapshot = drawAppThemeSnapshot(task); - break; - case SNAPSHOT_MODE_REAL: - snapshot = snapshotTask(task); - break; - default: - snapshot = null; - break; + final boolean snapshotHome = allowSnapshotHome && task.isActivityTypeHome(); + if (snapshotHome) { + snapshot = snapshotTask(task); + } else { + switch (getSnapshotMode(task)) { + case SNAPSHOT_MODE_NONE: + continue; + case SNAPSHOT_MODE_APP_THEME: + snapshot = drawAppThemeSnapshot(task); + break; + case SNAPSHOT_MODE_REAL: + snapshot = snapshotTask(task); + break; + default: + snapshot = null; + break; + } } if (snapshot != null) { final GraphicBuffer buffer = snapshot.getSnapshot(); @@ -196,8 +204,11 @@ class TaskSnapshotController { + buffer.getHeight()); } else { mCache.putSnapshot(task, snapshot); - mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot); - task.onSnapshotChanged(snapshot); + // Don't persist or notify the change for the temporal snapshot. + if (!snapshotHome) { + mPersister.persistSnapshot(task.mTaskId, task.mUserId, snapshot); + task.onSnapshotChanged(snapshot); + } } } } @@ -450,6 +461,10 @@ class TaskSnapshotController { mPersister.onTaskRemovedFromRecents(taskId, userId); } + void removeSnapshotCache(int taskId) { + mCache.removeRunningEntry(taskId); + } + /** * See {@link TaskSnapshotPersister#removeObsoleteFiles} */ @@ -485,7 +500,9 @@ class TaskSnapshotController { mTmpTasks.add(task); } }); - snapshotTasks(mTmpTasks); + // Allow taking snapshot of home when turning screen off to reduce the delay of + // unlocking/waking to home. + snapshotTasks(mTmpTasks, true /* allowSnapshotHome */); } } finally { listener.onScreenOff(); |