Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +33 −37 Original line number Original line Diff line number Diff line Loading @@ -377,12 +377,10 @@ public class StartingSurfaceDrawer { final int taskId = startingWindowInfo.taskInfo.taskId; final int taskId = startingWindowInfo.taskInfo.taskId; final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */); snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */); mMainExecutor.execute(() -> { mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT); mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT); final StartingWindowRecord tView = final StartingWindowRecord tView = new StartingWindowRecord(null/* decorView */, surface); new StartingWindowRecord(null/* decorView */, surface); mStartingWindowRecords.put(taskId, tView); mStartingWindowRecords.put(taskId, tView); }); } } /** /** Loading @@ -392,12 +390,11 @@ public class StartingSurfaceDrawer { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { Slog.d(TAG, "Task start finish, remove starting surface for task " + taskId); 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, protected void postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm, WindowManager.LayoutParams params) { View view, WindowManager wm, WindowManager.LayoutParams params) { mMainExecutor.execute(() -> { boolean shouldSaveView = true; boolean shouldSaveView = true; try { try { wm.addView(view, params); wm.addView(view, params); Loading Loading @@ -427,7 +424,6 @@ public class StartingSurfaceDrawer { new StartingWindowRecord(view, null /* TaskSnapshotWindow */); new StartingWindowRecord(view, null /* TaskSnapshotWindow */); mStartingWindowRecords.put(taskId, tView); mStartingWindowRecords.put(taskId, tView); } } }); } } protected void removeWindowSynced(int taskId) { protected void removeWindowSynced(int taskId) { Loading @@ -445,7 +441,7 @@ public class StartingSurfaceDrawer { if (DEBUG_TASK_SNAPSHOT) { if (DEBUG_TASK_SNAPSHOT) { Slog.v(TAG, "Removing task snapshot window for " + taskId); Slog.v(TAG, "Removing task snapshot window for " + taskId); } } record.mTaskSnapshotWindow.remove(mMainExecutor); record.mTaskSnapshotWindow.remove(); } } mStartingWindowRecords.remove(taskId); mStartingWindowRecords.remove(taskId); } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +27 −29 Original line number Original line 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.policy.DecorView; import com.android.internal.view.BaseIWindow; import com.android.internal.view.BaseIWindow; import com.android.wm.shell.common.ShellExecutor; 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. * 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 Window mWindow; private final Surface mSurface; private final Surface mSurface; private final Runnable mClearWindowHandler; private final Runnable mClearWindowHandler; private final ShellExecutor mMainExecutor; private SurfaceControl mSurfaceControl; private SurfaceControl mSurfaceControl; private SurfaceControl mChildSurfaceControl; private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; private final IWindowSession mSession; Loading Loading @@ -213,7 +215,7 @@ public class TaskSnapshotWindow { final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, topWindowInsetsState, clearWindowHandler); topWindowInsetsState, clearWindowHandler, mainExecutor); final Window window = snapshotSurface.mWindow; final Window window = snapshotSurface.mWindow; final InsetsState mTmpInsetsState = new InsetsState(); final InsetsState mTmpInsetsState = new InsetsState(); Loading @@ -229,7 +231,7 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { } catch (RemoteException e) { snapshotSurface.clearWindowSynced(); snapshotSurface.clearWindowSynced(); } } window.setOuter(snapshotSurface, mainExecutor); window.setOuter(snapshotSurface); try { try { session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, Loading @@ -249,7 +251,8 @@ public class TaskSnapshotWindow { TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState topWindowInsetsState, int currentOrientation, int activityType, InsetsState topWindowInsetsState, Runnable clearWindowHandler) { Runnable clearWindowHandler, ShellExecutor mainExecutor) { mMainExecutor = mainExecutor; mSurface = new Surface(); mSurface = new Surface(); mSession = WindowManagerGlobal.getWindowSession(); mSession = WindowManagerGlobal.getWindowSession(); mWindow = new Window(); mWindow = new Window(); Loading Loading @@ -286,19 +289,18 @@ public class TaskSnapshotWindow { mSystemBarBackgroundPainter.drawNavigationBarBackground(c); mSystemBarBackgroundPainter.drawNavigationBarBackground(c); } } void remove(ShellExecutor mainExecutor) { void remove() { final long now = SystemClock.uptimeMillis(); final long now = SystemClock.uptimeMillis(); if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS // Show the latest content as soon as possible for unlocking to home. // Show the latest content as soon as possible for unlocking to home. && mActivityType != ACTIVITY_TYPE_HOME) { && mActivityType != ACTIVITY_TYPE_HOME) { final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now; final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now; mainExecutor.executeDelayed(() -> remove(mainExecutor), delayTime); mMainExecutor.executeDelayed(() -> remove(), delayTime); if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); } } return; return; } } mainExecutor.execute(() -> { try { try { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); Loading @@ -307,7 +309,6 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { } catch (RemoteException e) { // nothing // nothing } } }); } } /** /** Loading Loading @@ -497,13 +498,12 @@ public class TaskSnapshotWindow { } } } } @ExternalThread static class Window extends BaseIWindow { static class Window extends BaseIWindow { private TaskSnapshotWindow mOuter; private TaskSnapshotWindow mOuter; private ShellExecutor mMainExecutor; public void setOuter(TaskSnapshotWindow outer, ShellExecutor mainExecutor) { public void setOuter(TaskSnapshotWindow outer) { mOuter = outer; mOuter = outer; mMainExecutor = mainExecutor; } } @Override @Override Loading @@ -511,22 +511,20 @@ public class TaskSnapshotWindow { MergedConfiguration mergedConfiguration, boolean forceLayout, MergedConfiguration mergedConfiguration, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId) { boolean alwaysConsumeSystemBars, int displayId) { if (mOuter != null) { if (mOuter != null) { mOuter.mMainExecutor.execute(() -> { if (mergedConfiguration != null if (mergedConfiguration != null && mOuter.mOrientationOnCreation && mOuter.mOrientationOnCreation != mergedConfiguration.getMergedConfiguration().orientation) { != mergedConfiguration.getMergedConfiguration().orientation) { // The orientation of the screen is changing. We better remove the snapshot ASAP // The orientation of the screen is changing. We better remove the snapshot // as we are going to wait on the new window in any case to unfreeze the screen, // ASAP as we are going to wait on the new window in any case to unfreeze // and the starting window is not needed anymore. // the screen, and the starting window is not needed anymore. mMainExecutor.execute(() -> { mOuter.clearWindowSynced(); mOuter.clearWindowSynced(); }); } else if (reportDraw) { } else if (reportDraw) { mMainExecutor.execute(() -> { if (mOuter.mHasDrawn) { if (mOuter.mHasDrawn) { mOuter.reportDrawn(); mOuter.reportDrawn(); } } }); } } }); } } } } } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitions.java 0 → 100644 +40 −0 Original line number Original line 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 Original line Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class Transitions { private final ShellExecutor mAnimExecutor; private final ShellExecutor mAnimExecutor; private final TransitionPlayerImpl mPlayerImpl; private final TransitionPlayerImpl mPlayerImpl; private final RemoteTransitionHandler mRemoteTransitionHandler; private final RemoteTransitionHandler mRemoteTransitionHandler; private final RemoteTransitionImpl mImpl = new RemoteTransitionImpl(); /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */ /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */ private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>(); 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 */ /** Keeps track of currently tracked transitions and all the animations associated with each */ private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>(); 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, public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { mOrganizer = organizer; mOrganizer = organizer; Loading @@ -101,8 +106,20 @@ public class Transitions { /** Create an empty/non-registering transitions object for system-ui tests. */ /** Create an empty/non-registering transitions object for system-ui tests. */ @VisibleForTesting @VisibleForTesting public static Transitions createEmptyForTesting() { public static RemoteTransitions createEmptyForTesting() { return new Transitions(); 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 */ /** 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 */ /** Register a remote transition to be used when `filter` matches an incoming transition */ @ExternalThread public void registerRemote(@NonNull TransitionFilter filter, public void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition) { @NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> mRemoteTransitionHandler.addFiltered(filter, remoteTransition)); mRemoteTransitionHandler.addFiltered(filter, remoteTransition); } } /** Unregisters a remote transition and all associated filters */ /** Unregisters a remote transition and all associated filters */ @ExternalThread public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) { 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 */ /** @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)); 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 Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.window.TaskSnapshot; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.startingsurface.TaskSnapshotWindow; import com.android.wm.shell.startingsurface.TaskSnapshotWindow; import org.junit.Test; import org.junit.Test; Loading Loading @@ -83,7 +84,7 @@ public class TaskSnapshotWindowTest { createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(), taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(), null /* clearWindow */); null /* clearWindow */, new TestShellExecutor()); } } private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, 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 Original line Diff line number Diff line Loading @@ -377,12 +377,10 @@ public class StartingSurfaceDrawer { final int taskId = startingWindowInfo.taskInfo.taskId; final int taskId = startingWindowInfo.taskInfo.taskId; final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, final TaskSnapshotWindow surface = TaskSnapshotWindow.create(startingWindowInfo, appToken, snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */); snapshot, mMainExecutor, () -> removeWindowSynced(taskId) /* clearWindow */); mMainExecutor.execute(() -> { mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT); mMainExecutor.executeDelayed(() -> removeWindowSynced(taskId), REMOVE_WHEN_TIMEOUT); final StartingWindowRecord tView = final StartingWindowRecord tView = new StartingWindowRecord(null/* decorView */, surface); new StartingWindowRecord(null/* decorView */, surface); mStartingWindowRecords.put(taskId, tView); mStartingWindowRecords.put(taskId, tView); }); } } /** /** Loading @@ -392,12 +390,11 @@ public class StartingSurfaceDrawer { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { Slog.d(TAG, "Task start finish, remove starting surface for task " + taskId); 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, protected void postAddWindow(int taskId, IBinder appToken, View view, WindowManager wm, WindowManager.LayoutParams params) { View view, WindowManager wm, WindowManager.LayoutParams params) { mMainExecutor.execute(() -> { boolean shouldSaveView = true; boolean shouldSaveView = true; try { try { wm.addView(view, params); wm.addView(view, params); Loading Loading @@ -427,7 +424,6 @@ public class StartingSurfaceDrawer { new StartingWindowRecord(view, null /* TaskSnapshotWindow */); new StartingWindowRecord(view, null /* TaskSnapshotWindow */); mStartingWindowRecords.put(taskId, tView); mStartingWindowRecords.put(taskId, tView); } } }); } } protected void removeWindowSynced(int taskId) { protected void removeWindowSynced(int taskId) { Loading @@ -445,7 +441,7 @@ public class StartingSurfaceDrawer { if (DEBUG_TASK_SNAPSHOT) { if (DEBUG_TASK_SNAPSHOT) { Slog.v(TAG, "Removing task snapshot window for " + taskId); Slog.v(TAG, "Removing task snapshot window for " + taskId); } } record.mTaskSnapshotWindow.remove(mMainExecutor); record.mTaskSnapshotWindow.remove(); } } mStartingWindowRecords.remove(taskId); mStartingWindowRecords.remove(taskId); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +27 −29 Original line number Original line 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.policy.DecorView; import com.android.internal.view.BaseIWindow; import com.android.internal.view.BaseIWindow; import com.android.wm.shell.common.ShellExecutor; 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. * 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 Window mWindow; private final Surface mSurface; private final Surface mSurface; private final Runnable mClearWindowHandler; private final Runnable mClearWindowHandler; private final ShellExecutor mMainExecutor; private SurfaceControl mSurfaceControl; private SurfaceControl mSurfaceControl; private SurfaceControl mChildSurfaceControl; private SurfaceControl mChildSurfaceControl; private final IWindowSession mSession; private final IWindowSession mSession; Loading Loading @@ -213,7 +215,7 @@ public class TaskSnapshotWindow { final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( final TaskSnapshotWindow snapshotSurface = new TaskSnapshotWindow( surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, surfaceControl, snapshot, layoutParams.getTitle(), taskDescription, appearance, windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, windowFlags, windowPrivateFlags, taskBounds, orientation, activityType, topWindowInsetsState, clearWindowHandler); topWindowInsetsState, clearWindowHandler, mainExecutor); final Window window = snapshotSurface.mWindow; final Window window = snapshotSurface.mWindow; final InsetsState mTmpInsetsState = new InsetsState(); final InsetsState mTmpInsetsState = new InsetsState(); Loading @@ -229,7 +231,7 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { } catch (RemoteException e) { snapshotSurface.clearWindowSynced(); snapshotSurface.clearWindowSynced(); } } window.setOuter(snapshotSurface, mainExecutor); window.setOuter(snapshotSurface); try { try { session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, -1, tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, tmpFrames, tmpMergedConfiguration, surfaceControl, mTmpInsetsState, Loading @@ -249,7 +251,8 @@ public class TaskSnapshotWindow { TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, TaskSnapshot snapshot, CharSequence title, TaskDescription taskDescription, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int appearance, int windowFlags, int windowPrivateFlags, Rect taskBounds, int currentOrientation, int activityType, InsetsState topWindowInsetsState, int currentOrientation, int activityType, InsetsState topWindowInsetsState, Runnable clearWindowHandler) { Runnable clearWindowHandler, ShellExecutor mainExecutor) { mMainExecutor = mainExecutor; mSurface = new Surface(); mSurface = new Surface(); mSession = WindowManagerGlobal.getWindowSession(); mSession = WindowManagerGlobal.getWindowSession(); mWindow = new Window(); mWindow = new Window(); Loading Loading @@ -286,19 +289,18 @@ public class TaskSnapshotWindow { mSystemBarBackgroundPainter.drawNavigationBarBackground(c); mSystemBarBackgroundPainter.drawNavigationBarBackground(c); } } void remove(ShellExecutor mainExecutor) { void remove() { final long now = SystemClock.uptimeMillis(); final long now = SystemClock.uptimeMillis(); if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS if (mSizeMismatch && now - mShownTime < SIZE_MISMATCH_MINIMUM_TIME_MS // Show the latest content as soon as possible for unlocking to home. // Show the latest content as soon as possible for unlocking to home. && mActivityType != ACTIVITY_TYPE_HOME) { && mActivityType != ACTIVITY_TYPE_HOME) { final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now; final long delayTime = mShownTime + SIZE_MISMATCH_MINIMUM_TIME_MS - now; mainExecutor.executeDelayed(() -> remove(mainExecutor), delayTime); mMainExecutor.executeDelayed(() -> remove(), delayTime); if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); Slog.d(TAG, "Defer removing snapshot surface in " + delayTime); } } return; return; } } mainExecutor.execute(() -> { try { try { if (DEBUG) { if (DEBUG) { Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); Slog.d(TAG, "Removing snapshot surface, mHasDrawn: " + mHasDrawn); Loading @@ -307,7 +309,6 @@ public class TaskSnapshotWindow { } catch (RemoteException e) { } catch (RemoteException e) { // nothing // nothing } } }); } } /** /** Loading Loading @@ -497,13 +498,12 @@ public class TaskSnapshotWindow { } } } } @ExternalThread static class Window extends BaseIWindow { static class Window extends BaseIWindow { private TaskSnapshotWindow mOuter; private TaskSnapshotWindow mOuter; private ShellExecutor mMainExecutor; public void setOuter(TaskSnapshotWindow outer, ShellExecutor mainExecutor) { public void setOuter(TaskSnapshotWindow outer) { mOuter = outer; mOuter = outer; mMainExecutor = mainExecutor; } } @Override @Override Loading @@ -511,22 +511,20 @@ public class TaskSnapshotWindow { MergedConfiguration mergedConfiguration, boolean forceLayout, MergedConfiguration mergedConfiguration, boolean forceLayout, boolean alwaysConsumeSystemBars, int displayId) { boolean alwaysConsumeSystemBars, int displayId) { if (mOuter != null) { if (mOuter != null) { mOuter.mMainExecutor.execute(() -> { if (mergedConfiguration != null if (mergedConfiguration != null && mOuter.mOrientationOnCreation && mOuter.mOrientationOnCreation != mergedConfiguration.getMergedConfiguration().orientation) { != mergedConfiguration.getMergedConfiguration().orientation) { // The orientation of the screen is changing. We better remove the snapshot ASAP // The orientation of the screen is changing. We better remove the snapshot // as we are going to wait on the new window in any case to unfreeze the screen, // ASAP as we are going to wait on the new window in any case to unfreeze // and the starting window is not needed anymore. // the screen, and the starting window is not needed anymore. mMainExecutor.execute(() -> { mOuter.clearWindowSynced(); mOuter.clearWindowSynced(); }); } else if (reportDraw) { } else if (reportDraw) { mMainExecutor.execute(() -> { if (mOuter.mHasDrawn) { if (mOuter.mHasDrawn) { mOuter.reportDrawn(); mOuter.reportDrawn(); } } }); } } }); } } } } } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitions.java 0 → 100644 +40 −0 Original line number Original line 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 Original line Diff line number Diff line Loading @@ -67,6 +67,7 @@ public class Transitions { private final ShellExecutor mAnimExecutor; private final ShellExecutor mAnimExecutor; private final TransitionPlayerImpl mPlayerImpl; private final TransitionPlayerImpl mPlayerImpl; private final RemoteTransitionHandler mRemoteTransitionHandler; private final RemoteTransitionHandler mRemoteTransitionHandler; private final RemoteTransitionImpl mImpl = new RemoteTransitionImpl(); /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */ /** List of possible handlers. Ordered by specificity (eg. tapped back to front). */ private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>(); 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 */ /** Keeps track of currently tracked transitions and all the animations associated with each */ private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>(); 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, public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool, @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { mOrganizer = organizer; mOrganizer = organizer; Loading @@ -101,8 +106,20 @@ public class Transitions { /** Create an empty/non-registering transitions object for system-ui tests. */ /** Create an empty/non-registering transitions object for system-ui tests. */ @VisibleForTesting @VisibleForTesting public static Transitions createEmptyForTesting() { public static RemoteTransitions createEmptyForTesting() { return new Transitions(); 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 */ /** 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 */ /** Register a remote transition to be used when `filter` matches an incoming transition */ @ExternalThread public void registerRemote(@NonNull TransitionFilter filter, public void registerRemote(@NonNull TransitionFilter filter, @NonNull IRemoteTransition remoteTransition) { @NonNull IRemoteTransition remoteTransition) { mMainExecutor.execute(() -> mRemoteTransitionHandler.addFiltered(filter, remoteTransition)); mRemoteTransitionHandler.addFiltered(filter, remoteTransition); } } /** Unregisters a remote transition and all associated filters */ /** Unregisters a remote transition and all associated filters */ @ExternalThread public void unregisterRemote(@NonNull IRemoteTransition remoteTransition) { 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 */ /** @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)); 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 Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.window.TaskSnapshot; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest; import com.android.wm.shell.TestShellExecutor; import com.android.wm.shell.startingsurface.TaskSnapshotWindow; import com.android.wm.shell.startingsurface.TaskSnapshotWindow; import org.junit.Test; import org.junit.Test; Loading Loading @@ -83,7 +84,7 @@ public class TaskSnapshotWindowTest { createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), createTaskDescription(Color.WHITE, Color.RED, Color.BLUE), 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, 0 /* appearance */, windowFlags /* windowFlags */, 0 /* privateWindowFlags */, taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(), taskBounds, ORIENTATION_PORTRAIT, ACTIVITY_TYPE_STANDARD, new InsetsState(), null /* clearWindow */); null /* clearWindow */, new TestShellExecutor()); } } private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, private TaskSnapshot createTaskSnapshot(int width, int height, Point taskSize, Loading