Loading packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java +41 −9 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.wm.shell.shared.TransitionUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; /** * An implementation of {@link IRemoteTransition} that accepts a {@link UIComponent} as the origin Loading @@ -52,6 +53,7 @@ import java.util.List; */ public class OriginRemoteTransition extends IRemoteTransition.Stub { private static final String TAG = "OriginRemoteTransition"; private static final long FINISH_ANIMATION_TIMEOUT_MS = 100; private final Context mContext; private final boolean mIsEntry; Loading Loading @@ -248,14 +250,12 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { if (mIsEntry) { if (!closingSurfaces.isEmpty()) { tmpTransaction .setRelativeLayer(mOriginLeash, closingSurfaces.get(0), 1); tmpTransaction.setRelativeLayer(mOriginLeash, closingSurfaces.get(0), 1); } else { logW("Missing closing surface is entry transition"); } if (!openingSurfaces.isEmpty()) { tmpTransaction .setRelativeLayer( tmpTransaction.setRelativeLayer( openingSurfaces.get(openingSurfaces.size() - 1), mOriginLeash, 1); } else { logW("Missing opening surface is entry transition"); Loading @@ -263,8 +263,7 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { } else { if (!openingSurfaces.isEmpty()) { tmpTransaction .setRelativeLayer(mOriginLeash, openingSurfaces.get(0), 1); tmpTransaction.setRelativeLayer(mOriginLeash, openingSurfaces.get(0), 1); } else { logW("Missing opening surface is exit transition"); } Loading Loading @@ -293,12 +292,26 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { private void finishAnimation(boolean finished) { logD("finishAnimation: finished=" + finished); OneShotRunnable finishInternalRunnable = new OneShotRunnable(this::finishInternal); Runnable timeoutRunnable = () -> { Log.w(TAG, "Timeout waiting for surface transaction!"); finishInternalRunnable.run(); }; Runnable committedRunnable = () -> { // Remove the timeout runnable. mHandler.removeCallbacks(timeoutRunnable); finishInternalRunnable.run(); }; if (mAnimator == null) { // The transition didn't start. Ensure we apply the start transaction and report // finish afterwards. mStartTransaction .addTransactionCommittedListener(mHandler::post, this::finishInternal) .addTransactionCommittedListener(mHandler::post, committedRunnable::run) .apply(); // Call finishInternal() anyway after the timeout. mHandler.postDelayed(timeoutRunnable, FINISH_ANIMATION_TIMEOUT_MS); return; } mAnimator = null; Loading @@ -306,8 +319,10 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { mPlayer.onEnd(finished); // Detach the origin from the transition leash and report finish after it's done. mOriginTransaction .detachFromTransitionLeash(mOrigin, mHandler::post, this::finishInternal) .detachFromTransitionLeash(mOrigin, mHandler::post, committedRunnable) .commit(); // Call finishInternal() anyway after the timeout. mHandler.postDelayed(timeoutRunnable, FINISH_ANIMATION_TIMEOUT_MS); } private void finishInternal() { Loading Loading @@ -423,6 +438,23 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { return out; } /** A {@link Runnable} that will only run once. */ private static class OneShotRunnable implements Runnable { private final AtomicBoolean mDone = new AtomicBoolean(); private final Runnable mRunnable; OneShotRunnable(Runnable runnable) { this.mRunnable = runnable; } @Override public void run() { if (!mDone.getAndSet(true)) { mRunnable.run(); } } } /** * An interface that represents an origin transitions. * Loading packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java +11 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.Surface; import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; import android.view.ViewTreeObserver.OnDrawListener; import java.util.ArrayList; Loading Loading @@ -131,7 +132,6 @@ public class ViewUIComponent implements UIComponent { mView.getViewTreeObserver().removeOnDrawListener(mOnDrawListener); // Restore view visibility mView.setVisibility(mVisibleOverride ? View.VISIBLE : View.INVISIBLE); mView.invalidate(); // Clean up surfaces. SurfaceControl.Transaction t = new SurfaceControl.Transaction(); t.reparent(sc, null) Loading @@ -142,8 +142,16 @@ public class ViewUIComponent implements UIComponent { sc.release(); executor.execute(onDone); }); ViewRootImpl viewRoot = mView.getViewRootImpl(); if (viewRoot == null) { t.apply(); } else { // Apply transaction AFTER the view is drawn. mView.getRootSurfaceControl().applyTransactionOnDraw(t); viewRoot.applyTransactionOnDraw(t); // Request layout to force redrawing the entire view tree, so that the transaction is // guaranteed to be applied. viewRoot.requestLayout(); } } @Override Loading Loading
packages/SystemUI/animation/lib/src/com/android/systemui/animation/OriginRemoteTransition.java +41 −9 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.wm.shell.shared.TransitionUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; /** * An implementation of {@link IRemoteTransition} that accepts a {@link UIComponent} as the origin Loading @@ -52,6 +53,7 @@ import java.util.List; */ public class OriginRemoteTransition extends IRemoteTransition.Stub { private static final String TAG = "OriginRemoteTransition"; private static final long FINISH_ANIMATION_TIMEOUT_MS = 100; private final Context mContext; private final boolean mIsEntry; Loading Loading @@ -248,14 +250,12 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { if (mIsEntry) { if (!closingSurfaces.isEmpty()) { tmpTransaction .setRelativeLayer(mOriginLeash, closingSurfaces.get(0), 1); tmpTransaction.setRelativeLayer(mOriginLeash, closingSurfaces.get(0), 1); } else { logW("Missing closing surface is entry transition"); } if (!openingSurfaces.isEmpty()) { tmpTransaction .setRelativeLayer( tmpTransaction.setRelativeLayer( openingSurfaces.get(openingSurfaces.size() - 1), mOriginLeash, 1); } else { logW("Missing opening surface is entry transition"); Loading @@ -263,8 +263,7 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { } else { if (!openingSurfaces.isEmpty()) { tmpTransaction .setRelativeLayer(mOriginLeash, openingSurfaces.get(0), 1); tmpTransaction.setRelativeLayer(mOriginLeash, openingSurfaces.get(0), 1); } else { logW("Missing opening surface is exit transition"); } Loading Loading @@ -293,12 +292,26 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { private void finishAnimation(boolean finished) { logD("finishAnimation: finished=" + finished); OneShotRunnable finishInternalRunnable = new OneShotRunnable(this::finishInternal); Runnable timeoutRunnable = () -> { Log.w(TAG, "Timeout waiting for surface transaction!"); finishInternalRunnable.run(); }; Runnable committedRunnable = () -> { // Remove the timeout runnable. mHandler.removeCallbacks(timeoutRunnable); finishInternalRunnable.run(); }; if (mAnimator == null) { // The transition didn't start. Ensure we apply the start transaction and report // finish afterwards. mStartTransaction .addTransactionCommittedListener(mHandler::post, this::finishInternal) .addTransactionCommittedListener(mHandler::post, committedRunnable::run) .apply(); // Call finishInternal() anyway after the timeout. mHandler.postDelayed(timeoutRunnable, FINISH_ANIMATION_TIMEOUT_MS); return; } mAnimator = null; Loading @@ -306,8 +319,10 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { mPlayer.onEnd(finished); // Detach the origin from the transition leash and report finish after it's done. mOriginTransaction .detachFromTransitionLeash(mOrigin, mHandler::post, this::finishInternal) .detachFromTransitionLeash(mOrigin, mHandler::post, committedRunnable) .commit(); // Call finishInternal() anyway after the timeout. mHandler.postDelayed(timeoutRunnable, FINISH_ANIMATION_TIMEOUT_MS); } private void finishInternal() { Loading Loading @@ -423,6 +438,23 @@ public class OriginRemoteTransition extends IRemoteTransition.Stub { return out; } /** A {@link Runnable} that will only run once. */ private static class OneShotRunnable implements Runnable { private final AtomicBoolean mDone = new AtomicBoolean(); private final Runnable mRunnable; OneShotRunnable(Runnable runnable) { this.mRunnable = runnable; } @Override public void run() { if (!mDone.getAndSet(true)) { mRunnable.run(); } } } /** * An interface that represents an origin transitions. * Loading
packages/SystemUI/animation/lib/src/com/android/systemui/animation/ViewUIComponent.java +11 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.view.Surface; import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; import android.view.ViewRootImpl; import android.view.ViewTreeObserver.OnDrawListener; import java.util.ArrayList; Loading Loading @@ -131,7 +132,6 @@ public class ViewUIComponent implements UIComponent { mView.getViewTreeObserver().removeOnDrawListener(mOnDrawListener); // Restore view visibility mView.setVisibility(mVisibleOverride ? View.VISIBLE : View.INVISIBLE); mView.invalidate(); // Clean up surfaces. SurfaceControl.Transaction t = new SurfaceControl.Transaction(); t.reparent(sc, null) Loading @@ -142,8 +142,16 @@ public class ViewUIComponent implements UIComponent { sc.release(); executor.execute(onDone); }); ViewRootImpl viewRoot = mView.getViewRootImpl(); if (viewRoot == null) { t.apply(); } else { // Apply transaction AFTER the view is drawn. mView.getRootSurfaceControl().applyTransactionOnDraw(t); viewRoot.applyTransactionOnDraw(t); // Request layout to force redrawing the entire view tree, so that the transaction is // guaranteed to be applied. viewRoot.requestLayout(); } } @Override Loading