Loading core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -206,3 +206,13 @@ flag { } } flag { name: "enforce_shell_thread_model" namespace: "windowing_frentend" description: "Crash the shell process if someone calls in from the wrong thread" bug: "351189446" is_fixed_read_only: true metadata { purpose: PURPOSE_BUGFIX } } libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java +7 −0 Original line number Diff line number Diff line Loading @@ -54,4 +54,11 @@ public class HandlerExecutor implements ShellExecutor { public boolean hasCallback(Runnable r) { return mHandler.hasCallbacks(r); } @Override public void assertCurrentThread() { if (!mHandler.getLooper().isCurrentThread()) { throw new IllegalStateException("must be called on " + mHandler); } } } libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java +7 −0 Original line number Diff line number Diff line Loading @@ -96,4 +96,11 @@ public interface ShellExecutor extends Executor { * See {@link android.os.Handler#hasCallbacks(Runnable)}. */ boolean hasCallback(Runnable runnable); /** * May throw if the caller is not on the same thread as the executor. */ default void assertCurrentThread() { return; } } libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +30 −5 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_NO_ANIMATION; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; import static com.android.window.flags.Flags.enforceShellThreadModel; import static com.android.window.flags.Flags.ensureWallpaperInTransitions; import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary; import static com.android.wm.shell.shared.TransitionUtil.isClosingType; Loading Loading @@ -924,9 +925,12 @@ public class Transitions implements RemoteCallable<Transitions>, } // An existing animation is playing, so see if we can merge. final ActiveTransition playing = track.mActiveTransition; final IBinder playingToken = playing.mToken; final IBinder readyToken = ready.mToken; if (ready.mAborted) { // record as merged since it is no-op. Calls back into processReadyQueue onMerged(playing, ready); onMerged(playingToken, readyToken); return; } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s ready while" Loading @@ -934,14 +938,31 @@ public class Transitions implements RemoteCallable<Transitions>, + " in case they can be merged", ready, playing); mTransitionTracer.logMergeRequested(ready.mInfo.getDebugId(), playing.mInfo.getDebugId()); playing.mHandler.mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT, playing.mToken, (wct) -> onMerged(playing, ready)); playing.mToken, (wct) -> onMerged(playingToken, readyToken)); } private void onMerged(@NonNull IBinder playingToken, @NonNull IBinder mergedToken) { if (enforceShellThreadModel()) { mMainExecutor.assertCurrentThread(); } ActiveTransition playing = mKnownTransitions.get(playingToken); if (playing == null) { Log.e(TAG, "Merging into a non-existent transition: " + playingToken); return; } ActiveTransition merged = mKnownTransitions.get(mergedToken); if (merged == null) { Log.e(TAG, "Merging a non-existent transition: " + mergedToken); return; } private void onMerged(@NonNull ActiveTransition playing, @NonNull ActiveTransition merged) { if (playing.getTrack() != merged.getTrack()) { throw new IllegalStateException("Can't merge across tracks: " + merged + " into " + playing); } final Track track = mTracks.get(playing.getTrack()); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s into %s", merged, playing); Loading Loading @@ -1071,13 +1092,17 @@ public class Transitions implements RemoteCallable<Transitions>, info.releaseAnimSurfaces(); } private void onFinish(IBinder token, @Nullable WindowContainerTransaction wct) { private void onFinish(IBinder token, @Nullable WindowContainerTransaction wct) { if (enforceShellThreadModel()) { mMainExecutor.assertCurrentThread(); } final ActiveTransition active = mKnownTransitions.get(token); if (active == null) { Log.e(TAG, "Trying to finish a non-existent transition: " + token); return; } final Track track = mTracks.get(active.getTrack()); if (track == null || track.mActiveTransition != active) { Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or " Loading Loading
core/java/android/window/flags/windowing_frontend.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -206,3 +206,13 @@ flag { } } flag { name: "enforce_shell_thread_model" namespace: "windowing_frentend" description: "Crash the shell process if someone calls in from the wrong thread" bug: "351189446" is_fixed_read_only: true metadata { purpose: PURPOSE_BUGFIX } }
libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java +7 −0 Original line number Diff line number Diff line Loading @@ -54,4 +54,11 @@ public class HandlerExecutor implements ShellExecutor { public boolean hasCallback(Runnable r) { return mHandler.hasCallbacks(r); } @Override public void assertCurrentThread() { if (!mHandler.getLooper().isCurrentThread()) { throw new IllegalStateException("must be called on " + mHandler); } } }
libs/WindowManager/Shell/src/com/android/wm/shell/common/ShellExecutor.java +7 −0 Original line number Diff line number Diff line Loading @@ -96,4 +96,11 @@ public interface ShellExecutor extends Executor { * See {@link android.os.Handler#hasCallbacks(Runnable)}. */ boolean hasCallback(Runnable runnable); /** * May throw if the caller is not on the same thread as the executor. */ default void assertCurrentThread() { return; } }
libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +30 −5 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import static android.window.TransitionInfo.FLAG_IS_WALLPAPER; import static android.window.TransitionInfo.FLAG_NO_ANIMATION; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; import static com.android.window.flags.Flags.enforceShellThreadModel; import static com.android.window.flags.Flags.ensureWallpaperInTransitions; import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary; import static com.android.wm.shell.shared.TransitionUtil.isClosingType; Loading Loading @@ -924,9 +925,12 @@ public class Transitions implements RemoteCallable<Transitions>, } // An existing animation is playing, so see if we can merge. final ActiveTransition playing = track.mActiveTransition; final IBinder playingToken = playing.mToken; final IBinder readyToken = ready.mToken; if (ready.mAborted) { // record as merged since it is no-op. Calls back into processReadyQueue onMerged(playing, ready); onMerged(playingToken, readyToken); return; } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s ready while" Loading @@ -934,14 +938,31 @@ public class Transitions implements RemoteCallable<Transitions>, + " in case they can be merged", ready, playing); mTransitionTracer.logMergeRequested(ready.mInfo.getDebugId(), playing.mInfo.getDebugId()); playing.mHandler.mergeAnimation(ready.mToken, ready.mInfo, ready.mStartT, playing.mToken, (wct) -> onMerged(playing, ready)); playing.mToken, (wct) -> onMerged(playingToken, readyToken)); } private void onMerged(@NonNull IBinder playingToken, @NonNull IBinder mergedToken) { if (enforceShellThreadModel()) { mMainExecutor.assertCurrentThread(); } ActiveTransition playing = mKnownTransitions.get(playingToken); if (playing == null) { Log.e(TAG, "Merging into a non-existent transition: " + playingToken); return; } ActiveTransition merged = mKnownTransitions.get(mergedToken); if (merged == null) { Log.e(TAG, "Merging a non-existent transition: " + mergedToken); return; } private void onMerged(@NonNull ActiveTransition playing, @NonNull ActiveTransition merged) { if (playing.getTrack() != merged.getTrack()) { throw new IllegalStateException("Can't merge across tracks: " + merged + " into " + playing); } final Track track = mTracks.get(playing.getTrack()); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s into %s", merged, playing); Loading Loading @@ -1071,13 +1092,17 @@ public class Transitions implements RemoteCallable<Transitions>, info.releaseAnimSurfaces(); } private void onFinish(IBinder token, @Nullable WindowContainerTransaction wct) { private void onFinish(IBinder token, @Nullable WindowContainerTransaction wct) { if (enforceShellThreadModel()) { mMainExecutor.assertCurrentThread(); } final ActiveTransition active = mKnownTransitions.get(token); if (active == null) { Log.e(TAG, "Trying to finish a non-existent transition: " + token); return; } final Track track = mTracks.get(active.getTrack()); if (track == null || track.mActiveTransition != active) { Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or " Loading