Loading core/java/android/app/ActivityOptions.java +41 −22 Original line number Diff line number Diff line Loading @@ -183,6 +183,12 @@ public class ActivityOptions extends ComponentOptions { */ public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener"; /** * Callback for when animation is aborted. * @hide */ private static final String KEY_ANIM_ABORT_LISTENER = "android:activity.animAbortListener"; /** * Specific a theme for a splash screen window. * @hide Loading Loading @@ -459,6 +465,7 @@ public class ActivityOptions extends ComponentOptions { private int mHeight; private IRemoteCallback mAnimationStartedListener; private IRemoteCallback mAnimationFinishedListener; private IRemoteCallback mAnimationAbortListener; private SceneTransitionInfo mSceneTransitionInfo; private PendingIntent mUsageTimeReport; private int mLaunchDisplayId = INVALID_DISPLAY; Loading Loading @@ -715,6 +722,14 @@ public class ActivityOptions extends ComponentOptions { } } /** * Callback for finding out when the given animation is finished * @hide */ public void setOnAnimationFinishedListener(IRemoteCallback listener) { mAnimationFinishedListener = listener; } /** * Callback for finding out when the given animation has drawn its last frame. * @hide Loading @@ -727,6 +742,14 @@ public class ActivityOptions extends ComponentOptions { void onAnimationFinished(long elapsedRealTime); } /** * Callback for finding out when the given animation is aborted * @hide */ public void setOnAnimationAbortListener(IRemoteCallback listener) { mAnimationAbortListener = listener; } /** * Create an ActivityOptions specifying an animation where the new * activity is scaled from a small originating area of the screen to Loading Loading @@ -1327,6 +1350,8 @@ public class ActivityOptions extends ComponentOptions { KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE, MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); mDisableStartingWindow = opts.getBoolean(KEY_DISABLE_STARTING_WINDOW); mAnimationAbortListener = IRemoteCallback.Stub.asInterface( opts.getBinder(KEY_ANIM_ABORT_LISTENER)); } /** Loading Loading @@ -1427,11 +1452,15 @@ public class ActivityOptions extends ComponentOptions { /** @hide */ public void abort() { if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { sendResultIgnoreErrors(mAnimationStartedListener, null); sendResultIgnoreErrors(mAnimationAbortListener, null); } private void sendResultIgnoreErrors(IRemoteCallback callback, Bundle data) { if (callback != null) { try { callback.sendResult(data); } catch (RemoteException e) { } } } Loading Loading @@ -2110,12 +2139,7 @@ public class ActivityOptions extends ComponentOptions { mCustomExitResId = otherOptions.mCustomExitResId; mCustomBackgroundColor = otherOptions.mCustomBackgroundColor; mThumbnail = null; if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } sendResultIgnoreErrors(mAnimationStartedListener, null); mAnimationStartedListener = otherOptions.mAnimationStartedListener; break; case ANIM_CUSTOM_IN_PLACE: Loading @@ -2126,12 +2150,7 @@ public class ActivityOptions extends ComponentOptions { mStartY = otherOptions.mStartY; mWidth = otherOptions.mWidth; mHeight = otherOptions.mHeight; if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } sendResultIgnoreErrors(mAnimationStartedListener, null); mAnimationStartedListener = null; break; case ANIM_THUMBNAIL_SCALE_UP: Loading @@ -2143,12 +2162,7 @@ public class ActivityOptions extends ComponentOptions { mStartY = otherOptions.mStartY; mWidth = otherOptions.mWidth; mHeight = otherOptions.mHeight; if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } sendResultIgnoreErrors(mAnimationStartedListener, null); mAnimationStartedListener = otherOptions.mAnimationStartedListener; break; case ANIM_SCENE_TRANSITION: Loading @@ -2165,6 +2179,9 @@ public class ActivityOptions extends ComponentOptions { mRemoteAnimationAdapter = otherOptions.mRemoteAnimationAdapter; mLaunchIntoPipParams = otherOptions.mLaunchIntoPipParams; mIsEligibleForLegacyPermissionPrompt = otherOptions.mIsEligibleForLegacyPermissionPrompt; sendResultIgnoreErrors(mAnimationAbortListener, null); mAnimationAbortListener = otherOptions.mAnimationAbortListener; } /** Loading Loading @@ -2363,6 +2380,8 @@ public class ActivityOptions extends ComponentOptions { if (mDisableStartingWindow) { b.putBoolean(KEY_DISABLE_STARTING_WINDOW, mDisableStartingWindow); } b.putBinder(KEY_ANIM_ABORT_LISTENER, mAnimationAbortListener != null ? mAnimationAbortListener.asBinder() : null); return b; } Loading services/tests/wmtests/src/com/android/server/wm/ActivityOptionsTest.java +27 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.IRemoteCallback; import android.platform.test.annotations.Presubmit; import android.util.Log; import android.util.Rational; Loading @@ -63,6 +64,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** * Build/Install/Run: Loading Loading @@ -118,6 +120,29 @@ public class ActivityOptionsTest { assertTrue(opts.isLaunchIntoPip()); } @Test public void testAbortListenerCalled() { AtomicBoolean callbackCalled = new AtomicBoolean(false); ActivityOptions options = ActivityOptions.makeBasic(); options.setOnAnimationAbortListener(new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) { callbackCalled.set(true); } }); // Verify that the callback is called on abort options.abort(); assertTrue(callbackCalled.get()); // Verify that the callback survives saving to bundle ActivityOptions optionsCopy = ActivityOptions.fromBundle(options.toBundle()); callbackCalled.set(false); optionsCopy.abort(); assertTrue(callbackCalled.get()); } @Test public void testTransferLaunchCookie() { final Binder cookie = new Binder(); Loading Loading @@ -279,7 +304,9 @@ public class ActivityOptionsTest { case "android.activity.pendingIntentCreatorBackgroundActivityStartMode": // KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE case "android.activity.launchCookie": // KEY_LAUNCH_COOKIE case "android:activity.animAbortListener": // KEY_ANIM_ABORT_LISTENER // Existing keys break; default: unknownKeys.add(key); Loading Loading
core/java/android/app/ActivityOptions.java +41 −22 Original line number Diff line number Diff line Loading @@ -183,6 +183,12 @@ public class ActivityOptions extends ComponentOptions { */ public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener"; /** * Callback for when animation is aborted. * @hide */ private static final String KEY_ANIM_ABORT_LISTENER = "android:activity.animAbortListener"; /** * Specific a theme for a splash screen window. * @hide Loading Loading @@ -459,6 +465,7 @@ public class ActivityOptions extends ComponentOptions { private int mHeight; private IRemoteCallback mAnimationStartedListener; private IRemoteCallback mAnimationFinishedListener; private IRemoteCallback mAnimationAbortListener; private SceneTransitionInfo mSceneTransitionInfo; private PendingIntent mUsageTimeReport; private int mLaunchDisplayId = INVALID_DISPLAY; Loading Loading @@ -715,6 +722,14 @@ public class ActivityOptions extends ComponentOptions { } } /** * Callback for finding out when the given animation is finished * @hide */ public void setOnAnimationFinishedListener(IRemoteCallback listener) { mAnimationFinishedListener = listener; } /** * Callback for finding out when the given animation has drawn its last frame. * @hide Loading @@ -727,6 +742,14 @@ public class ActivityOptions extends ComponentOptions { void onAnimationFinished(long elapsedRealTime); } /** * Callback for finding out when the given animation is aborted * @hide */ public void setOnAnimationAbortListener(IRemoteCallback listener) { mAnimationAbortListener = listener; } /** * Create an ActivityOptions specifying an animation where the new * activity is scaled from a small originating area of the screen to Loading Loading @@ -1327,6 +1350,8 @@ public class ActivityOptions extends ComponentOptions { KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE, MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED); mDisableStartingWindow = opts.getBoolean(KEY_DISABLE_STARTING_WINDOW); mAnimationAbortListener = IRemoteCallback.Stub.asInterface( opts.getBinder(KEY_ANIM_ABORT_LISTENER)); } /** Loading Loading @@ -1427,11 +1452,15 @@ public class ActivityOptions extends ComponentOptions { /** @hide */ public void abort() { if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { sendResultIgnoreErrors(mAnimationStartedListener, null); sendResultIgnoreErrors(mAnimationAbortListener, null); } private void sendResultIgnoreErrors(IRemoteCallback callback, Bundle data) { if (callback != null) { try { callback.sendResult(data); } catch (RemoteException e) { } } } Loading Loading @@ -2110,12 +2139,7 @@ public class ActivityOptions extends ComponentOptions { mCustomExitResId = otherOptions.mCustomExitResId; mCustomBackgroundColor = otherOptions.mCustomBackgroundColor; mThumbnail = null; if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } sendResultIgnoreErrors(mAnimationStartedListener, null); mAnimationStartedListener = otherOptions.mAnimationStartedListener; break; case ANIM_CUSTOM_IN_PLACE: Loading @@ -2126,12 +2150,7 @@ public class ActivityOptions extends ComponentOptions { mStartY = otherOptions.mStartY; mWidth = otherOptions.mWidth; mHeight = otherOptions.mHeight; if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } sendResultIgnoreErrors(mAnimationStartedListener, null); mAnimationStartedListener = null; break; case ANIM_THUMBNAIL_SCALE_UP: Loading @@ -2143,12 +2162,7 @@ public class ActivityOptions extends ComponentOptions { mStartY = otherOptions.mStartY; mWidth = otherOptions.mWidth; mHeight = otherOptions.mHeight; if (mAnimationStartedListener != null) { try { mAnimationStartedListener.sendResult(null); } catch (RemoteException e) { } } sendResultIgnoreErrors(mAnimationStartedListener, null); mAnimationStartedListener = otherOptions.mAnimationStartedListener; break; case ANIM_SCENE_TRANSITION: Loading @@ -2165,6 +2179,9 @@ public class ActivityOptions extends ComponentOptions { mRemoteAnimationAdapter = otherOptions.mRemoteAnimationAdapter; mLaunchIntoPipParams = otherOptions.mLaunchIntoPipParams; mIsEligibleForLegacyPermissionPrompt = otherOptions.mIsEligibleForLegacyPermissionPrompt; sendResultIgnoreErrors(mAnimationAbortListener, null); mAnimationAbortListener = otherOptions.mAnimationAbortListener; } /** Loading Loading @@ -2363,6 +2380,8 @@ public class ActivityOptions extends ComponentOptions { if (mDisableStartingWindow) { b.putBoolean(KEY_DISABLE_STARTING_WINDOW, mDisableStartingWindow); } b.putBinder(KEY_ANIM_ABORT_LISTENER, mAnimationAbortListener != null ? mAnimationAbortListener.asBinder() : null); return b; } Loading
services/tests/wmtests/src/com/android/server/wm/ActivityOptionsTest.java +27 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.IRemoteCallback; import android.platform.test.annotations.Presubmit; import android.util.Log; import android.util.Rational; Loading @@ -63,6 +64,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** * Build/Install/Run: Loading Loading @@ -118,6 +120,29 @@ public class ActivityOptionsTest { assertTrue(opts.isLaunchIntoPip()); } @Test public void testAbortListenerCalled() { AtomicBoolean callbackCalled = new AtomicBoolean(false); ActivityOptions options = ActivityOptions.makeBasic(); options.setOnAnimationAbortListener(new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) { callbackCalled.set(true); } }); // Verify that the callback is called on abort options.abort(); assertTrue(callbackCalled.get()); // Verify that the callback survives saving to bundle ActivityOptions optionsCopy = ActivityOptions.fromBundle(options.toBundle()); callbackCalled.set(false); optionsCopy.abort(); assertTrue(callbackCalled.get()); } @Test public void testTransferLaunchCookie() { final Binder cookie = new Binder(); Loading Loading @@ -279,7 +304,9 @@ public class ActivityOptionsTest { case "android.activity.pendingIntentCreatorBackgroundActivityStartMode": // KEY_PENDING_INTENT_CREATOR_BACKGROUND_ACTIVITY_START_MODE case "android.activity.launchCookie": // KEY_LAUNCH_COOKIE case "android:activity.animAbortListener": // KEY_ANIM_ABORT_LISTENER // Existing keys break; default: unknownKeys.add(key); Loading