Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb4b7d99 authored by George Mount's avatar George Mount
Browse files

Implement "Back" for Activity Transitions.

Change-Id: Iceaf888f57f2c7598f9291687ac9ad76d55bd82c
parent 45849beb
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -3150,6 +3150,7 @@ package android.app {
    method public void finishActivityFromChild(android.app.Activity, int);
    method public void finishAffinity();
    method public void finishFromChild(android.app.Activity);
    method public void finishWithTransition();
    method public android.app.ActionBar getActionBar();
    method public final android.app.Application getApplication();
    method public android.content.ComponentName getCallingActivity();
@@ -30460,6 +30461,8 @@ package android.view {
    method public boolean requestFeature(int);
    method public abstract void restoreHierarchyState(android.os.Bundle);
    method public abstract android.os.Bundle saveHierarchyState();
    method public void setAllowOverlappingEnterTransition(boolean);
    method public void setAllowOverlappingExitTransition(boolean);
    method public void setAttributes(android.view.WindowManager.LayoutParams);
    method public abstract void setBackgroundDrawable(android.graphics.drawable.Drawable);
    method public void setBackgroundDrawableResource(int);
@@ -30488,7 +30491,6 @@ package android.view {
    method public abstract void setTitle(java.lang.CharSequence);
    method public abstract deprecated void setTitleColor(int);
    method public void setTransitionManager(android.transition.TransitionManager);
    method public void setTriggerEarlyEnterTransition(boolean);
    method public void setType(int);
    method public void setUiOptions(int);
    method public void setUiOptions(int, int);
+46 −38
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.transition.Scene;
import android.transition.Transition;
import android.transition.TransitionManager;
import android.util.ArrayMap;
import android.util.Pair;
import android.util.SuperNotCalledException;
import android.widget.Toolbar;
import com.android.internal.app.WindowDecorActionBar;
@@ -774,7 +773,6 @@ public class Activity extends ContextThemeWrapper

    private Thread mUiThread;
    final Handler mHandler = new Handler();
    private ActivityOptions mTransitionActivityOptions;

    /** Return the intent that started this activity. */
    public Intent getIntent() {
@@ -1400,6 +1398,9 @@ public class Activity extends ContextThemeWrapper
    protected void onStop() {
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this);
        if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
        if (mWindow != null) {
            mWindow.restoreViewVisibilityAfterTransitionToCallee();
        }
        getApplication().dispatchActivityStopped(this);
        mTranslucentCallback = null;
        mCalled = true;
@@ -2300,7 +2301,7 @@ public class Activity extends ContextThemeWrapper
     */
    public void onBackPressed() {
        if (!mFragments.popBackStackImmediate()) {
            finish();
            finishWithTransition();
        }
    }

@@ -3483,8 +3484,7 @@ public class Activity extends ContextThemeWrapper
    public void startActivityForResult(Intent intent, int requestCode) {
        Bundle options = null;
        if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
            final Pair<View, String>[] noSharedElements = null;
            options = ActivityOptions.makeSceneTransitionAnimation(noSharedElements).toBundle();
            options = ActivityOptions.makeSceneTransitionAnimation().toBundle();
        }
        startActivityForResult(intent, requestCode, options);
    }
@@ -3532,7 +3532,7 @@ public class Activity extends ContextThemeWrapper
                    mActionBar.captureSharedElements(sharedElementMap);
                    activityOptions.addSharedElements(sharedElementMap);
                }
                options = mWindow.startExitTransition(activityOptions);
                options = mWindow.startExitTransitionToCallee(options);
            }
        }
        if (mParent == null) {
@@ -4386,6 +4386,23 @@ public class Activity extends ContextThemeWrapper
        finish();
    }

    /**
     * Reverses the Activity Scene entry Transition and triggers the calling Activity
     * to reverse its exit Transition. When the exit Transition completes,
     * {@link #finish()} is called. If no entry Transition was used, finish() is called
     * immediately and the Activity exit Transition is run.
     * @see android.view.Window#setTriggerEarlySceneTransition(boolean, boolean)
     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.view.View, String)
     */
    public void finishWithTransition() {
        mWindow.startExitTransitionToCaller(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        });
    }

    /**
     * Force finish another activity that you had previously started with
     * {@link #startActivityForResult}.
@@ -5396,13 +5413,8 @@ public class Activity extends ContextThemeWrapper
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
        mTransitionActivityOptions = null;
        Window.SceneTransitionListener sceneTransitionListener = null;
        if (options != null) {
            ActivityOptions activityOptions = new ActivityOptions(options);
            if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
                mTransitionActivityOptions = activityOptions;
                sceneTransitionListener = new Window.SceneTransitionListener() {
        Window.SceneTransitionListener sceneTransitionListener
                = new Window.SceneTransitionListener() {
            @Override
            public void nullPendingTransition() {
                overridePendingTransition(0, 0);
@@ -5428,11 +5440,7 @@ public class Activity extends ContextThemeWrapper
                Activity.this.onCaptureSharedElementEnd();
            }
        };

            }
        }

        mWindow.setTransitionOptions(mTransitionActivityOptions, sceneTransitionListener);
        mWindow.setTransitionOptions(options, sceneTransitionListener);
    }

    /** @hide */
+50 −33
Original line number Diff line number Diff line
@@ -20,8 +20,10 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.transition.Transition;
import android.util.Log;
import android.util.Pair;
@@ -136,6 +138,11 @@ public class ActivityOptions {
    /** @hide */
    public static final int ANIM_SCENE_TRANSITION = 5;

    private static final int MSG_SET_LISTENER = 100;
    private static final int MSG_HIDE_SHARED_ELEMENTS = 101;
    private static final int MSG_PREPARE_RESTORE = 102;
    private static final int MSG_RESTORE = 103;

    private String mPackageName;
    private int mAnimationType = ANIM_NONE;
    private int mCustomEnterResId;
@@ -146,7 +153,7 @@ public class ActivityOptions {
    private int mStartWidth;
    private int mStartHeight;
    private IRemoteCallback mAnimationStartedListener;
    private IRemoteCallback mTransitionCompleteListener;
    private ResultReceiver mTransitionCompleteListener;
    private ArrayList<String> mSharedElementNames;
    private ArrayList<String> mLocalElementNames;

@@ -428,8 +435,7 @@ public class ActivityOptions {
                break;

            case ANIM_SCENE_TRANSITION:
                mTransitionCompleteListener = IRemoteCallback.Stub.asInterface(
                        opts.getBinder(KEY_TRANSITION_COMPLETE_LISTENER));
                mTransitionCompleteListener = opts.getParcelable(KEY_TRANSITION_COMPLETE_LISTENER);
                mSharedElementNames = opts.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
                mLocalElementNames = opts.getStringArrayList(KEY_LOCAL_ELEMENT_NAMES);
                break;
@@ -495,7 +501,6 @@ public class ActivityOptions {
    /** @hide */
    public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target,
            ArrayList<String> sharedElementNames) {
        boolean listenerSent = false;
        if (mTransitionCompleteListener != null) {
            IRemoteCallback callback = new IRemoteCallback.Stub() {
                @Override
@@ -510,28 +515,29 @@ public class ActivityOptions {
            Bundle bundle = new Bundle();
            bundle.putBinder(KEY_TRANSITION_TARGET_LISTENER, callback.asBinder());
            bundle.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, sharedElementNames);
            try {
                mTransitionCompleteListener.sendResult(bundle);
                listenerSent = true;
            } catch (RemoteException e) {
                Log.w(TAG, "Couldn't retrieve transition notifications", e);
            mTransitionCompleteListener.send(MSG_SET_LISTENER, bundle);
        }
    }
        if (!listenerSent) {
            target.sharedElementTransitionComplete(null);
            target.exitTransitionComplete();

    /** @hide */
    public void dispatchSharedElementsReady() {
        if (mTransitionCompleteListener != null) {
            mTransitionCompleteListener.send(MSG_HIDE_SHARED_ELEMENTS, null);
        }
    }

    /** @hide */
    public void dispatchSharedElementsReady() {
    public void dispatchPrepareRestore() {
        if (mTransitionCompleteListener != null) {
            try {
                mTransitionCompleteListener.sendResult(null);
            } catch (RemoteException e) {
                Log.w(TAG, "Couldn't synchronize shared elements", e);
            mTransitionCompleteListener.send(MSG_PREPARE_RESTORE, null);
        }
    }

    /** @hide */
    public void dispatchRestore(Bundle sharedElementsArgs) {
        if (mTransitionCompleteListener != null) {
            mTransitionCompleteListener.send(MSG_RESTORE, sharedElementsArgs);
        }
    }

    /** @hide */
@@ -658,8 +664,7 @@ public class ActivityOptions {
            case ANIM_SCENE_TRANSITION:
                b.putInt(KEY_ANIM_TYPE, mAnimationType);
                if (mTransitionCompleteListener != null) {
                    b.putBinder(KEY_TRANSITION_COMPLETE_LISTENER,
                            mTransitionCompleteListener.asBinder());
                    b.putParcelable(KEY_TRANSITION_COMPLETE_LISTENER, mTransitionCompleteListener);
                }
                b.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, mSharedElementNames);
                b.putStringArrayList(KEY_LOCAL_ELEMENT_NAMES, mLocalElementNames);
@@ -710,9 +715,11 @@ public class ActivityOptions {
        Bundle getSharedElementExitState();
        void acceptedSharedElements(ArrayList<String> sharedElementNames);
        void hideSharedElements();
        void restore(Bundle sharedElementState);
        void prepareForRestore();
    }

    private static class ExitTransitionListener extends IRemoteCallback.Stub
    private static class ExitTransitionListener extends ResultReceiver
            implements Transition.TransitionListener {
        private boolean mSharedElementNotified;
        private Transition mExitTransition;
@@ -724,6 +731,7 @@ public class ActivityOptions {

        public ExitTransitionListener(Transition exitTransition, Transition sharedElementTransition,
                SharedElementSource sharedElementSource) {
            super(null);
            mSharedElementSource = sharedElementSource;
            mExitTransition = exitTransition;
            mExitTransition.addListener(this);
@@ -732,17 +740,26 @@ public class ActivityOptions {
        }

        @Override
        public void sendResult(Bundle data) throws RemoteException {
            if (data != null) {
                mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(
                        data.getBinder(KEY_TRANSITION_TARGET_LISTENER));
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            switch (resultCode) {
                case MSG_SET_LISTENER:
                    IBinder listener = resultData.getBinder(KEY_TRANSITION_TARGET_LISTENER);
                    mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(listener);
                    ArrayList<String> sharedElementNames
                        = data.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
                            = resultData.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
                    mSharedElementSource.acceptedSharedElements(sharedElementNames);
                    notifySharedElement();
                    notifyExit();
            } else {
                    break;
                case MSG_HIDE_SHARED_ELEMENTS:
                    mSharedElementSource.hideSharedElements();
                    break;
                case MSG_PREPARE_RESTORE:
                    mSharedElementSource.prepareForRestore();
                    break;
                case MSG_RESTORE:
                    mSharedElementSource.restore(resultData);
                    break;
            }
        }

+42 −13
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package android.view;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -1390,11 +1389,11 @@ public abstract class Window {
     * @param options Options to set or null for none
     * @hide
     */
    public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
    public void setTransitionOptions(Bundle options, SceneTransitionListener listener) {
    }

    /**
     * A callback for Activity transitions to be told when the shared element is ready to be shown
     * A callback for Window transitions to be told when the shared element is ready to be shown
     * and start the transition to its target location.
     * @hide
     */
@@ -1407,26 +1406,56 @@ public abstract class Window {
    }

    /**
     * Controls when the Activity enter scene is triggered and the background is faded in. If
     * triggerEarly is true, the enter scene will begin as soon as possible and the background
     * will fade in when all shared elements are ready to begin transitioning. If triggerEarly is
     * false, the Activity enter scene and background fade will be triggered when the calling
     * Activity's exit transition completes.
     *
     * @param triggerEarly Set to true to have the Activity enter scene transition in as early as
     *                     possible or set to false to wait for the calling Activity to exit first.
     * Controls how the Activity's start Scene is faded in and when the enter scene
     * is triggered to start.
     * <p>When allow is true, the enter Scene will begin as soon as possible
     * and the background will fade in when all shared elements are ready to begin
     * transitioning. If allow is false, the Activity enter Scene and
     * background fade will be triggered when the calling Activity's exit transition
     * completes.</p>
     * @param allow Set to true to have the Activity enter scene transition in
     *              as early as possible or set to false to wait for the calling
     *              Activity to exit first. The default value is true.
     */
    public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
    public void setAllowOverlappingEnterTransition(boolean allow) {
    }

    /**
     * Controls how the Activity's Scene fades out and when the calling Activity's
     * enter scene is triggered when finishing to return to a calling Activity.
     * <p>When allow is true, the Scene will fade out quickly
     * and inform the calling Activity to transition in when the fade completes.
     * When allow is false, the calling Activity will transition in after
     * the Activity's Scene has exited.
     * </p>
     * @param allow Set to true to have the Activity fade out as soon as possible
     *              and transition in the calling Activity. The default value is
     *              true.
     */
    public void setAllowOverlappingExitTransition(boolean allow) {
    }

    /**
     * Start the exit transition.
     * @hide
     */
    public Bundle startExitTransition(ActivityOptions options) {
    public Bundle startExitTransitionToCallee(Bundle options) {
        return null;
    }

    /**
     * Starts the transition back to the calling Activity.
     * onTransitionEnd will be called on the current thread if there is no exit transition.
     * @hide
     */
    public void startExitTransitionToCaller(Runnable onTransitionEnd) {
        onTransitionEnd.run();
    }

    /** @hide */
    public void restoreViewVisibilityAfterTransitionToCallee() {
    }

    /**
     * On entering Activity Scene transitions, shared element names may be mapped from a
     * source Activity's specified name to a unique shared element name in the View hierarchy.
+324 −96

File changed.

Preview size limit exceeded, changes collapsed.