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

Commit f84e2f60 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Add ability to register remote animation definitions per activity

This introduces a more stable way of setting a remote animation
than using overridePendingTransition: An activity can register
a set of remote animations which is broke down by transition type.
Whenever the activity is involved into such a transition, the
remote animation will be started.

Remote animations take precedence over regular animations, and
prefixOrderIndex in the hierarchy decides precedence within
multiple apps that set remote animation definitions such that
higher apps override lower apps.

Bug: 64674361
Test: go/wm-smoke
Test: Use with launcher
Change-Id: Id300ff62d9f60966ea2609168f6a02860b3de7af
parent 99dbbf93
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static java.lang.Character.MIN_VALUE;

import android.annotation.CallSuper;
@@ -98,6 +99,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.RemoteAnimationDefinition;
import android.view.SearchEvent;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
@@ -7659,6 +7661,22 @@ public class Activity extends ContextThemeWrapper
        }
    }

    /**
     * Registers remote animations per transition type for this activity.
     *
     * @param definition The remote animation definition that defines which transition whould run
     *                   which remote animation.
     * @hide
     */
    @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS)
    public void registerRemoteAnimations(RemoteAnimationDefinition definition) {
        try {
            ActivityManager.getService().registerRemoteAnimations(mToken, definition);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to call registerRemoteAnimations", e);
        }
    }

    class HostCallbacks extends FragmentHostCallback<Activity> {
        public HostCallbacks() {
            super(Activity.this /*activity*/);
+6 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ import android.os.PersistableBundle;
import android.os.StrictMode;
import android.os.WorkSource;
import android.service.voice.IVoiceInteractionSession;
import android.view.RemoteAnimationDefinition;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
@@ -672,4 +673,9 @@ interface IActivityManager {
      *  user unlock progress.
      */
     boolean startUserInBackgroundWithListener(int userid, IProgressListener unlockProgressListener);

     /**
      * Registers remote animations for a specific activity.
      */
     void registerRemoteAnimations(in IBinder token, in RemoteAnimationDefinition definition);
}
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.view;

parcelable RemoteAnimationDefinition;
+93 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.view;

import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.util.SparseArray;
import android.view.WindowManager.TransitionType;

/**
 * Defines which animation types should be overridden by which remote animation.
 *
 * @hide
 */
public class RemoteAnimationDefinition implements Parcelable {

    private final SparseArray<RemoteAnimationAdapter> mTransitionAnimationMap;

    public RemoteAnimationDefinition() {
        mTransitionAnimationMap = new SparseArray<>();
    }

    /**
     * Registers a remote animation for a specific transition.
     *
     * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
     * @param adapter The adapter that described how to run the remote animation.
     */
    public void addRemoteAnimation(@TransitionType int transition, RemoteAnimationAdapter adapter) {
        mTransitionAnimationMap.put(transition, adapter);
    }

    /**
     * Checks whether a remote animation for specific transition is defined.
     *
     * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
     * @return Whether this definition has defined a remote animation for the specified transition.
     */
    public boolean hasTransition(@TransitionType int transition) {
        return mTransitionAnimationMap.get(transition) != null;
    }

    /**
     * Retrieves the remote animation for a specific transition.
     *
     * @param transition The transition type. Must be one of WindowManager.TRANSIT_* values.
     * @return The remote animation adapter for the specified transition.
     */
    public @Nullable RemoteAnimationAdapter getAdapter(@TransitionType int transition) {
        return mTransitionAnimationMap.get(transition);
    }

    public RemoteAnimationDefinition(Parcel in) {
        mTransitionAnimationMap = in.readSparseArray(null /* loader */);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeSparseArray((SparseArray) mTransitionAnimationMap);
    }

    public static final Creator<RemoteAnimationDefinition> CREATOR =
            new Creator<RemoteAnimationDefinition>() {
        public RemoteAnimationDefinition createFromParcel(Parcel in) {
            return new RemoteAnimationDefinition(in);
        }

        public RemoteAnimationDefinition[] newArray(int size) {
            return new RemoteAnimationDefinition[size];
        }
    };
}
+185 −0
Original line number Diff line number Diff line
@@ -104,6 +104,191 @@ public interface WindowManager extends ViewManager {
    /** @hide */
    final static String INPUT_CONSUMER_WALLPAPER = "wallpaper_input_consumer";

    /**
     * Not set up for a transition.
     * @hide
     */
    int TRANSIT_UNSET = -1;

    /**
     * No animation for transition.
     * @hide
     */
    int TRANSIT_NONE = 0;

    /**
     * A window in a new activity is being opened on top of an existing one in the same task.
     * @hide
     */
    int TRANSIT_ACTIVITY_OPEN = 6;

    /**
     * The window in the top-most activity is being closed to reveal the previous activity in the
     * same task.
     * @hide
     */
    int TRANSIT_ACTIVITY_CLOSE = 7;

    /**
     * A window in a new task is being opened on top of an existing one in another activity's task.
     * @hide
     */
    int TRANSIT_TASK_OPEN = 8;

    /**
     * A window in the top-most activity is being closed to reveal the previous activity in a
     * different task.
     * @hide
     */
    int TRANSIT_TASK_CLOSE = 9;

    /**
     * A window in an existing task is being displayed on top of an existing one in another
     * activity's task.
     * @hide
     */
    int TRANSIT_TASK_TO_FRONT = 10;

    /**
     * A window in an existing task is being put below all other tasks.
     * @hide
     */
    int TRANSIT_TASK_TO_BACK = 11;

    /**
     * A window in a new activity that doesn't have a wallpaper is being opened on top of one that
     * does, effectively closing the wallpaper.
     * @hide
     */
    int TRANSIT_WALLPAPER_CLOSE = 12;

    /**
     * A window in a new activity that does have a wallpaper is being opened on one that didn't,
     * effectively opening the wallpaper.
     * @hide
     */
    int TRANSIT_WALLPAPER_OPEN = 13;

    /**
     * A window in a new activity is being opened on top of an existing one, and both are on top
     * of the wallpaper.
     * @hide
     */
    int TRANSIT_WALLPAPER_INTRA_OPEN = 14;

    /**
     * The window in the top-most activity is being closed to reveal the previous activity, and
     * both are on top of the wallpaper.
     * @hide
     */
    int TRANSIT_WALLPAPER_INTRA_CLOSE = 15;

    /**
     * A window in a new task is being opened behind an existing one in another activity's task.
     * The new window will show briefly and then be gone.
     * @hide
     */
    int TRANSIT_TASK_OPEN_BEHIND = 16;

    /**
     * A window in a task is being animated in-place.
     * @hide
     */
    int TRANSIT_TASK_IN_PLACE = 17;

    /**
     * An activity is being relaunched (e.g. due to configuration change).
     * @hide
     */
    int TRANSIT_ACTIVITY_RELAUNCH = 18;

    /**
     * A task is being docked from recents.
     * @hide
     */
    int TRANSIT_DOCK_TASK_FROM_RECENTS = 19;

    /**
     * Keyguard is going away.
     * @hide
     */
    int TRANSIT_KEYGUARD_GOING_AWAY = 20;

    /**
     * Keyguard is going away with showing an activity behind that requests wallpaper.
     * @hide
     */
    int TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;

    /**
     * Keyguard is being occluded.
     * @hide
     */
    int TRANSIT_KEYGUARD_OCCLUDE = 22;

    /**
     * Keyguard is being unoccluded.
     * @hide
     */
    int TRANSIT_KEYGUARD_UNOCCLUDE = 23;

    /**
     * @hide
     */
    @IntDef(prefix = { "TRANSIT_" }, value = {
            TRANSIT_UNSET,
            TRANSIT_NONE,
            TRANSIT_ACTIVITY_OPEN,
            TRANSIT_ACTIVITY_CLOSE,
            TRANSIT_TASK_OPEN,
            TRANSIT_TASK_CLOSE,
            TRANSIT_TASK_TO_FRONT,
            TRANSIT_TASK_TO_BACK,
            TRANSIT_WALLPAPER_CLOSE,
            TRANSIT_WALLPAPER_OPEN,
            TRANSIT_WALLPAPER_INTRA_OPEN,
            TRANSIT_WALLPAPER_INTRA_CLOSE,
            TRANSIT_TASK_OPEN_BEHIND,
            TRANSIT_TASK_IN_PLACE,
            TRANSIT_ACTIVITY_RELAUNCH,
            TRANSIT_DOCK_TASK_FROM_RECENTS,
            TRANSIT_KEYGUARD_GOING_AWAY,
            TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
            TRANSIT_KEYGUARD_OCCLUDE,
            TRANSIT_KEYGUARD_UNOCCLUDE
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface TransitionType {}

    /**
     * Transition flag: Keyguard is going away, but keeping the notification shade open
     * @hide
     */
    int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE = 0x1;

    /**
     * Transition flag: Keyguard is going away, but doesn't want an animation for it
     * @hide
     */
    int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION = 0x2;

    /**
     * Transition flag: Keyguard is going away while it was showing the system wallpaper.
     * @hide
     */
    int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER = 0x4;

    /**
     * @hide
     */
    @IntDef(flag = true, prefix = { "TRANSIT_FLAG_" }, value = {
            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE,
            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION,
            TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface TransitionFlags {}

    /**
     * Exception that is thrown when trying to add view whose
     * {@link LayoutParams} {@link LayoutParams#token}
Loading