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

Commit fd10cd19 authored by Robert Carr's avatar Robert Carr
Browse files

Force CROSSFADE rotation when launching from double tap gesture.

When activity transition triggers a rotation change, the starting
window will normally be the top window at the time we try
to select the window animation. However, these layout params won't
have the apps rotation animation set (as the client code will set that
on the real window, not the starting window). Eventually we would
like to add API to specify rotation animation via manifest to solve
this problem cleanly. In the mean time, we can force a specific rotation
animation from the double tap gesture, and clean up some camera
ugliness. We accomplish this by attaching an animation hint to
ActivityOptions.

Bug: 28838855
Change-Id: If052cd8cbae76651da43f3b4c590cd9dcc1afc0f
parent ef5c3aad
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ public class ActivityOptions {
            = "android:activity.exitCoordinatorIndex";

    private static final String KEY_USAGE_TIME_REPORT = "android:activity.usageTimeReport";
    private static final String KEY_ROTATION_ANIMATION_HINT = "android:activity.rotationAnimationHint";

    /** @hide */
    public static final int ANIM_NONE = 0;
@@ -244,6 +245,7 @@ public class ActivityOptions {
    private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
    private boolean mTaskOverlay;
    private AppTransitionAnimationSpec mAnimSpecs[];
    private int mRotationAnimationHint = -1;

    /**
     * Create an ActivityOptions specifying a custom animation to run when
@@ -863,6 +865,7 @@ public class ActivityOptions {
            mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
                    opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
        }
        mRotationAnimationHint = opts.getInt(KEY_ROTATION_ANIMATION_HINT);
    }

    /**
@@ -1216,6 +1219,7 @@ public class ActivityOptions {
        if (mAnimationFinishedListener != null) {
            b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
        }
        b.putInt(KEY_ROTATION_ANIMATION_HINT, mRotationAnimationHint);

        return b;
    }
@@ -1262,6 +1266,27 @@ public class ActivityOptions {
        return null;
    }

    /**
     * Returns the rotation animation set by {@link setRotationAnimationHint} or -1
     * if unspecified.
     * @hide
     */
    public int getRotationAnimationHint() {
        return mRotationAnimationHint;
    }


    /**
     * Set a rotation animation to be used if launching the activity
     * triggers an orientation change, or -1 to clear. See
     * {@link android.view.WindowManager.LayoutParams} for rotation
     * animation values.
     * @hide
     */
    public void setRotationAnimationHint(int hint) {
        mRotationAnimationHint = hint;
    }

    /** @hide */
    @Override
    public String toString() {
+1 −1
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ interface IWindowManager
            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
            int configChanges, boolean voiceInteraction, boolean launchTaskBehind,
            in Rect taskBounds, in Configuration configuration, int taskResizeMode,
            boolean alwaysFocusable, boolean homeTask, int targetSdkVersion);
            boolean alwaysFocusable, boolean homeTask, int targetSdkVersion, int rotationAnimationHint);
    /**
     *
     * @param token The token we are adding to the input task Id.
+2 −0
Original line number Diff line number Diff line
@@ -416,6 +416,8 @@ public interface WindowManagerPolicy {
         * screen with other application windows.
         */
        public boolean isInMultiWindowMode();

        public int getRotationAnimationHint();
    }

    /**
+15 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone;

import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -44,6 +45,7 @@ import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.TextView;
@@ -448,12 +450,24 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
                @Override
                public void run() {
                    int result = ActivityManager.START_CANCELED;

                    // Normally an activity will set it's requested rotation
                    // animation on its window. However when launching an activity
                    // causes the orientation to change this is too late. In these cases
                    // the default animation is used. This doesn't look good for
                    // the camera (as it rotates the camera contents out of sync
                    // with physical reality). So, we ask the WindowManager to
                    // force the crossfade animation if an orientation change
                    // happens to occur during the launch.
                    ActivityOptions o = ActivityOptions.makeBasic();
                    o.setRotationAnimationHint(
                            WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE);
                    try {
                        result = ActivityManagerNative.getDefault().startActivityAsUser(
                                null, getContext().getBasePackageName(),
                                intent,
                                intent.resolveTypeIfNeeded(getContext().getContentResolver()),
                                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
                                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, o.toBundle(),
                                UserHandle.CURRENT.getIdentifier());
                    } catch (RemoteException e) {
                        Log.w(TAG, "Unable to start camera activity", e);
+15 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
@@ -3322,13 +3323,26 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
                intent.setFlags(
                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                int result = ActivityManager.START_CANCELED;
                ActivityOptions options = new ActivityOptions(getActivityOptions());
                if (intent == KeyguardBottomAreaView.INSECURE_CAMERA_INTENT) {
                    // Normally an activity will set it's requested rotation
                    // animation on its window. However when launching an activity
                    // causes the orientation to change this is too late. In these cases
                    // the default animation is used. This doesn't look good for
                    // the camera (as it rotates the camera contents out of sync
                    // with physical reality). So, we ask the WindowManager to
                    // force the crossfade animation if an orientation change
                    // happens to occur during the launch.
                    options.setRotationAnimationHint(
                            WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE);
                }
                try {
                    result = ActivityManagerNative.getDefault().startActivityAsUser(
                            null, mContext.getBasePackageName(),
                            intent,
                            intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                            null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
                            getActivityOptions(), UserHandle.CURRENT.getIdentifier());
                            options.toBundle(), UserHandle.CURRENT.getIdentifier());
                } catch (RemoteException e) {
                    Log.w(TAG, "Unable to start activity", e);
                }
Loading