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