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

Commit 3bfd2b7b authored by Craig Mautner's avatar Craig Mautner Committed by Android Git Automerger
Browse files

am 159da3db: Merge "Add enter-animation-done callback for system windows" into lmp-mr1-dev

* commit '159da3db':
  Add enter-animation-done callback for system windows
parents d93421b1 159da3db
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -85,4 +85,9 @@ oneway interface IWindow {
     * is done.
     */
    void doneAnimating();

    /**
     * Called for non-application windows when the enter animation has completed.
     */
    void dispatchWindowShown();
}
+22 −0
Original line number Diff line number Diff line
@@ -3089,6 +3089,7 @@ public final class ViewRootImpl implements ViewParent,
    private final static int MSG_INVALIDATE_WORLD = 23;
    private final static int MSG_WINDOW_MOVED = 24;
    private final static int MSG_SYNTHESIZE_INPUT_EVENT = 25;
    private final static int MSG_DISPATCH_WINDOW_SHOWN = 26;

    final class ViewRootHandler extends Handler {
        @Override
@@ -3138,6 +3139,8 @@ public final class ViewRootImpl implements ViewParent,
                    return "MSG_WINDOW_MOVED";
                case MSG_SYNTHESIZE_INPUT_EVENT:
                    return "MSG_SYNTHESIZE_INPUT_EVENT";
                case MSG_DISPATCH_WINDOW_SHOWN:
                    return "MSG_DISPATCH_WINDOW_SHOWN";
            }
            return super.getMessageName(message);
        }
@@ -3366,6 +3369,9 @@ public final class ViewRootImpl implements ViewParent,
                    invalidateWorld(mView);
                }
            } break;
            case MSG_DISPATCH_WINDOW_SHOWN: {
                handleDispatchWindowShown();
            }
            }
        }
    }
@@ -5212,6 +5218,10 @@ public final class ViewRootImpl implements ViewParent,
        }
    }

    public void handleDispatchWindowShown() {
        mAttachInfo.mTreeObserver.dispatchOnWindowShown();
    }

    public void getLastTouchPoint(Point outLocation) {
        outLocation.x = (int) mLastTouchPoint.x;
        outLocation.y = (int) mLastTouchPoint.y;
@@ -6072,6 +6082,10 @@ public final class ViewRootImpl implements ViewParent,
        mHandler.sendMessage(msg);
    }

    public void dispatchWindowShown() {
        mHandler.sendEmptyMessage(MSG_DISPATCH_WINDOW_SHOWN);
    }

    public void dispatchCloseSystemDialogs(String reason) {
        Message msg = Message.obtain();
        msg.what = MSG_CLOSE_SYSTEM_DIALOGS;
@@ -6582,6 +6596,14 @@ public final class ViewRootImpl implements ViewParent,
                viewAncestor.dispatchDoneAnimating();
            }
        }

        @Override
        public void dispatchWindowShown() {
            final ViewRootImpl viewAncestor = mViewAncestor.get();
            if (viewAncestor != null) {
                viewAncestor.dispatchWindowShown();
            }
        }
    }

    public static final class CalledFromWrongThreadException extends AndroidRuntimeException {
+86 −0
Original line number Diff line number Diff line
@@ -44,10 +44,15 @@ public final class ViewTreeObserver {
    private CopyOnWriteArray<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
    private CopyOnWriteArray<OnScrollChangedListener> mOnScrollChangedListeners;
    private CopyOnWriteArray<OnPreDrawListener> mOnPreDrawListeners;
    private CopyOnWriteArray<OnWindowShownListener> mOnWindowShownListeners;

    // These listeners cannot be mutated during dispatch
    private ArrayList<OnDrawListener> mOnDrawListeners;

    /** Remains false until #dispatchOnWindowShown() is called. If a listener registers after
     * that the listener will be immediately called. */
    private boolean mWindowShown;

    private boolean mAlive = true;

    /**
@@ -173,6 +178,19 @@ public final class ViewTreeObserver {
        public void onScrollChanged();
    }

    /**
     * Interface definition for a callback noting when a system window has been displayed.
     * This is only used for non-Activity windows. Activity windows can use
     * Activity.onEnterAnimationComplete() to get the same signal.
     * @hide
     */
    public interface OnWindowShownListener {
        /**
         * Callback method to be invoked when a non-activity window is fully shown.
         */
        void onWindowShown();
    }

    /**
     * Parameters used with OnComputeInternalInsetsListener.
     * 
@@ -375,6 +393,14 @@ public final class ViewTreeObserver {
            }
        }

        if (observer.mOnWindowShownListeners != null) {
            if (mOnWindowShownListeners != null) {
                mOnWindowShownListeners.addAll(observer.mOnWindowShownListeners);
            } else {
                mOnWindowShownListeners = observer.mOnWindowShownListeners;
            }
        }

        observer.kill();
    }

@@ -567,6 +593,45 @@ public final class ViewTreeObserver {
        mOnPreDrawListeners.remove(victim);
    }

    /**
     * Register a callback to be invoked when the view tree window has been shown
     *
     * @param listener The callback to add
     *
     * @throws IllegalStateException If {@link #isAlive()} returns false
     * @hide
     */
    public void addOnWindowShownListener(OnWindowShownListener listener) {
        checkIsAlive();

        if (mOnWindowShownListeners == null) {
            mOnWindowShownListeners = new CopyOnWriteArray<OnWindowShownListener>();
        }

        mOnWindowShownListeners.add(listener);
        if (mWindowShown) {
            listener.onWindowShown();
        }
    }

    /**
     * Remove a previously installed window shown callback
     *
     * @param victim The callback to remove
     *
     * @throws IllegalStateException If {@link #isAlive()} returns false
     *
     * @see #addOnWindowShownListener(OnWindowShownListener)
     * @hide
     */
    public void removeOnWindowShownListener(OnWindowShownListener victim) {
        checkIsAlive();
        if (mOnWindowShownListeners == null) {
            return;
        }
        mOnWindowShownListeners.remove(victim);
    }

    /**
     * <p>Register a callback to be invoked when the view tree is about to be drawn.</p>
     * <p><strong>Note:</strong> this method <strong>cannot</strong> be invoked from
@@ -853,6 +918,27 @@ public final class ViewTreeObserver {
        return cancelDraw;
    }

    /**
     * Notifies registered listeners that the window is now shown
     * @hide
     */
    @SuppressWarnings("unchecked")
    public final void dispatchOnWindowShown() {
        mWindowShown = true;
        final CopyOnWriteArray<OnWindowShownListener> listeners = mOnWindowShownListeners;
        if (listeners != null && listeners.size() > 0) {
            CopyOnWriteArray.Access<OnWindowShownListener> access = listeners.start();
            try {
                int count = access.size();
                for (int i = 0; i < count; i++) {
                    access.get(i).onWindowShown();
                }
            } finally {
                listeners.end();
            }
        }
    }

    /**
     * Notifies registered listeners that the drawing pass is about to start.
     */
+4 −0
Original line number Diff line number Diff line
@@ -102,4 +102,8 @@ public class BaseIWindow extends IWindow.Stub {
    @Override
    public void doneAnimating() {
    }

    @Override
    public void dispatchWindowShown() {
    }
}
+16 −21
Original line number Diff line number Diff line
@@ -17,17 +17,11 @@
package com.android.server.am;

import android.app.AlertDialog;
import android.app.Service;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Message;
import android.util.Slog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.TextView;

@@ -39,11 +33,10 @@ import com.android.internal.R;
 * in the background rather than just freeze the screen and not know if the user-switch affordance
 * was being handled.
 */
final class UserSwitchingDialog extends AlertDialog {
final class UserSwitchingDialog extends AlertDialog
        implements ViewTreeObserver.OnWindowShownListener {
    private static final String TAG = "ActivityManagerUserSwitchingDialog";

    private static final int MSG_START_USER = 1;

    private final ActivityManagerService mService;
    private final int mUserId;

@@ -74,19 +67,21 @@ final class UserSwitchingDialog extends AlertDialog {

    @Override
    public void show() {
        // Slog.v(TAG, "show called");
        super.show();
        // TODO: Instead of just an arbitrary delay, wait for a signal that the window was fully
        // displayed by the window manager
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_USER), 250);
        final View decorView = getWindow().getDecorView();
        if (decorView != null) {
            decorView.getViewTreeObserver().addOnWindowShownListener(this);
        }
    }

    private final Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_START_USER:
                    mService.startUserInForeground(mUserId, UserSwitchingDialog.this);
                    break;
    @Override
    public void onWindowShown() {
        // Slog.v(TAG, "onWindowShown called");
        mService.startUserInForeground(mUserId, this);
        final View decorView = getWindow().getDecorView();
        if (decorView != null) {
            decorView.getViewTreeObserver().removeOnWindowShownListener(this);
        }
    }
    };
}
Loading