/*
 * Copyright (C) 2016 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 com.android.server.wm;

import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static android.view.WindowManager.TRANSIT_UNSET;

import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.app.ActivityManager.TaskSnapshot;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Slog;
import android.view.IApplicationToken;
import android.view.RemoteAnimationDefinition;
import android.view.WindowManager;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.AttributeCache;
import com.android.server.policy.WindowManagerPolicy.StartingSurface;

/**
 * Controller for the app window token container. This is created by activity manager to link
 * activity records to the app window token container they use in window manager.
 *
 * Test class: {@link AppWindowContainerControllerTests}
 */
public class AppWindowContainerController
        extends WindowContainerController<AppWindowToken, AppWindowContainerListener> {

    private static final int STARTING_WINDOW_TYPE_NONE = 0;
    private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
    private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;

    private final IApplicationToken mToken;
    private final Handler mHandler;

    private final class H extends Handler {
        public static final int NOTIFY_WINDOWS_DRAWN = 1;
        public static final int NOTIFY_STARTING_WINDOW_DRAWN = 2;
        public static final int NOTIFY_WINDOWS_NOTDRAWN = 3;

        public H(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case NOTIFY_WINDOWS_DRAWN:
                    if (mListener == null) {
                        return;
                    }
                    if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting drawn in "
                            + AppWindowContainerController.this.mToken);
                    mListener.onWindowsDrawn(msg.getWhen());
                    break;
                case NOTIFY_STARTING_WINDOW_DRAWN:
                    if (mListener == null) {
                        return;
                    }
                    if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting starting window drawn in "
                            + AppWindowContainerController.this.mToken);
                    mListener.onStartingWindowDrawn(msg.getWhen());
                    break;
                case NOTIFY_WINDOWS_NOTDRAWN:
                    if (mListener == null) {
                        return;
                    }
                    if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting undrawn in "
                            + AppWindowContainerController.this.mToken);
                    mListener.onWindowsNotDrawn(msg.getWhen());
                    break;
                default:
                    break;
            }
        }
    }

    private final Runnable mOnWindowsVisible = () -> {
        if (mListener == null) {
            return;
        }
        if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting visible in "
                + AppWindowContainerController.this.mToken);
        mListener.onWindowsVisible();
    };

    private final Runnable mOnWindowsGone = () -> {
        if (mListener == null) {
            return;
        }
        if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting gone in "
                + AppWindowContainerController.this.mToken);
        mListener.onWindowsGone();
    };

    private final Runnable mAddStartingWindow = new Runnable() {

        @Override
        public void run() {
            final StartingData startingData;
            final AppWindowToken container;

            synchronized (mWindowMap) {
                if (mContainer == null) {
                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
                            + " add starting window");
                    return;
                }

                // There can only be one adding request, silly caller!
                mService.mAnimationHandler.removeCallbacks(this);

                startingData = mContainer.startingData;
                container = mContainer;
            }

            if (startingData == null) {
                // Animation has been canceled... do nothing.
                if (DEBUG_STARTING_WINDOW)
                    Slog.v(TAG_WM, "startingData was nulled out before handling"
                            + " mAddStartingWindow: " + mContainer);
                return;
            }

            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting "
                    + AppWindowContainerController.this + ": startingData="
                    + container.startingData);

            StartingSurface surface = null;
            try {
                surface = startingData.createStartingSurface(container);
            } catch (Exception e) {
                Slog.w(TAG_WM, "Exception when adding starting window", e);
            }
            if (surface != null) {
                boolean abort = false;
                synchronized (mWindowMap) {
                    // If the window was successfully added, then
                    // we need to remove it.
                    if (container.removed || container.startingData == null) {
                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                                "Aborted starting " + container
                                        + ": removed=" + container.removed
                                        + " startingData=" + container.startingData);
                        container.startingWindow = null;
                        container.startingData = null;
                        abort = true;
                    } else {
                        container.startingSurface = surface;
                    }
                    if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM,
                            "Added starting " + mContainer
                                    + ": startingWindow="
                                    + container.startingWindow + " startingView="
                                    + container.startingSurface);
                }
                if (abort) {
                    surface.remove();
                }
            } else if (DEBUG_STARTING_WINDOW) {
                Slog.v(TAG_WM, "Surface returned was null: " + mContainer);
            }
        }
    };

    public AppWindowContainerController(TaskWindowContainerController taskController,
            IApplicationToken token, AppWindowContainerListener listener, int index,
            int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
            boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
            int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos) {
        this(taskController, token, listener, index, requestedOrientation, fullscreen,
                showForAllUsers,
                configChanges, voiceInteraction, launchTaskBehind, alwaysFocusable,
                targetSdkVersion, rotationAnimationHint, inputDispatchingTimeoutNanos,
                WindowManagerService.getInstance());
    }

    public AppWindowContainerController(TaskWindowContainerController taskController,
            IApplicationToken token, AppWindowContainerListener listener, int index,
            int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
            boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
            int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
            WindowManagerService service) {
        super(listener, service);
        mHandler = new H(service.mH.getLooper());
        mToken = token;
        synchronized(mWindowMap) {
            AppWindowToken atoken = mRoot.getAppWindowToken(mToken.asBinder());
            if (atoken != null) {
                // TODO: Should this throw an exception instead?
                Slog.w(TAG_WM, "Attempted to add existing app token: " + mToken);
                return;
            }

            final Task task = taskController.mContainer;
            if (task == null) {
                throw new IllegalArgumentException("AppWindowContainerController: invalid "
                        + " controller=" + taskController);
            }

            atoken = createAppWindow(mService, token, voiceInteraction, task.getDisplayContent(),
                    inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
                    requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
                    alwaysFocusable, this);
            if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
                    + " controller=" + taskController + " at " + index);
            task.addChild(atoken, index);
        }
    }

    @VisibleForTesting
    AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
            boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
            boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
            int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
            boolean alwaysFocusable, AppWindowContainerController controller) {
        return new AppWindowToken(service, token, voiceInteraction, dc,
                inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
                rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
                controller);
    }

    public void removeContainer(int displayId) {
        synchronized(mWindowMap) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            if (dc == null) {
                Slog.w(TAG_WM, "removeAppToken: Attempted to remove binder token: "
                        + mToken + " from non-existing displayId=" + displayId);
                return;
            }
            dc.removeAppToken(mToken.asBinder());
            super.removeContainer();
        }
    }

    @Override
    public void removeContainer() {
        throw new UnsupportedOperationException("Use removeContainer(displayId) instead.");
    }

    public void reparent(TaskWindowContainerController taskController, int position) {
        synchronized (mWindowMap) {
            if (DEBUG_ADD_REMOVE) Slog.i(TAG_WM, "reparent: moving app token=" + mToken
                    + " to task=" + taskController + " at " + position);
            if (mContainer == null) {
                if (DEBUG_ADD_REMOVE) Slog.i(TAG_WM,
                        "reparent: could not find app token=" + mToken);
                return;
            }
            final Task task = taskController.mContainer;
            if (task == null) {
                throw new IllegalArgumentException("reparent: could not find task="
                        + taskController);
            }
            mContainer.reparent(task, position);
            mContainer.getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
        }
    }

    public Configuration setOrientation(int requestedOrientation, int displayId,
            Configuration displayConfig, boolean freezeScreenIfNeeded) {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM,
                        "Attempted to set orientation of non-existing app token: " + mToken);
                return null;
            }

            mContainer.setOrientation(requestedOrientation);

            final IBinder binder = freezeScreenIfNeeded ? mToken.asBinder() : null;
            return mService.updateOrientationFromAppTokens(displayConfig, binder, displayId);

        }
    }

    public int getOrientation() {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                return SCREEN_ORIENTATION_UNSPECIFIED;
            }

            return mContainer.getOrientationIgnoreVisibility();
        }
    }

    public void setDisablePreviewScreenshots(boolean disable) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to set disable screenshots of non-existing app"
                        + " token: " + mToken);
                return;
            }
            mContainer.setDisablePreviewScreenshots(disable);
        }
    }

    public void setVisibility(boolean visible, boolean deferHidingClient) {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: "
                        + mToken);
                return;
            }

            final AppWindowToken wtoken = mContainer;

            // Don't set visibility to false if we were already not visible. This prevents WM from
            // adding the app to the closing app list which doesn't make sense for something that is
            // already not visible. However, set visibility to true even if we are already visible.
            // This makes sure the app is added to the opening apps list so that the right
            // transition can be selected.
            // TODO: Probably a good idea to separate the concept of opening/closing apps from the
            // concept of setting visibility...
            if (!visible && wtoken.hiddenRequested) {

                if (!deferHidingClient && wtoken.mDeferHidingClient) {
                    // We previously deferred telling the client to hide itself when visibility was
                    // initially set to false. Now we would like it to hide, so go ahead and set it.
                    wtoken.mDeferHidingClient = deferHidingClient;
                    wtoken.setClientHidden(true);
                }
                return;
            }

            if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG_WM, "setAppVisibility("
                    + mToken + ", visible=" + visible + "): " + mService.mAppTransition
                    + " hidden=" + wtoken.isHidden() + " hiddenRequested="
                    + wtoken.hiddenRequested + " Callers=" + Debug.getCallers(6));

            mService.mOpeningApps.remove(wtoken);
            mService.mClosingApps.remove(wtoken);
            wtoken.waitingToShow = false;
            wtoken.hiddenRequested = !visible;
            wtoken.mDeferHidingClient = deferHidingClient;

            if (!visible) {
                // If the app is dead while it was visible, we kept its dead window on screen.
                // Now that the app is going invisible, we can remove it. It will be restarted
                // if made visible again.
                wtoken.removeDeadWindows();
            } else {
                if (!mService.mAppTransition.isTransitionSet()
                        && mService.mAppTransition.isReady()) {
                    // Add the app mOpeningApps if transition is unset but ready. This means
                    // we're doing a screen freeze, and the unfreeze will wait for all opening
                    // apps to be ready.
                    mService.mOpeningApps.add(wtoken);
                }
                wtoken.startingMoved = false;
                // If the token is currently hidden (should be the common case), or has been
                // stopped, then we need to set up to wait for its windows to be ready.
                if (wtoken.isHidden() || wtoken.mAppStopped) {
                    wtoken.clearAllDrawn();

                    // If the app was already visible, don't reset the waitingToShow state.
                    if (wtoken.isHidden()) {
                        wtoken.waitingToShow = true;
                    }
                }

                // In the case where we are making an app visible but holding off for a transition,
                // we still need to tell the client to make its windows visible so they get drawn.
                // Otherwise, we will wait on performing the transition until all windows have been
                // drawn, they never will be, and we are sad.
                wtoken.setClientHidden(false);

                wtoken.requestUpdateWallpaperIfNeeded();

                if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "No longer Stopped: " + wtoken);
                wtoken.mAppStopped = false;

                mContainer.transferStartingWindowFromHiddenAboveTokenIfNeeded();
            }

            // If we are preparing an app transition, then delay changing
            // the visibility of this token until we execute that transition.
            if (wtoken.okToAnimate() && mService.mAppTransition.isTransitionSet()) {
                wtoken.inPendingTransaction = true;
                if (visible) {
                    mService.mOpeningApps.add(wtoken);
                    wtoken.mEnteringAnimation = true;
                } else {
                    mService.mClosingApps.add(wtoken);
                    wtoken.mEnteringAnimation = false;
                }
                if (mService.mAppTransition.getAppTransition()
                        == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
                    // We're launchingBehind, add the launching activity to mOpeningApps.
                    final WindowState win =
                            mService.getDefaultDisplayContentLocked().findFocusedWindow();
                    if (win != null) {
                        final AppWindowToken focusedToken = win.mAppToken;
                        if (focusedToken != null) {
                            if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "TRANSIT_TASK_OPEN_BEHIND, "
                                    + " adding " + focusedToken + " to mOpeningApps");
                            // Force animation to be loaded.
                            focusedToken.setHidden(true);
                            mService.mOpeningApps.add(focusedToken);
                        }
                    }
                }
                return;
            }

            wtoken.setVisibility(null, visible, TRANSIT_UNSET, true, wtoken.mVoiceInteraction);
            wtoken.updateReportedVisibilityLocked();
        }
    }

    /**
     * Notifies that we launched an app that might be visible or not visible depending on what kind
     * of Keyguard flags it's going to set on its windows.
     */
    public void notifyUnknownVisibilityLaunched() {
        synchronized(mWindowMap) {
            if (mContainer != null) {
                mService.mUnknownAppVisibilityController.notifyLaunched(mContainer);
            }
        }
    }

    public boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
            CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
            IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
            boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
        synchronized(mWindowMap) {
            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "setAppStartingWindow: token=" + mToken
                    + " pkg=" + pkg + " transferFrom=" + transferFrom + " newTask=" + newTask
                    + " taskSwitch=" + taskSwitch + " processRunning=" + processRunning
                    + " allowTaskSnapshot=" + allowTaskSnapshot);

            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to set icon of non-existing app token: " + mToken);
                return false;
            }

            // If the display is frozen, we won't do anything until the actual window is
            // displayed so there is no reason to put in the starting window.
            if (!mContainer.okToDisplay()) {
                return false;
            }

            if (mContainer.startingData != null) {
                return false;
            }

            final WindowState mainWin = mContainer.findMainWindow();
            if (mainWin != null && mainWin.mWinAnimator.getShown()) {
                // App already has a visible window...why would you want a starting window?
                return false;
            }

            final TaskSnapshot snapshot = mService.mTaskSnapshotController.getSnapshot(
                    mContainer.getTask().mTaskId, mContainer.getTask().mUserId,
                    false /* restoreFromDisk */, false /* reducedResolution */);
            final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
                    allowTaskSnapshot, activityCreated, fromRecents, snapshot);

            if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
                return createSnapshot(snapshot);
            }

            // If this is a translucent window, then don't show a starting window -- the current
            // effect (a full-screen opaque starting window that fades away to the real contents
            // when it is ready) does not work for this.
            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Checking theme of starting window: 0x"
                    + Integer.toHexString(theme));
            if (theme != 0) {
                AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
                        com.android.internal.R.styleable.Window, mService.mCurrentUserId);
                if (ent == null) {
                    // Whoops!  App doesn't exist. Um. Okay. We'll just pretend like we didn't
                    // see that.
                    return false;
                }
                final boolean windowIsTranslucent = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowIsTranslucent, false);
                final boolean windowIsFloating = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowIsFloating, false);
                final boolean windowShowWallpaper = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowShowWallpaper, false);
                final boolean windowDisableStarting = ent.array.getBoolean(
                        com.android.internal.R.styleable.Window_windowDisablePreview, false);
                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Translucent=" + windowIsTranslucent
                        + " Floating=" + windowIsFloating
                        + " ShowWallpaper=" + windowShowWallpaper);
                if (windowIsTranslucent) {
                    return false;
                }
                if (windowIsFloating || windowDisableStarting) {
                    return false;
                }
                if (windowShowWallpaper) {
                    if (mContainer.getDisplayContent().mWallpaperController.getWallpaperTarget()
                            == null) {
                        // If this theme is requesting a wallpaper, and the wallpaper
                        // is not currently visible, then this effectively serves as
                        // an opaque window and our starting window transition animation
                        // can still work.  We just need to make sure the starting window
                        // is also showing the wallpaper.
                        windowFlags |= FLAG_SHOW_WALLPAPER;
                    } else {
                        return false;
                    }
                }
            }

            if (mContainer.transferStartingWindow(transferFrom)) {
                return true;
            }

            // There is no existing starting window, and we don't want to create a splash screen, so
            // that's it!
            if (type != STARTING_WINDOW_TYPE_SPLASH_SCREEN) {
                return false;
            }

            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SplashScreenStartingData");
            mContainer.startingData = new SplashScreenStartingData(mService, pkg, theme,
                    compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                    mContainer.getMergedOverrideConfiguration());
            scheduleAddStartingWindow();
        }
        return true;
    }

    private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
            boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
            TaskSnapshot snapshot) {
        if (mService.mAppTransition.getAppTransition() == TRANSIT_DOCK_TASK_FROM_RECENTS) {
            // TODO(b/34099271): Remove this statement to add back the starting window and figure
            // out why it causes flickering, the starting window appears over the thumbnail while
            // the docked from recents transition occurs
            return STARTING_WINDOW_TYPE_NONE;
        } else if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
            return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
        } else if (taskSwitch && allowTaskSnapshot) {
            return snapshot == null ? STARTING_WINDOW_TYPE_NONE
                    : snapshotOrientationSameAsTask(snapshot) || fromRecents
                            ? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
        } else {
            return STARTING_WINDOW_TYPE_NONE;
        }
    }

    void scheduleAddStartingWindow() {
        // Note: we really want to do sendMessageAtFrontOfQueue() because we
        // want to process the message ASAP, before any other queued
        // messages.
        if (!mService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
            mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
        }
    }

    private boolean createSnapshot(TaskSnapshot snapshot) {
        if (snapshot == null) {
            return false;
        }

        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating SnapshotStartingData");
        mContainer.startingData = new SnapshotStartingData(mService, snapshot);
        scheduleAddStartingWindow();
        return true;
    }

    private boolean snapshotOrientationSameAsTask(TaskSnapshot snapshot) {
        if (snapshot == null) {
            return false;
        }
        return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
    }

    public void removeStartingWindow() {
        synchronized (mWindowMap) {
            if (mContainer.startingWindow == null) {
                if (mContainer.startingData != null) {
                    // Starting window has not been added yet, but it is scheduled to be added.
                    // Go ahead and cancel the request.
                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
                            "Clearing startingData for token=" + mContainer);
                    mContainer.startingData = null;
                }
                return;
            }

            final StartingSurface surface;
            if (mContainer.startingData != null) {
                surface = mContainer.startingSurface;
                mContainer.startingData = null;
                mContainer.startingSurface = null;
                mContainer.startingWindow = null;
                mContainer.startingDisplayed = false;
                if (surface == null) {
                    if (DEBUG_STARTING_WINDOW) {
                        Slog.v(TAG_WM, "startingWindow was set but startingSurface==null, couldn't "
                                + "remove");
                    }
                    return;
                }
            } else {
                if (DEBUG_STARTING_WINDOW) {
                    Slog.v(TAG_WM, "Tried to remove starting window but startingWindow was null:"
                            + mContainer);
                }
                return;
            }

            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Schedule remove starting " + mContainer
                    + " startingWindow=" + mContainer.startingWindow
                    + " startingView=" + mContainer.startingSurface
                    + " Callers=" + Debug.getCallers(5));

            // Use the same thread to remove the window as we used to add it, as otherwise we end up
            // with things in the view hierarchy being called from different threads.
            mService.mAnimationHandler.post(() -> {
                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Removing startingView=" + surface);
                try {
                    surface.remove();
                } catch (Exception e) {
                    Slog.w(TAG_WM, "Exception when removing starting window", e);
                }
            });
        }
    }

    public void pauseKeyDispatching() {
        synchronized (mWindowMap) {
            if (mContainer != null) {
                mService.mInputMonitor.pauseDispatchingLw(mContainer);
            }
        }
    }

    public void resumeKeyDispatching() {
        synchronized (mWindowMap) {
            if (mContainer != null) {
                mService.mInputMonitor.resumeDispatchingLw(mContainer);
            }
        }
    }

    public void notifyAppResumed(boolean wasStopped) {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + mToken);
                return;
            }
            mContainer.notifyAppResumed(wasStopped);
        }
    }

    public void notifyAppStopping() {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to notify stopping on non-existing app token: "
                        + mToken);
                return;
            }
            mContainer.detachChildren();
        }
    }

    public void notifyAppStopped() {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to notify stopped of non-existing app token: "
                        + mToken);
                return;
            }
            mContainer.notifyAppStopped();
        }
    }

    public void startFreezingScreen(int configChanges) {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM,
                        "Attempted to freeze screen with non-existing app token: " + mContainer);
                return;
            }

            if (configChanges == 0 && mContainer.okToDisplay()) {
                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Skipping set freeze of " + mToken);
                return;
            }

            mContainer.startFreezingScreen();
        }
    }

    public void stopFreezingScreen(boolean force) {
        synchronized(mWindowMap) {
            if (mContainer == null) {
                return;
            }
            if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + mToken + ": hidden="
                    + mContainer.isHidden() + " freezing=" + mContainer.isFreezingScreen());
            mContainer.stopFreezingScreen(true, force);
        }
    }

    public void registerRemoteAnimations(RemoteAnimationDefinition definition) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                Slog.w(TAG_WM, "Attempted to register remote animations with non-existing app"
                        + " token: " + mToken);
                return;
            }
            mContainer.registerRemoteAnimations(definition);
        }
    }

    void reportStartingWindowDrawn() {
        mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_STARTING_WINDOW_DRAWN));
    }

    void reportWindowsDrawn() {
        mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_WINDOWS_DRAWN));
    }

    void reportWindowsNotDrawn() {
        mHandler.sendMessage(mHandler.obtainMessage(H.NOTIFY_WINDOWS_NOTDRAWN));
    }

    void reportWindowsVisible() {
        mHandler.post(mOnWindowsVisible);
    }

    void reportWindowsGone() {
        mHandler.post(mOnWindowsGone);
    }

    /** Calls directly into activity manager so window manager lock shouldn't held. */
    boolean keyDispatchingTimedOut(String reason, int windowPid) {
        return mListener != null && mListener.keyDispatchingTimedOut(reason, windowPid);
    }

    /**
     * Notifies AWT that this app is waiting to pause in order to determine if it will enter PIP.
     * This information helps AWT know that the app is in the process of pausing before it gets the
     * signal on the WM side.
     */
    public void setWillCloseOrEnterPip(boolean willCloseOrEnterPip) {
        synchronized (mWindowMap) {
            if (mContainer == null) {
                return;
            }

            mContainer.setWillCloseOrEnterPip(willCloseOrEnterPip);
        }
    }

    @Override
    public String toString() {
        return "AppWindowContainerController{"
                + " token=" + mToken
                + " mContainer=" + mContainer
                + " mListener=" + mListener
                + "}";
    }
}
