Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +33 −37 Original line number Diff line number Diff line Loading @@ -377,12 +377,10 @@ public class StartingSurfaceDrawer { final int taskId = startingWindowInfo.taskInfo.taskId; final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */); mMainExecutor.execute(() -> { mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT); final StartingWindowRecord tView = new StartingWindowRecord(null/* decorView */, surface); mStartingWindowRecords.put(taskId, tView); }); } /** Loading @@ -392,12 +390,11 @@ public class StartingSurfaceDrawer { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { Slog.d(TAG, "Task start finish, remove starting surface for task " + taskId); } mMainExecutor.execute(() -> removeWindowSynced(taskId)); removeWindowSynced(taskId); } protected void postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm, WindowManager.LayoutParams params) { mMainExecutor.execute(() -> { boolean shouldSaveView = true; try { wm.addView(view, params); Loading Loading @@ -427,7 +424,6 @@ public class StartingSurfaceDrawer { new StartingWindowRecord(view, null /* TaskSnapshotWindow */); mStartingWindowRecords.put(taskId, tView); } }); } protected void removeWindowSynced(int taskId) { Loading @@ -445,7 +441,7 @@ public class StartingSurfaceDrawer { if (DEBUG_TASK_SNAPSHOT) { Slog.v(TAG, "Removing task snapshot window for " + taskId); } record.mTaskSnapshotWindow.remove(mMainExecutor); record.mTaskSnapshotWindow.remove(); } mStartingWindowRecords.remove(taskId); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +27 −29 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.DecorView; import com.android.internal.view.BaseIWindow; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.annotations.ExternalThread; /** * This class represents a starting window that shows a snapshot. Loading Loading @@ -121,6 +122,7 @@ public class TaskSnapshotWindow { private final Window mWindow; private final Surface mSurface; private final Runnable mClearWindowHandler; private final ShellExecutor mMainExecutor; private SurfaceControl mSurfaceControl; private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; Loading Loading @@ -213,7 +215,7 @@ public class TaskSnapshotWindow { final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, topWindowInsetsState, clearWindowHandler); topWindowInsetsState, clearWindowHandler, mainExecutor); final Window window = snapshotSurface.mWindow; final InsetsState mTmpInsetsState = new InsetsState(); Loading @@ -229,7 +231,7 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { snapshotSurface.clearWindowSynced(); } window.setOuter(snapshotSurface, mainExecutor); window.setOuter(snapshotSurface); try { session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, Loading @@ -249,7 +251,8 @@ public class TaskSnapshotWindow { TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState topWindowInsetsState, Runnable clearWindowHandler) { Runnable clearWindowHandler, ShellExecutor mainExecutor) { mMainExecutor = mainExecutor; mSurface = new Surface(); mSession = WindowManagerGlobal.getWindowSession(); mWindow = new Window(); Loading Loading @@ -286,19 +289,18 @@ public class TaskSnapshotWindow { mSystemBarBackgroundPainter.drawNavigationBarBackground(c); } void remove(ShellExecutor mainExecutor) { void remove() { final long now = SystemClock.uptimeMillis(); if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS // Show the latest content as soon as possible for unlocking to home. && mActivityType != ACTIVITY_TYPE_HOME) { final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now; mainExecutor.executeDelayed(() -> remove(mainExecutor), delayTime); mMainExecutor.executeDelayed(() -> remove(), delayTime); if (DEBUG) { Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); } return; } mainExecutor.execute(() -> { try { if (DEBUG) { Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); Loading @@ -307,7 +309,6 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { // nothing } }); } /** Loading Loading @@ -497,13 +498,12 @@ public class TaskSnapshotWindow { } } @ExternalThread static class Window extends BaseIWindow { private TaskSnapshotWindow mOuter; private ShellExecutor mMainExecutor; public void setOuter(TaskSnapshotWindow outer, ShellExecutor mainExecutor) { public void setOuter(TaskSnapshotWindow outer) { mOuter = outer; mMainExecutor = mainExecutor; } @Override Loading @@ -511,22 +511,20 @@ public class TaskSnapshotWindow { MergedConfiguration mergedConfiguration, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId) { if (mOuter != null) { mOuter.mMainExecutor.execute(() -> { if (mergedConfiguration != null && mOuter.mOrientationOnCreation != mergedConfiguration.getMergedConfiguration().orientation) { // The orientation of the screen is changing. We better remove the snapshot ASAP // as we are going to wait on the new window in any case to unfreeze the screen, // and the starting window is not needed anymore. mMainExecutor.execute(() -> { // The orientation of the screen is changing. We better remove the snapshot // ASAP as we are going to wait on the new window in any case to unfreeze // the screen, and the starting window is not needed anymore. mOuter.clearWindowSynced(); }); } else if (reportDraw) { mMainExecutor.execute(() -> { if (mOuter.mHasDrawn) { mOuter.reportDrawn(); } }); } }); } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitions.java 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.transition; import android.annotation.NonNull; import android.window.IRemoteTransition; import android.window.TransitionFilter; import com.android.wm.shell.common.annotations.ExternalThread; /** * Interface to manage remote transitions. */ @ExternalThread public interface RemoteTransitions { /** * Registers a remote transition. */ void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition); /** * Unregisters a remote transition. */ void unregisterRemote(@NonNull IRemoteTransition remoteTransition); } libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +39 −6 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class Transitions { private final ShellExecutor mAnimExecutor; private final TransitionPlayerImpl mPlayerImpl; private final RemoteTransitionHandler mRemoteTransitionHandler; private final RemoteTransitionImpl mImpl = new RemoteTransitionImpl(); /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */ private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>(); Loading @@ -78,6 +79,10 @@ public class Transitions { /** Keeps track of currently tracked transitions and all the animations associated with each */ private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>(); public static RemoteTransitions asRemoteTransitions(Transitions transitions) { return transitions.mImpl; } public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { mOrganizer = organizer; Loading @@ -101,8 +106,20 @@ public class Transitions { /** Create an empty/non-registering transitions object for system-ui tests. */ @VisibleForTesting public static Transitions createEmptyForTesting() { return new Transitions(); public static RemoteTransitions createEmptyForTesting() { return new RemoteTransitions() { @Override public void registerRemote(@androidx.annotation.NonNull TransitionFilter filter, @androidx.annotation.NonNull IRemoteTransition remoteTransition) { // Do nothing } @Override public void unregisterRemote( @androidx.annotation.NonNull IRemoteTransition remoteTransition) { // Do nothing } }; } /** Register this transition handler with Core */ Loading Loading @@ -134,16 +151,14 @@ public class Transitions { } /** Register a remote transition to be used when `filter` matches an incoming transition */ @ExternalThread public void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> mRemoteTransitionHandler.addFiltered(filter, remoteTransition)); mRemoteTransitionHandler.addFiltered(filter, remoteTransition); } /** Unregisters a remote transition and all associated filters */ @ExternalThread public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> mRemoteTransitionHandler.removeFiltered(remoteTransition)); mRemoteTransitionHandler.removeFiltered(remoteTransition); } /** @return true if the transition was triggered by opening something vs closing something */ Loading Loading @@ -361,4 +376,22 @@ public class Transitions { mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request)); } } @ExternalThread private class RemoteTransitionImpl implements RemoteTransitions { @Override public void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> { Transitions.this.registerRemote(filter, remoteTransition); }); } @Override public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> { Transitions.this.unregisterRemote(remoteTransition); }); } } } libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.window.TaskSnapshot; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.startingsurface.TaskSnapshotWindow; import org.junit.Test; Loading Loading @@ -83,7 +84,7 @@ public class TaskSnapshotWindowTest { createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(), null /* clearWindow */); null /* clearWindow */, new TestShellExecutor()); } private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +33 −37 Original line number Diff line number Diff line Loading @@ -377,12 +377,10 @@ public class StartingSurfaceDrawer { final int taskId = startingWindowInfo.taskInfo.taskId; final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */); mMainExecutor.execute(() -> { mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT); final StartingWindowRecord tView = new StartingWindowRecord(null/* decorView */, surface); mStartingWindowRecords.put(taskId, tView); }); } /** Loading @@ -392,12 +390,11 @@ public class StartingSurfaceDrawer { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { Slog.d(TAG, "Task start finish, remove starting surface for task " + taskId); } mMainExecutor.execute(() -> removeWindowSynced(taskId)); removeWindowSynced(taskId); } protected void postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm, WindowManager.LayoutParams params) { mMainExecutor.execute(() -> { boolean shouldSaveView = true; try { wm.addView(view, params); Loading Loading @@ -427,7 +424,6 @@ public class StartingSurfaceDrawer { new StartingWindowRecord(view, null /* TaskSnapshotWindow */); mStartingWindowRecords.put(taskId, tView); } }); } protected void removeWindowSynced(int taskId) { Loading @@ -445,7 +441,7 @@ public class StartingSurfaceDrawer { if (DEBUG_TASK_SNAPSHOT) { Slog.v(TAG, "Removing task snapshot window for " + taskId); } record.mTaskSnapshotWindow.remove(mMainExecutor); record.mTaskSnapshotWindow.remove(); } mStartingWindowRecords.remove(taskId); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +27 −29 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.policy.DecorView; import com.android.internal.view.BaseIWindow; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.annotations.ExternalThread; /** * This class represents a starting window that shows a snapshot. Loading Loading @@ -121,6 +122,7 @@ public class TaskSnapshotWindow { private final Window mWindow; private final Surface mSurface; private final Runnable mClearWindowHandler; private final ShellExecutor mMainExecutor; private SurfaceControl mSurfaceControl; private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; Loading Loading @@ -213,7 +215,7 @@ public class TaskSnapshotWindow { final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, topWindowInsetsState, clearWindowHandler); topWindowInsetsState, clearWindowHandler, mainExecutor); final Window window = snapshotSurface.mWindow; final InsetsState mTmpInsetsState = new InsetsState(); Loading @@ -229,7 +231,7 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { snapshotSurface.clearWindowSynced(); } window.setOuter(snapshotSurface, mainExecutor); window.setOuter(snapshotSurface); try { session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, Loading @@ -249,7 +251,8 @@ public class TaskSnapshotWindow { TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState topWindowInsetsState, Runnable clearWindowHandler) { Runnable clearWindowHandler, ShellExecutor mainExecutor) { mMainExecutor = mainExecutor; mSurface = new Surface(); mSession = WindowManagerGlobal.getWindowSession(); mWindow = new Window(); Loading Loading @@ -286,19 +289,18 @@ public class TaskSnapshotWindow { mSystemBarBackgroundPainter.drawNavigationBarBackground(c); } void remove(ShellExecutor mainExecutor) { void remove() { final long now = SystemClock.uptimeMillis(); if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS // Show the latest content as soon as possible for unlocking to home. && mActivityType != ACTIVITY_TYPE_HOME) { final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now; mainExecutor.executeDelayed(() -> remove(mainExecutor), delayTime); mMainExecutor.executeDelayed(() -> remove(), delayTime); if (DEBUG) { Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); } return; } mainExecutor.execute(() -> { try { if (DEBUG) { Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); Loading @@ -307,7 +309,6 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { // nothing } }); } /** Loading Loading @@ -497,13 +498,12 @@ public class TaskSnapshotWindow { } } @ExternalThread static class Window extends BaseIWindow { private TaskSnapshotWindow mOuter; private ShellExecutor mMainExecutor; public void setOuter(TaskSnapshotWindow outer, ShellExecutor mainExecutor) { public void setOuter(TaskSnapshotWindow outer) { mOuter = outer; mMainExecutor = mainExecutor; } @Override Loading @@ -511,22 +511,20 @@ public class TaskSnapshotWindow { MergedConfiguration mergedConfiguration, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId) { if (mOuter != null) { mOuter.mMainExecutor.execute(() -> { if (mergedConfiguration != null && mOuter.mOrientationOnCreation != mergedConfiguration.getMergedConfiguration().orientation) { // The orientation of the screen is changing. We better remove the snapshot ASAP // as we are going to wait on the new window in any case to unfreeze the screen, // and the starting window is not needed anymore. mMainExecutor.execute(() -> { // The orientation of the screen is changing. We better remove the snapshot // ASAP as we are going to wait on the new window in any case to unfreeze // the screen, and the starting window is not needed anymore. mOuter.clearWindowSynced(); }); } else if (reportDraw) { mMainExecutor.execute(() -> { if (mOuter.mHasDrawn) { mOuter.reportDrawn(); } }); } }); } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitions.java 0 → 100644 +40 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.wm.shell.transition; import android.annotation.NonNull; import android.window.IRemoteTransition; import android.window.TransitionFilter; import com.android.wm.shell.common.annotations.ExternalThread; /** * Interface to manage remote transitions. */ @ExternalThread public interface RemoteTransitions { /** * Registers a remote transition. */ void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition); /** * Unregisters a remote transition. */ void unregisterRemote(@NonNull IRemoteTransition remoteTransition); }
libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +39 −6 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class Transitions { private final ShellExecutor mAnimExecutor; private final TransitionPlayerImpl mPlayerImpl; private final RemoteTransitionHandler mRemoteTransitionHandler; private final RemoteTransitionImpl mImpl = new RemoteTransitionImpl(); /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */ private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>(); Loading @@ -78,6 +79,10 @@ public class Transitions { /** Keeps track of currently tracked transitions and all the animations associated with each */ private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>(); public static RemoteTransitions asRemoteTransitions(Transitions transitions) { return transitions.mImpl; } public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { mOrganizer = organizer; Loading @@ -101,8 +106,20 @@ public class Transitions { /** Create an empty/non-registering transitions object for system-ui tests. */ @VisibleForTesting public static Transitions createEmptyForTesting() { return new Transitions(); public static RemoteTransitions createEmptyForTesting() { return new RemoteTransitions() { @Override public void registerRemote(@androidx.annotation.NonNull TransitionFilter filter, @androidx.annotation.NonNull IRemoteTransition remoteTransition) { // Do nothing } @Override public void unregisterRemote( @androidx.annotation.NonNull IRemoteTransition remoteTransition) { // Do nothing } }; } /** Register this transition handler with Core */ Loading Loading @@ -134,16 +151,14 @@ public class Transitions { } /** Register a remote transition to be used when `filter` matches an incoming transition */ @ExternalThread public void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> mRemoteTransitionHandler.addFiltered(filter, remoteTransition)); mRemoteTransitionHandler.addFiltered(filter, remoteTransition); } /** Unregisters a remote transition and all associated filters */ @ExternalThread public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> mRemoteTransitionHandler.removeFiltered(remoteTransition)); mRemoteTransitionHandler.removeFiltered(remoteTransition); } /** @return true if the transition was triggered by opening something vs closing something */ Loading Loading @@ -361,4 +376,22 @@ public class Transitions { mMainExecutor.execute(() -> Transitions.this.requestStartTransition(iBinder, request)); } } @ExternalThread private class RemoteTransitionImpl implements RemoteTransitions { @Override public void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> { Transitions.this.registerRemote(filter, remoteTransition); }); } @Override public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> { Transitions.this.unregisterRemote(remoteTransition); }); } } }
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/startingsurface/TaskSnapshotWindowTest.java +2 −1 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.window.TaskSnapshot; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.startingsurface.TaskSnapshotWindow; import org.junit.Test; Loading Loading @@ -83,7 +84,7 @@ public class TaskSnapshotWindowTest { createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(), null /* clearWindow */); null /* clearWindow */, new TestShellExecutor()); } private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, Loading