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

Commit 77ba4803 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Add AppTransitionListener

Introduces the concept of a listener to be notified about app
transition events. The only client at the moment is window manager
which notifies activity manager about completed transitions, but this
can be used for various clients, including the status bar.

Bug: 19233606
Change-Id: Ia6fec5837b6eb4db90f3cb1c999d3f157ba6dd4a
parent 3ef69833
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.display.DisplayManagerInternal;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.view.animation.Animation;

import java.util.List;

@@ -84,6 +84,41 @@ public abstract class WindowManagerInternal {
        public void onUserContextChanged();
    }

    /**
     * Abstract class to be notified about {@link com.android.server.wm.AppTransition} events. Held
     * as an abstract class so a listener only needs to implement the methods of its interest.
     */
    public static abstract class AppTransitionListener {

        /**
         * Called when an app transition is being setup and about to be executed.
         */
        public void onAppTransitionPendingLocked() {}

        /**
         * Called when a pending app transition gets cancelled.
         */
        public void onAppTransitionCancelledLocked() {}

        /**
         * Called when an app transition gets started
         *
         * @param openToken the token for the opening app
         * @param closeToken the token for the closing app
         * @param openAnimation the animation for the opening app
         * @param closeAnimation the animation for the closing app
         */
        public void onAppTransitionStartingLocked(IBinder openToken, IBinder closeToken,
                Animation openAnimation, Animation closeAnimation) {}

        /**
         * Called when an app transition is finished running.
         *
         * @param token the token for app whose transition has finished
         */
        public void onAppTransitionFinishedLocked(IBinder token) {}
    }

    /**
     * Request that the window manager call
     * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager}
+44 −5
Original line number Diff line number Diff line
@@ -17,16 +17,13 @@
package com.android.server.wm;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
@@ -47,7 +44,9 @@ import com.android.server.AttributeCache;
import com.android.server.wm.WindowManagerService.H;

import java.io.PrintWriter;
import java.util.ArrayList;

import static android.view.WindowManagerInternal.AppTransitionListener;
import static com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation;
import static com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation;
import static com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation;
@@ -185,6 +184,8 @@ public class AppTransition implements Dump {

    private int mCurrentUserId = 0;

    private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>();

    AppTransition(Context context, Handler h) {
        mContext = context;
        mH = h;
@@ -291,12 +292,18 @@ public class AppTransition implements Dump {
    void prepare() {
        if (!isRunning()) {
            mAppTransitionState = APP_STATE_IDLE;
            notifyAppTransitionPendingLocked();
        }
    }

    void goodToGo() {
    void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) {
        mNextAppTransition = TRANSIT_UNSET;
        mAppTransitionState = APP_STATE_RUNNING;
        notifyAppTransitionStartingLocked(
                openingAppAnimator != null ? openingAppAnimator.mAppToken.token : null,
                closingAppAnimator != null ? closingAppAnimator.mAppToken.token : null,
                openingAppAnimator != null ? openingAppAnimator.animation : null,
                closingAppAnimator != null ? closingAppAnimator.animation : null);
    }

    void clear() {
@@ -309,6 +316,38 @@ public class AppTransition implements Dump {
        setAppTransition(AppTransition.TRANSIT_UNSET);
        clear();
        setReady();
        notifyAppTransitionCancelledLocked();
    }

    void registerListenerLocked(AppTransitionListener listener) {
        mListeners.add(listener);
    }

    public void notifyAppTransitionFinishedLocked(AppWindowAnimator animator) {
        IBinder token = animator != null ? animator.mAppToken.token : null;
        for (int i = 0; i < mListeners.size(); i++) {
            mListeners.get(i).onAppTransitionFinishedLocked(token);
        }
    }

    private void notifyAppTransitionPendingLocked() {
        for (int i = 0; i < mListeners.size(); i++) {
            mListeners.get(i).onAppTransitionPendingLocked();
        }
    }

    private void notifyAppTransitionCancelledLocked() {
        for (int i = 0; i < mListeners.size(); i++) {
            mListeners.get(i).onAppTransitionCancelledLocked();
        }
    }

    private void notifyAppTransitionStartingLocked(IBinder openToken,
            IBinder closeToken, Animation openAnimation, Animation closeAnimation) {
        for (int i = 0; i < mListeners.size(); i++) {
            mListeners.get(i).onAppTransitionStartingLocked(openToken, closeToken, openAnimation,
                    closeAnimation);
        }
    }

    private AttributeCache.Entry getCachedAnimations(WindowManager.LayoutParams lp) {
+1 −18
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.wm;

import android.graphics.Matrix;
import android.os.RemoteException;
import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;
@@ -312,23 +311,7 @@ public class AppWindowAnimator {
        for (int i = 0; i < numAllAppWinAnimators; i++) {
            mAllAppWinAnimators.get(i).finishExit();
        }
        if (mAppToken.mLaunchTaskBehind) {
            try {
                mService.mActivityManager.notifyLaunchTaskBehindComplete(mAppToken.token);
            } catch (RemoteException e) {
            }
            mAppToken.mLaunchTaskBehind = false;
        } else {
            mAppToken.updateReportedVisibilityLocked();
            if (mAppToken.mEnteringAnimation) {
                mAppToken.mEnteringAnimation = false;
                try {
                    mService.mActivityManager.notifyEnterAnimationComplete(mAppToken.token);
                } catch (RemoteException e) {
                }
            }
        }

        mService.mAppTransition.notifyAppTransitionFinishedLocked(this);
        return false;
    }

+31 −1
Original line number Diff line number Diff line
@@ -779,6 +779,35 @@ public class WindowManagerService extends IWindowManager.Stub
    // For example, when this flag is true, there will be no wallpaper service.
    final boolean mOnlyCore;

    /** Listener to notify activity manager about app transitions. */
    private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
            = new WindowManagerInternal.AppTransitionListener() {

        @Override
        public void onAppTransitionFinishedLocked(IBinder token) {
            AppWindowToken atoken = findAppWindowToken(token);
            if (atoken == null) {
                return;
            }
            if (atoken.mLaunchTaskBehind) {
                try {
                    mActivityManager.notifyLaunchTaskBehindComplete(atoken.token);
                } catch (RemoteException e) {
                }
                atoken.mLaunchTaskBehind = false;
            } else {
                atoken.updateReportedVisibilityLocked();
                if (atoken.mEnteringAnimation) {
                    atoken.mEnteringAnimation = false;
                    try {
                        mActivityManager.notifyEnterAnimationComplete(atoken.token);
                    } catch (RemoteException e) {
                    }
                }
            }
        }
    };

    public static WindowManagerService main(final Context context,
            final InputManagerService im,
            final boolean haveInputMethods, final boolean showBootMsgs,
@@ -855,6 +884,7 @@ public class WindowManagerService extends IWindowManager.Stub
        mScreenFrozenLock.setReferenceCounted(false);

        mAppTransition = new AppTransition(context, mH);
        mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);

        mActivityManager = ActivityManagerNative.getDefault();
        mBatteryStats = BatteryStatsService.getService();
@@ -8873,7 +8903,6 @@ public class WindowManagerService extends IWindowManager.Stub
            if (mSkipAppTransitionAnimation) {
                transit = AppTransition.TRANSIT_UNSET;
            }
            mAppTransition.goodToGo();
            mStartingIconInTransition = false;
            mSkipAppTransitionAnimation = false;

@@ -9168,6 +9197,7 @@ public class WindowManagerService extends IWindowManager.Stub
                }
            }

            mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
            mAppTransition.postAnimationCallback();
            mAppTransition.clear();