/*
 * Copyright (C) 2007 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.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
import static android.Manifest.permission.STATUS_BAR_SERVICE;
import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.INVALID_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.myPid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.ADD_TOO_MANY_TOKENS;
import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_BLAST_SYNC;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;

import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
import static com.android.server.LockGuard.INDEX_WINDOW;
import static com.android.server.LockGuard.installLock;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_BOOT;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.ProtoLogGroup.WM_ERROR;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_DISPLAY_ID;
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
import static com.android.server.wm.WindowManagerServiceDumpProto.LAST_ORIENTATION;
import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY;
import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
import static com.android.server.wm.WindowManagerServiceDumpProto.ROTATION;

import android.Manifest;
import android.Manifest.permission;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityManagerInternal;
import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.IActivityTaskManager;
import android.app.IAssistDataReceiver;
import android.app.WindowConfiguration;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.hardware.configstore.V1_0.ISurfaceFlingerConfigs;
import android.hardware.configstore.V1_0.OptionalBool;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.input.InputManager;
import android.hardware.input.InputManagerInternal;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.SystemService;
import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.sysprop.SurfaceFlingerProperties;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.TypedValue;
import android.util.proto.ProtoOutputStream;
import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IDisplayFoldListener;
import android.view.IDisplayWindowInsetsController;
import android.view.IDisplayWindowListener;
import android.view.IDisplayWindowRotationController;
import android.view.IInputFilter;
import android.view.IOnKeyguardExitResult;
import android.view.IPinnedStackListener;
import android.view.IRecentsAnimationRunner;
import android.view.IRotationWatcher;
import android.view.IScrollCaptureController;
import android.view.ISystemGestureExclusionListener;
import android.view.IWallpaperVisibilityListener;
import android.view.IWindow;
import android.view.IWindowId;
import android.view.IWindowManager;
import android.view.IWindowSession;
import android.view.IWindowSessionCallback;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputWindowHandle;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.KeyEvent;
import android.view.MagnificationSpec;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.RemoteAnimationAdapter;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
import android.view.WindowContentFrameStats;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManager.RemoveContentMode;
import android.view.WindowManager.TransitionType;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants.PointerEventListener;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.internal.policy.KeyInterceptionInfo;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.LatencyTracker;
import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.AnimationThread;
import com.android.server.DisplayThread;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.input.InputManagerService;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.policy.WindowManagerPolicy.ScreenOffListener;
import com.android.server.power.ShutdownThread;
import com.android.server.protolog.ProtoLogImpl;
import com.android.server.protolog.common.ProtoLog;
import com.android.server.utils.PriorityDump;
import com.android.server.wm.utils.DeviceConfigInterface;

import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.Socket;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowManagerService" : TAG_WM;

    private static final String WM_USE_BLAST_ADAPTER_FLAG = "wm_use_blast_adapter";

    static final int LAYOUT_REPEAT_THRESHOLD = 4;

    static final boolean PROFILE_ORIENTATION = false;

    /** How much to multiply the policy's type layer, to reserve room
     * for multiple windows of the same type and Z-ordering adjustment
     * with TYPE_LAYER_OFFSET. */
    static final int TYPE_LAYER_MULTIPLIER = 10000;

    /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
     * or below others in the same layer. */
    static final int TYPE_LAYER_OFFSET = 1000;

    /** How much to increment the layer for each window, to reserve room
     * for effect surfaces between them.
     */
    static final int WINDOW_LAYER_MULTIPLIER = 5;

    /**
     * Animation thumbnail is as far as possible below the window above
     * the thumbnail (or in other words as far as possible above the window
     * below it).
     */
    static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1;

    /** The maximum length we will accept for a loaded animation duration:
     * this is 10 seconds.
     */
    static final int MAX_ANIMATION_DURATION = 10 * 1000;

    /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
    static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;

    /** Amount of time (in milliseconds) to delay before declaring a seamless rotation timeout. */
    static final int SEAMLESS_ROTATION_TIMEOUT_DURATION = 2000;

    /** Amount of time (in milliseconds) to delay before declaring a window replacement timeout. */
    static final int WINDOW_REPLACEMENT_TIMEOUT_DURATION = 2000;

    /** Amount of time to allow a last ANR message to exist before freeing the memory. */
    static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours

    // Maximum number of milliseconds to wait for input devices to be enumerated before
    // proceding with safe mode detection.
    private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;

    // Default input dispatching timeout in nanoseconds.
    static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;

    // Poll interval in milliseconds for watching boot animation finished.
    // TODO(b/159045990) Migrate to SystemService.waitForState with dedicated thread.
    private static final int BOOT_ANIMATION_POLL_INTERVAL = 50;

    // The name of the boot animation service in init.rc.
    private static final String BOOT_ANIMATION_SERVICE = "bootanim";

    static final int UPDATE_FOCUS_NORMAL = 0;
    static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
    static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
    static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
    /** Indicates we are removing the focused window when updating the focus. */
    static final int UPDATE_FOCUS_REMOVING_FOCUS = 4;

    private static final String SYSTEM_SECURE = "ro.secure";
    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";

    private static final String DENSITY_OVERRIDE = "ro.config.density_override";
    private static final String SIZE_OVERRIDE = "ro.config.size_override";

    private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";

    // Used to indicate that if there is already a transition set, it should be preserved when
    // trying to apply a new one.
    private static final boolean ALWAYS_KEEP_CURRENT = true;

    /**
     * If set, new app transition framework which supports setting animation on any element
     * in a surface is used.
     * <p>
     * Only set this to non-zero once the new app transition framework is productionalized.
     * </p>
     */
    private static final String HIERARCHICAL_ANIMATIONS_PROPERTY =
            "persist.wm.hierarchical_animations";

    private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
            "ro.sf.disable_triple_buffer";

    /**
     * @see #HIERARCHICAL_ANIMATIONS_PROPERTY
     */
    static boolean sHierarchicalAnimations =
            SystemProperties.getBoolean(HIERARCHICAL_ANIMATIONS_PROPERTY, true);

    static boolean sEnableTripleBuffering = !SystemProperties.getBoolean(
            DISABLE_TRIPLE_BUFFERING_PROPERTY, false);

    // Enums for animation scale update types.
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
    private @interface UpdateAnimationScaleMode {};
    private static final int WINDOW_ANIMATION_SCALE = 0;
    private static final int TRANSITION_ANIMATION_SCALE = 1;
    private static final int ANIMATION_DURATION_SCALE = 2;

    private static final int ANIMATION_COMPLETED_TIMEOUT_MS = 5000;

    /** The maximum count of window tokens without surface that an app can register. */
    private static final int MAXIMUM_WINDOW_TOKEN_COUNT_WITHOUT_SURFACE = 5;

    /** System UI can create more window context... */
    private static final int SYSTEM_UI_MULTIPLIER = 2;

    // TODO(b/143053092): Remove the settings if it becomes stable.
    private static final String FIXED_ROTATION_TRANSFORM_SETTING_NAME = "fixed_rotation_transform";
    boolean mIsFixedRotationTransformEnabled;

    final WindowManagerConstants mConstants;

    final WindowTracing mWindowTracing;

    final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;

    final private KeyguardDisableHandler mKeyguardDisableHandler;
    // TODO: eventually unify all keyguard state in a common place instead of having it spread over
    // AM's KeyguardController and the policy's KeyguardServiceDelegate.
    boolean mKeyguardGoingAway;
    boolean mKeyguardOrAodShowingOnDefaultDisplay;
    // VR Vr2d Display Id.
    int mVr2dDisplayId = INVALID_DISPLAY;
    boolean mVrModeEnabled = false;

    /* If true, shadows drawn around the window will be rendered by the system compositor. If
     * false, shadows will be drawn by the client by setting an elevation on the root view and
     * the contents will be inset by the shadow radius. */
    boolean mRenderShadowsInCompositor = false;

    /**
     * Tracks a map of input tokens to info that is used to decide whether to intercept
     * a key event.
     */
    final Map<IBinder, KeyInterceptionInfo> mKeyInterceptionInfoForToken =
            Collections.synchronizedMap(new ArrayMap<>());


    private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
        @Override
        public void onVrStateChanged(boolean enabled) {
            synchronized (mGlobalLock) {
                mVrModeEnabled = enabled;
                final PooledConsumer c = PooledLambda.obtainConsumer(
                        DisplayPolicy::onVrStateChangedLw, PooledLambda.__(), enabled);
                mRoot.forAllDisplayPolicies(c);
                c.recycle();
            }
        }
    };

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED:
                    mKeyguardDisableHandler.updateKeyguardEnabled(getSendingUserId());
                    break;
            }
        }
    };
    final WindowSurfacePlacer mWindowPlacerLocked;

    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
        @Override
        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
                boolean asProto) {
            // Bugreport dumps the trace 2x, 1x as proto and 1x as text. Save file to disk only 1x.
            if (asProto && mWindowTracing.isEnabled()) {
                mWindowTracing.stopTrace(null, false /* writeToFile */);
                BackgroundThread.getHandler().post(() -> {
                    mWindowTracing.writeTraceToFile();
                    mWindowTracing.startTrace(null);
                });
            }
            doDump(fd, pw, new String[] {"-a"}, asProto);
        }

        @Override
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
            doDump(fd, pw, args, asProto);
        }
    };

    /**
     * Current user when multi-user is enabled. Don't show windows of
     * non-current user. Also see mCurrentProfileIds.
     */
    int mCurrentUserId;
    /**
     * Users that are profiles of the current user. These are also allowed to show windows
     * on the current user.
     */
    int[] mCurrentProfileIds = new int[] {};

    final Context mContext;

    final boolean mHasPermanentDpad;
    final long mDrawLockTimeoutMillis;
    final boolean mAllowAnimationsInLowPowerMode;

    final boolean mAllowBootMessages;

    final boolean mLimitedAlphaCompositing;
    final int mMaxUiWidth;

    @VisibleForTesting
    WindowManagerPolicy mPolicy;

    final IActivityManager mActivityManager;
    // TODO: Probably not needed once activities are fully in WM.
    final IActivityTaskManager mActivityTaskManager;
    final ActivityManagerInternal mAmInternal;
    final ActivityTaskManagerInternal mAtmInternal;

    final AppOpsManager mAppOps;
    final PackageManagerInternal mPmInternal;

    final DisplayWindowSettings mDisplayWindowSettings;

    /** If the system should display notifications for apps displaying an alert window. */
    boolean mShowAlertWindowNotifications = true;

    /**
     * All currently active sessions with clients.
     */
    final ArraySet<Session> mSessions = new ArraySet<>();

    /** Mapping from an IWindow IBinder to the server's Window object. */
    final HashMap<IBinder, WindowState> mWindowMap = new HashMap<>();

    /** Mapping from an InputWindowHandle token to the server's Window object. */
    final HashMap<IBinder, WindowState> mInputToWindowMap = new HashMap<>();

    /** Global service lock used by the package the owns this service. */
    final WindowManagerGlobalLock mGlobalLock;

    /**
     * List of app window tokens that are waiting for replacing windows. If the
     * replacement doesn't come in time the stale windows needs to be disposed of.
     */
    final ArrayList<ActivityRecord> mWindowReplacementTimeouts = new ArrayList<>();

    /**
     * Windows that are being resized.  Used so we can tell the client about
     * the resize after closing the transaction in which we resized the
     * underlying surface.
     */
    final ArrayList<WindowState> mResizingWindows = new ArrayList<>();

    /**
     * Windows whose animations have ended and now must be removed.
     */
    final ArrayList<WindowState> mPendingRemove = new ArrayList<>();

    /**
     * Used when processing mPendingRemove to avoid working on the original array.
     */
    WindowState[] mPendingRemoveTmp = new WindowState[20];

    // TODO: use WindowProcessController once go/wm-unified is done.
    /** Mapping of process pids to configurations */
    final SparseArray<Configuration> mProcessConfigurations = new SparseArray<>();

    /**
     * Windows whose surface should be destroyed.
     */
    final ArrayList<WindowState> mDestroySurface = new ArrayList<>();

    /**
     * Windows with a preserved surface waiting to be destroyed. These windows
     * are going through a surface change. We keep the old surface around until
     * the first frame on the new surface finishes drawing.
     */
    final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();

    /**
     * This is set when we have run out of memory, and will either be an empty
     * list or contain windows that need to be force removed.
     */
    final ArrayList<WindowState> mForceRemoves = new ArrayList<>();

    /**
     * The callbacks to make when the windows all have been drawn for a given
     * {@link WindowContainer}.
     */
    final HashMap<WindowContainer, Runnable> mWaitingForDrawnCallbacks = new HashMap<>();

    /** List of window currently causing non-system overlay windows to be hidden. */
    private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();

    AccessibilityController mAccessibilityController;
    private RecentsAnimationController mRecentsAnimationController;

    Watermark mWatermark;
    StrictModeFlash mStrictModeFlash;
    EmulatorDisplayOverlay mEmulatorDisplayOverlay;

    final float[] mTmpFloats = new float[9];
    final Rect mTmpRect = new Rect();
    final Rect mTmpRect2 = new Rect();
    final Rect mTmpRect3 = new Rect();
    final RectF mTmpRectF = new RectF();

    final Matrix mTmpTransform = new Matrix();

    boolean mDisplayReady;
    boolean mSafeMode;
    boolean mDisplayEnabled = false;
    boolean mSystemBooted = false;
    boolean mForceDisplayEnabled = false;
    boolean mShowingBootMessages = false;
    boolean mBootAnimationStopped = false;
    boolean mSystemReady = false;

    // Following variables are for debugging screen wakelock only.
    WindowState mLastWakeLockHoldingWindow = null;
    WindowState mLastWakeLockObscuringWindow = null;

    /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
     * LAST_ANR_LIFETIME_DURATION_MSECS */
    String mLastANRState;

    // The root of the device window hierarchy.
    RootWindowContainer mRoot;

    // Whether the system should use BLAST for ViewRootImpl
    final boolean mUseBLAST;

    int mDockedStackCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
    Rect mDockedStackCreateBounds;

    boolean mIsPc;
    /**
     * Flag that indicates that desktop mode is forced for public secondary screens.
     *
     * This includes several settings:
     * - Set freeform windowing mode on external screen if it's supported and enabled.
     * - Enable system decorations and IME on external screen.
     * - TODO: Show mouse pointer on external screen.
     */
    boolean mForceDesktopModeOnExternalDisplays;

    boolean mDisableTransitionAnimation;

    class RotationWatcher {
        final IRotationWatcher mWatcher;
        final IBinder.DeathRecipient mDeathRecipient;
        final int mDisplayId;
        RotationWatcher(IRotationWatcher watcher, IBinder.DeathRecipient deathRecipient,
                int displayId) {
            mWatcher = watcher;
            mDeathRecipient = deathRecipient;
            mDisplayId = displayId;
        }
    }

    ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
    final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
            new WallpaperVisibilityListeners();

    IDisplayWindowRotationController mDisplayRotationController = null;
    private final DeathRecipient mDisplayRotationControllerDeath =
            () -> mDisplayRotationController = null;

    final DisplayWindowListenerController mDisplayNotificationController;

    boolean mDisplayFrozen = false;
    long mDisplayFreezeTime = 0;
    int mLastDisplayFreezeDuration = 0;
    Object mLastFinishedFreezeSource = null;
    boolean mSwitchingUser = false;

    final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
    final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
    final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
    int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;

    boolean mClientFreezingScreen = false;
    int mAppsFreezingScreen = 0;

    @VisibleForTesting
    boolean mPerDisplayFocusEnabled;

    // State while inside of layoutAndPlaceSurfacesLocked().
    boolean mFocusMayChange;

    // This is held as long as we have the screen frozen, to give us time to
    // perform a rotation animation when turning off shows the lock screen which
    // changes the orientation.
    private final PowerManager.WakeLock mScreenFrozenLock;

    final TaskSnapshotController mTaskSnapshotController;

    boolean mIsTouchDevice;

    final H mH = new H();

    /**
     * Handler for things to run that have direct impact on an animation, i.e. animation tick,
     * layout, starting window creation, whereas {@link H} runs things that are still important, but
     * not as critical.
     */
    final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());

    boolean mHardKeyboardAvailable;
    WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
    SettingsObserver mSettingsObserver;
    final EmbeddedWindowController mEmbeddedWindowController;

    @VisibleForTesting
    final class SettingsObserver extends ContentObserver {
        private final Uri mDisplayInversionEnabledUri =
                Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
        private final Uri mWindowAnimationScaleUri =
                Settings.Global.getUriFor(Settings.Global.WINDOW_ANIMATION_SCALE);
        private final Uri mTransitionAnimationScaleUri =
                Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE);
        private final Uri mAnimationDurationScaleUri =
                Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE);
        private final Uri mImmersiveModeConfirmationsUri =
                Settings.Secure.getUriFor(Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS);
        private final Uri mPolicyControlUri =
                Settings.Global.getUriFor(Settings.Global.POLICY_CONTROL);
        private final Uri mPointerLocationUri =
                Settings.System.getUriFor(Settings.System.POINTER_LOCATION);
        private final Uri mForceDesktopModeOnExternalDisplaysUri = Settings.Global.getUriFor(
                        Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS);
        private final Uri mFreeformWindowUri = Settings.Global.getUriFor(
                Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT);
        private final Uri mForceResizableUri = Settings.Global.getUriFor(
                DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
        private final Uri mSizeCompatFreeformUri = Settings.Global.getUriFor(
                DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM);
        private final Uri mRenderShadowsInCompositorUri = Settings.Global.getUriFor(
                DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
        private final Uri mFixedRotationTransformUri = Settings.Global.getUriFor(
                FIXED_ROTATION_TRANSFORM_SETTING_NAME);

        public SettingsObserver() {
            super(new Handler());
            ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(mDisplayInversionEnabledUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mWindowAnimationScaleUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mTransitionAnimationScaleUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mAnimationDurationScaleUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mImmersiveModeConfirmationsUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mPolicyControlUri, false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(mPointerLocationUri, false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(mForceDesktopModeOnExternalDisplaysUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mFreeformWindowUri, false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(mForceResizableUri, false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(mSizeCompatFreeformUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mRenderShadowsInCompositorUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mFixedRotationTransformUri, false, this,
                    UserHandle.USER_ALL);
        }

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            if (uri == null) {
                return;
            }

            if (mImmersiveModeConfirmationsUri.equals(uri) || mPolicyControlUri.equals(uri)) {
                updateSystemUiSettings();
                return;
            }

            if (mPointerLocationUri.equals(uri)) {
                updatePointerLocation();
                return;
            }

            if (mForceDesktopModeOnExternalDisplaysUri.equals(uri)) {
                updateForceDesktopModeOnExternalDisplays();
                return;
            }

            if (mFreeformWindowUri.equals(uri)) {
                updateFreeformWindowManagement();
                return;
            }

            if (mForceResizableUri.equals(uri)) {
                updateForceResizableTasks();
                return;
            }

            if (mSizeCompatFreeformUri.equals(uri)) {
                updateSizeCompatFreeform();
                return;
            }

            if (mRenderShadowsInCompositorUri.equals(uri)) {
                setShadowRenderer();
                return;
            }

            if (mFixedRotationTransformUri.equals(uri)) {
                updateFixedRotationTransform();
                return;
            }

            @UpdateAnimationScaleMode
            final int mode;
            if (mWindowAnimationScaleUri.equals(uri)) {
                mode = WINDOW_ANIMATION_SCALE;
            } else if (mTransitionAnimationScaleUri.equals(uri)) {
                mode = TRANSITION_ANIMATION_SCALE;
            } else if (mAnimationDurationScaleUri.equals(uri)) {
                mode = ANIMATION_DURATION_SCALE;
            } else {
                // Ignoring unrecognized content changes
                return;
            }
            Message m = mH.obtainMessage(H.UPDATE_ANIMATION_SCALE, mode, 0);
            mH.sendMessage(m);
        }

        void loadSettings() {
            updateSystemUiSettings();
            updatePointerLocation();
            updateFixedRotationTransform();
        }

        void updateSystemUiSettings() {
            boolean changed;
            synchronized (mGlobalLock) {
                changed = ImmersiveModeConfirmation.loadSetting(mCurrentUserId, mContext)
                        || PolicyControl.reloadFromSetting(mContext);
            }
            if (changed) {
                updateRotation(false /* alwaysSendConfiguration */, false /* forceRelayout */);
            }
        }

        void updatePointerLocation() {
            ContentResolver resolver = mContext.getContentResolver();
            final boolean enablePointerLocation = Settings.System.getIntForUser(resolver,
                    Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT) != 0;

            if (mPointerLocationEnabled == enablePointerLocation) {
                return;
            }
            mPointerLocationEnabled = enablePointerLocation;
            synchronized (mGlobalLock) {
                final PooledConsumer c = PooledLambda.obtainConsumer(
                        DisplayPolicy::setPointerLocationEnabled, PooledLambda.__(),
                        mPointerLocationEnabled);
                mRoot.forAllDisplayPolicies(c);
                c.recycle();
            }
        }

        void updateForceDesktopModeOnExternalDisplays() {
            ContentResolver resolver = mContext.getContentResolver();
            final boolean enableForceDesktopMode = Settings.Global.getInt(resolver,
                    DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
            if (mForceDesktopModeOnExternalDisplays == enableForceDesktopMode) {
                return;
            }
            setForceDesktopModeOnExternalDisplays(enableForceDesktopMode);
        }

        void updateFreeformWindowManagement() {
            ContentResolver resolver = mContext.getContentResolver();
            final boolean freeformWindowManagement = mContext.getPackageManager().hasSystemFeature(
                    FEATURE_FREEFORM_WINDOW_MANAGEMENT) || Settings.Global.getInt(
                    resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;

            if (mAtmService.mSupportsFreeformWindowManagement != freeformWindowManagement) {
                mAtmService.mSupportsFreeformWindowManagement = freeformWindowManagement;
                synchronized (mGlobalLock) {
                    // Notify the root window container that the display settings value may change.
                    mRoot.onSettingsRetrieved();
                }
            }
        }

        void updateForceResizableTasks() {
            ContentResolver resolver = mContext.getContentResolver();
            final boolean forceResizable = Settings.Global.getInt(resolver,
                    DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;

            mAtmService.mForceResizableActivities = forceResizable;
        }

        void updateSizeCompatFreeform() {
            ContentResolver resolver = mContext.getContentResolver();
            final boolean sizeCompatFreeform = Settings.Global.getInt(resolver,
                    DEVELOPMENT_ENABLE_SIZECOMPAT_FREEFORM, 0) != 0;

            mAtmService.mSizeCompatFreeform = sizeCompatFreeform;
        }

        void updateFixedRotationTransform() {
            final int enabled = Settings.Global.getInt(mContext.getContentResolver(),
                    FIXED_ROTATION_TRANSFORM_SETTING_NAME, 2);
            if (enabled == 2) {
                // Make sure who read the settings won't use inconsistent default value.
                Settings.Global.putInt(mContext.getContentResolver(),
                        FIXED_ROTATION_TRANSFORM_SETTING_NAME, 1);
            }
            mIsFixedRotationTransformEnabled = enabled != 0;
        }
    }

    private void setShadowRenderer() {
        mRenderShadowsInCompositor = Settings.Global.getInt(mContext.getContentResolver(),
                DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR, 1) != 0;
    }

    PowerManager mPowerManager;
    PowerManagerInternal mPowerManagerInternal;

    private float mWindowAnimationScaleSetting = 1.0f;
    private float mTransitionAnimationScaleSetting = 1.0f;
    private float mAnimatorDurationScaleSetting = 1.0f;
    private boolean mAnimationsDisabled = false;
    boolean mPointerLocationEnabled = false;

    final InputManagerService mInputManager;
    final DisplayManagerInternal mDisplayManagerInternal;
    final DisplayManager mDisplayManager;
    final ActivityTaskManagerService mAtmService;

    /** Indicates whether this device supports wide color gamut / HDR rendering */
    private boolean mHasWideColorGamutSupport;
    private boolean mHasHdrSupport;

    /** Who is holding the screen on. */
    private Session mHoldingScreenOn;
    private PowerManager.WakeLock mHoldingScreenWakeLock;

    /** Whether or not a layout can cause a wake up when theater mode is enabled. */
    boolean mAllowTheaterModeWakeFromLayout;

    final TaskPositioningController mTaskPositioningController;
    final DragDropController mDragDropController;

    /** For frozen screen animations. */
    private int mExitAnimId, mEnterAnimId;

    /** The display that the rotation animation is applying to. */
    private int mFrozenDisplayId;

    /** Skip repeated ActivityRecords initialization. Note that AppWindowsToken's version of this
     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
    int mTransactionSequence;

    final WindowAnimator mAnimator;
    SurfaceAnimationRunner mSurfaceAnimationRunner;

    /**
     * Keeps track of which animations got transferred to which animators. Entries will get cleaned
     * up when the animation finishes.
     */
    final ArrayMap<AnimationAdapter, SurfaceAnimator> mAnimationTransferMap = new ArrayMap<>();

    private WindowContentFrameStats mTempWindowRenderStats;

    private final LatencyTracker mLatencyTracker;

    /**
     * Whether the UI is currently running in touch mode (not showing
     * navigational focus because the user is directly pressing the screen).
     */
    private boolean mInTouchMode;

    private ViewServer mViewServer;
    final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
    boolean mWindowsChanged = false;

    public interface WindowChangeListener {
        public void windowsChanged();
        public void focusChanged();
    }

    final Configuration mTempConfiguration = new Configuration();

    final HighRefreshRateBlacklist mHighRefreshRateBlacklist;

    // If true, only the core apps and services are being launched because the device
    // is in a special boot mode, such as being encrypted or waiting for a decryption password.
    // For example, when this flag is true, there will be no wallpaper service.
    final boolean mOnlyCore;

    static WindowManagerThreadPriorityBooster sThreadPriorityBooster =
            new WindowManagerThreadPriorityBooster();

    Function<SurfaceSession, SurfaceControl.Builder> mSurfaceControlFactory;
    Supplier<SurfaceControl.Transaction> mTransactionFactory;
    final Supplier<Surface> mSurfaceFactory;

    private final SurfaceControl.Transaction mTransaction;

    static void boostPriorityForLockedSection() {
        sThreadPriorityBooster.boost();
    }

    static void resetPriorityAfterLockedSection() {
        sThreadPriorityBooster.reset();
    }

    void openSurfaceTransaction() {
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
            SurfaceControl.openTransaction();
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

    /**
     * Closes a surface transaction.
     * @param where debug string indicating where the transaction originated
     */
    void closeSurfaceTransaction(String where) {
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
            SurfaceControl.closeTransaction();
            mWindowTracing.logState(where);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

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

        @Override
        public void onAppTransitionCancelledLocked(int transit) {
        }

        @Override
        public void onAppTransitionFinishedLocked(IBinder token) {
            final ActivityRecord atoken = mRoot.getActivityRecord(token);
            if (atoken == null) {
                return;
            }

            // While running a recents animation, this will get called early because we show the
            // recents animation target activity immediately when the animation starts. Defer the
            // mLaunchTaskBehind updates until recents animation finishes.
            final boolean isRecentsAnimationTarget = getRecentsAnimationController() != null
                    && getRecentsAnimationController().isTargetApp(atoken);
            if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget) {
                try {
                    mActivityTaskManager.notifyLaunchTaskBehindComplete(atoken.token);
                } catch (RemoteException e) {
                }
                atoken.mLaunchTaskBehind = false;
            } else {
                atoken.updateReportedVisibilityLocked();
                // We should also defer sending the finished callback until the recents animation
                // successfully finishes.
                if (atoken.mEnteringAnimation && !isRecentsAnimationTarget) {
                    atoken.mEnteringAnimation = false;
                    try {
                        mActivityTaskManager.notifyEnterAnimationComplete(atoken.token);
                    } catch (RemoteException e) {
                    }
                }
            }
        }
    };

    final ArrayList<AppFreezeListener> mAppFreezeListeners = new ArrayList<>();

    interface AppFreezeListener {
        void onAppFreezeTimeout();
    }

    private static WindowManagerService sInstance;
    static WindowManagerService getInstance() {
        return sInstance;
    }

    public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
            ActivityTaskManagerService atm) {
        return main(context, im, showBootMsgs, onlyCore, policy, atm,
                SurfaceControl.Transaction::new, Surface::new, SurfaceControl.Builder::new);
    }

    /**
     * Creates and returns an instance of the WindowManagerService. This call allows the caller
     * to override factories that can be used to stub native calls during test.
     */
    @VisibleForTesting
    public static WindowManagerService main(final Context context, final InputManagerService im,
            final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
            ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
            Supplier<Surface> surfaceFactory,
            Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
        DisplayThread.getHandler().runWithScissors(() ->
                sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
                        atm, transactionFactory, surfaceFactory, surfaceControlFactory), 0);
        return sInstance;
    }

    private void initPolicy() {
        UiThread.getHandler().runWithScissors(new Runnable() {
            @Override
            public void run() {
                WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
                mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
            }
        }, 0);
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args, ShellCallback callback, ResultReceiver result) {
        new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result);
    }

    private WindowManagerService(Context context, InputManagerService inputManager,
            boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
            ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
            Supplier<Surface> surfaceFactory,
            Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
        installLock(this, INDEX_WINDOW);
        mGlobalLock = atm.getGlobalLock();
        mAtmService = atm;
        mContext = context;
        mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
        mAllowBootMessages = showBootMsgs;
        mOnlyCore = onlyCore;
        mLimitedAlphaCompositing = context.getResources().getBoolean(
                com.android.internal.R.bool.config_sf_limitedAlpha);
        mHasPermanentDpad = context.getResources().getBoolean(
                com.android.internal.R.bool.config_hasPermanentDpad);
        mInTouchMode = context.getResources().getBoolean(
                com.android.internal.R.bool.config_defaultInTouchMode);
        inputManager.setInTouchMode(mInTouchMode);
        mDrawLockTimeoutMillis = context.getResources().getInteger(
                com.android.internal.R.integer.config_drawLockTimeoutMillis);
        mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
                com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
        mMaxUiWidth = context.getResources().getInteger(
                com.android.internal.R.integer.config_maxUiWidth);
        mDisableTransitionAnimation = context.getResources().getBoolean(
                com.android.internal.R.bool.config_disableTransitionAnimation);
        mPerDisplayFocusEnabled = context.getResources().getBoolean(
                com.android.internal.R.bool.config_perDisplayFocusEnabled);
        mInputManager = inputManager; // Must be before createDisplayContentLocked.
        mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

        mSurfaceControlFactory = surfaceControlFactory;
        mTransactionFactory = transactionFactory;
        mSurfaceFactory = surfaceFactory;
        mTransaction = mTransactionFactory.get();

        mDisplayWindowSettings = new DisplayWindowSettings(this);
        mPolicy = policy;
        mAnimator = new WindowAnimator(this);
        mRoot = new RootWindowContainer(this);

        mUseBLAST = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT,
                    WM_USE_BLAST_ADAPTER_FLAG, false);

        mWindowPlacerLocked = new WindowSurfacePlacer(this);
        mTaskSnapshotController = new TaskSnapshotController(this);

        mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
                Choreographer.getInstance());

        LocalServices.addService(WindowManagerPolicy.class, mPolicy);

        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);

        mKeyguardDisableHandler = KeyguardDisableHandler.create(mContext, mPolicy, mH);

        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);

        if (mPowerManagerInternal != null) {
            mPowerManagerInternal.registerLowPowerModeObserver(
                    new PowerManagerInternal.LowPowerModeListener() {
                @Override
                public int getServiceType() {
                    return ServiceType.ANIMATION;
                }

                @Override
                public void onLowPowerModeChanged(PowerSaveState result) {
                    synchronized (mGlobalLock) {
                        final boolean enabled = result.batterySaverEnabled;
                        if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
                            mAnimationsDisabled = enabled;
                            dispatchNewAnimatorScaleLocked(null);
                        }
                    }
                }
            });
            mAnimationsDisabled = mPowerManagerInternal
                    .getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled;
        }
        mScreenFrozenLock = mPowerManager.newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
        mScreenFrozenLock.setReferenceCounted(false);

        mDisplayNotificationController = new DisplayWindowListenerController(this);

        mActivityManager = ActivityManager.getService();
        mActivityTaskManager = ActivityTaskManager.getService();
        mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
        mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
        AppOpsManager.OnOpChangedInternalListener opListener =
                new AppOpsManager.OnOpChangedInternalListener() {
                    @Override public void onOpChanged(int op, String packageName) {
                        updateAppOpsState();
                    }
                };
        mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
        mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);

        mPmInternal = LocalServices.getService(PackageManagerInternal.class);
        final IntentFilter suspendPackagesFilter = new IntentFilter();
        suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
        suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
        context.registerReceiverAsUser(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                final String[] affectedPackages =
                        intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                final boolean suspended =
                        Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
                updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)),
                        suspended);
            }
        }, UserHandle.ALL, suspendPackagesFilter, null, null);

        final ContentResolver resolver = context.getContentResolver();
        // Get persisted window scale setting
        mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
                Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
        mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver,
                Settings.Global.TRANSITION_ANIMATION_SCALE,
                context.getResources().getFloat(
                        R.dimen.config_appTransitionAnimationDurationScaleDefault));

        setAnimatorDurationScale(Settings.Global.getFloat(resolver,
                Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));

        mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;

        IntentFilter filter = new IntentFilter();
        // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
        filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);

        mLatencyTracker = LatencyTracker.getInstance(context);

        mSettingsObserver = new SettingsObserver();

        mHoldingScreenWakeLock = mPowerManager.newWakeLock(
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
        mHoldingScreenWakeLock.setReferenceCounted(false);

        mSurfaceAnimationRunner = new SurfaceAnimationRunner(mTransactionFactory,
                mPowerManagerInternal);

        mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);

        mTaskPositioningController = new TaskPositioningController(
                this, mInputManager, mActivityTaskManager, mH.getLooper());
        mDragDropController = new DragDropController(this, mH.getLooper());

        mHighRefreshRateBlacklist = HighRefreshRateBlacklist.create(context.getResources());

        mConstants = new WindowManagerConstants(this, DeviceConfigInterface.REAL);
        mConstants.start(new HandlerExecutor(mH));

        LocalServices.addService(WindowManagerInternal.class, new LocalService());
        mEmbeddedWindowController = new EmbeddedWindowController(mAtmService);

        mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(
                mContext.getResources());

        setGlobalShadowSettings();
    }

    private void setGlobalShadowSettings() {
        final TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
        float lightY = a.getDimension(R.styleable.Lighting_lightY, 0);
        float lightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
        float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
        float ambientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0);
        float spotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0);
        float[] ambientColor = {0.f, 0.f, 0.f, ambientShadowAlpha};
        float[] spotColor = {0.f, 0.f, 0.f, spotShadowAlpha};
        SurfaceControl.setGlobalShadowSettings(ambientColor, spotColor, lightY, lightZ,
                lightRadius);
        setShadowRenderer();
    }

    /**
     * Called after all entities (such as the {@link ActivityManagerService}) have been set up and
     * associated with the {@link WindowManagerService}.
     */
    public void onInitReady() {
        initPolicy();

        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);
        createWatermark();
        showEmulatorDisplayOverlayIfNeeded();
    }

    public InputManagerCallback getInputManagerCallback() {
        return mInputManagerCallback;
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        try {
            return super.onTransact(code, data, reply, flags);
        } catch (RuntimeException e) {
            // The window manager only throws security exceptions, so let's
            // log all others.
            if (!(e instanceof SecurityException)) {
                ProtoLog.wtf(WM_ERROR, "Window Manager Crash %s", e);
            }
            throw e;
        }
    }

    static boolean excludeWindowTypeFromTapOutTask(int windowType) {
        switch (windowType) {
            case TYPE_STATUS_BAR:
            case TYPE_NOTIFICATION_SHADE:
            case TYPE_NAVIGATION_BAR:
            case TYPE_INPUT_METHOD_DIALOG:
            case TYPE_VOLUME_OVERLAY:
                return true;
        }
        return false;
    }

    public int addWindow(Session session, IWindow client, int seq,
            LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
            Rect outContentInsets, Rect outStableInsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
            InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
            int requestUserId) {
        Arrays.fill(outActiveControls, null);
        int[] appOp = new int[1];
        final boolean isRoundedCornerOverlay = (attrs.privateFlags
                & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
        int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName,
                appOp);
        if (res != WindowManagerGlobal.ADD_OKAY) {
            return res;
        }

        WindowState parentWindow = null;
        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        final int type = attrs.type;

        synchronized (mGlobalLock) {
            if (!mDisplayReady) {
                throw new IllegalStateException("Display has not been initialialized");
            }

            final DisplayContent displayContent = getDisplayContentOrCreate(displayId, attrs.token);

            if (displayContent == null) {
                ProtoLog.w(WM_ERROR, "Attempted to add window to a display that does "
                        + "not exist: %d. Aborting.", displayId);
                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
            }
            if (!displayContent.hasAccess(session.mUid)) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to add window to a display for which the application "
                                + "does not have access: %d.  Aborting.", displayId);
                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
            }

            if (mWindowMap.containsKey(client.asBinder())) {
                ProtoLog.w(WM_ERROR, "Window %s is already added", client);
                return WindowManagerGlobal.ADD_DUPLICATE_ADD;
            }

            if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
                parentWindow = windowForClientLocked(null, attrs.token, false);
                if (parentWindow == null) {
                    ProtoLog.w(WM_ERROR, "Attempted to add window with token that is not a window: "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
                }
                if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
                        && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
                    ProtoLog.w(WM_ERROR, "Attempted to add window with token that is a sub-window: "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
                }
            }

            if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to add private presentation window to a non-private display.  "
                                + "Aborting.");
                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
            }

            if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to add presentation window to a non-suitable display.  "
                                + "Aborting.");
                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
            }

            int userId = UserHandle.getUserId(session.mUid);
            if (requestUserId != userId) {
                try {
                    mAmInternal.handleIncomingUser(callingPid, callingUid, requestUserId,
                            false /*allowAll*/, ALLOW_NON_FULL, null, null);
                } catch (Exception exp) {
                    ProtoLog.w(WM_ERROR, "Trying to add window with invalid user=%d",
                            requestUserId);
                    return WindowManagerGlobal.ADD_INVALID_USER;
                }
                // It's fine to use this userId
                userId = requestUserId;
            }

            ActivityRecord activity = null;
            final boolean hasParent = parentWindow != null;
            // Use existing parent window token for child windows since they go in the same token
            // as there parent window so we can apply the same policy on them.
            WindowToken token = displayContent.getWindowToken(
                    hasParent ? parentWindow.mAttrs.token : attrs.token);
            // If this is a child window, we want to apply the same type checking rules as the
            // parent window type.
            final int rootType = hasParent ? parentWindow.mAttrs.type : type;

            boolean addToastWindowRequiresToken = false;

            if (token == null) {
                if (!unprivilegedAppCanCreateTokenWith(parentWindow, callingUid, type,
                        rootType, attrs.token, attrs.packageName)) {
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
                final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
                token = new WindowToken(this, binder, type, false, displayContent,
                        session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);
            } else if (rootType >= FIRST_APPLICATION_WINDOW
                    && rootType <= LAST_APPLICATION_WINDOW) {
                activity = token.asActivityRecord();
                if (activity == null) {
                    ProtoLog.w(WM_ERROR, "Attempted to add window with non-application token "
                            + ".%s Aborting.", token);
                    return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
                } else if (activity.getParent() == null) {
                    ProtoLog.w(WM_ERROR, "Attempted to add window with exiting application token "
                            + ".%s Aborting.", token);
                    return WindowManagerGlobal.ADD_APP_EXITING;
                } else if (type == TYPE_APPLICATION_STARTING && activity.startingWindow != null) {
                    ProtoLog.w(WM_ERROR,
                            "Attempted to add starting window to token with already existing"
                                    + " starting window");
                    return WindowManagerGlobal.ADD_DUPLICATE_ADD;
                }
            } else if (rootType == TYPE_INPUT_METHOD) {
                if (token.windowType != TYPE_INPUT_METHOD) {
                    ProtoLog.w(WM_ERROR, "Attempted to add input method window with bad token "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            } else if (rootType == TYPE_VOICE_INTERACTION) {
                if (token.windowType != TYPE_VOICE_INTERACTION) {
                    ProtoLog.w(WM_ERROR, "Attempted to add voice interaction window with bad token "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            } else if (rootType == TYPE_WALLPAPER) {
                if (token.windowType != TYPE_WALLPAPER) {
                    ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with bad token "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
                if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
                    ProtoLog.w(WM_ERROR,
                            "Attempted to add Accessibility overlay window with bad token "
                                    + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            } else if (type == TYPE_TOAST) {
                // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
                addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName,
                        callingUid, parentWindow);
                if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) {
                    ProtoLog.w(WM_ERROR, "Attempted to add a toast window with bad token "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            } else if (type == TYPE_QS_DIALOG) {
                if (token.windowType != TYPE_QS_DIALOG) {
                    ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with bad token "
                            + "%s.  Aborting.", attrs.token);
                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                }
            } else if (token.asActivityRecord() != null) {
                ProtoLog.w(WM_ERROR, "Non-null activity for system window of rootType=%d",
                        rootType);
                // It is not valid to use an app token with other system types; we will
                // instead make a new token for it (as if null had been passed in for the token).
                attrs.token = null;
                token = new WindowToken(this, client.asBinder(), type, false, displayContent,
                        session.mCanAddInternalSystemWindow);
            }

            final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid, userId,
                    session.mCanAddInternalSystemWindow);
            if (win.mDeathRecipient == null) {
                // Client has apparently died, so there is no reason to
                // continue.
                ProtoLog.w(WM_ERROR, "Adding window client %s"
                        + " that is dead, aborting.", client.asBinder());
                return WindowManagerGlobal.ADD_APP_EXITING;
            }

            if (win.getDisplayContent() == null) {
                ProtoLog.w(WM_ERROR, "Adding window to Display that has been removed.");
                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
            }

            final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
            displayPolicy.adjustWindowParamsLw(win, win.mAttrs, callingPid, callingUid);

            res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
            if (res != WindowManagerGlobal.ADD_OKAY) {
                return res;
            }

            final boolean openInputChannels = (outInputChannel != null
                    && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
            if  (openInputChannels) {
                win.openInputChannel(outInputChannel);
            }

            // If adding a toast requires a token for this app we always schedule hiding
            // toast windows to make sure they don't stick around longer then necessary.
            // We hide instead of remove such windows as apps aren't prepared to handle
            // windows being removed under them.
            //
            // If the app is older it can add toasts without a token and hence overlay
            // other apps. To be maximally compatible with these apps we will hide the
            // window after the toast timeout only if the focused window is from another
            // UID, otherwise we allow unlimited duration. When a UID looses focus we
            // schedule hiding all of its toast windows.
            if (type == TYPE_TOAST) {
                if (!displayContent.canAddToastWindowForUid(callingUid)) {
                    ProtoLog.w(WM_ERROR, "Adding more than one toast window for UID at a time.");
                    return WindowManagerGlobal.ADD_DUPLICATE_ADD;
                }
                // Make sure this happens before we moved focus as one can make the
                // toast focusable to force it not being hidden after the timeout.
                // Focusable toasts are always timed out to prevent a focused app to
                // show a focusable toasts while it has focus which will be kept on
                // the screen after the activity goes away.
                if (addToastWindowRequiresToken
                        || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0
                        || displayContent.mCurrentFocus == null
                        || displayContent.mCurrentFocus.mOwnerUid != callingUid) {
                    mH.sendMessageDelayed(
                            mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win),
                            win.mAttrs.hideTimeoutMilliseconds);
                }
            }

            // From now on, no exceptions or errors allowed!

            res = WindowManagerGlobal.ADD_OKAY;

            if (mUseBLAST) {
                res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST;
            }
            if (sEnableTripleBuffering) {
                res |= WindowManagerGlobal.ADD_FLAG_USE_TRIPLE_BUFFERING;
            }

            if (displayContent.mCurrentFocus == null) {
                displayContent.mWinAddedSinceNullFocus.add(win);
            }

            if (excludeWindowTypeFromTapOutTask(type)) {
                displayContent.mTapExcludedWindows.add(win);
            }

            win.attach();
            mWindowMap.put(client.asBinder(), win);
            win.initAppOpsState();

            final boolean suspended = mPmInternal.isPackageSuspended(win.getOwningPackage(),
                    UserHandle.getUserId(win.getOwningUid()));
            win.setHiddenWhileSuspended(suspended);

            final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
            win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);

            final ActivityRecord tokenActivity = token.asActivityRecord();
            if (type == TYPE_APPLICATION_STARTING && tokenActivity != null) {
                tokenActivity.startingWindow = win;
                ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "addWindow: %s startingWindow=%s",
                        activity, win);
            }

            boolean imMayMove = true;

            win.mToken.addWindow(win);
            displayPolicy.addWindowLw(win, attrs);
            if (type == TYPE_INPUT_METHOD) {
                displayContent.setInputMethodWindowLocked(win);
                imMayMove = false;
            } else if (type == TYPE_INPUT_METHOD_DIALOG) {
                displayContent.computeImeTarget(true /* updateImeTarget */);
                imMayMove = false;
            } else {
                if (type == TYPE_WALLPAPER) {
                    displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                } else if ((attrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) {
                    // If there is currently a wallpaper being shown, and
                    // the base layer of the new window is below the current
                    // layer of the target window, then adjust the wallpaper.
                    // This is to avoid a new window being placed between the
                    // wallpaper and its target.
                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                }
            }

            final WindowStateAnimator winAnimator = win.mWinAnimator;
            winAnimator.mEnterAnimationPending = true;
            winAnimator.mEnteringAnimation = true;
            // Check if we need to prepare a transition for replacing window first.
            if (activity != null && activity.isVisible()
                    && !prepareWindowReplacementTransition(activity)) {
                // If not, check if need to set up a dummy transition during display freeze
                // so that the unfreeze wait for the apps to draw. This might be needed if
                // the app is relaunching.
                prepareNoneTransitionForRelaunching(activity);
            }

            if (displayPolicy.getLayoutHint(win.mAttrs, token, outFrame, outContentInsets,
                    outStableInsets, outDisplayCutout)) {
                res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS;
            }
            outInsetsState.set(win.getInsetsState(), win.isClientLocal());

            if (mInTouchMode) {
                res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
            }
            if (win.mActivityRecord == null || win.mActivityRecord.isClientVisible()) {
                res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
            }

            displayContent.getInputMonitor().setUpdateInputWindowsNeededLw();

            boolean focusChanged = false;
            if (win.canReceiveKeys()) {
                focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
                        false /*updateInputWindows*/);
                if (focusChanged) {
                    imMayMove = false;
                }
            }

            if (imMayMove) {
                displayContent.computeImeTarget(true /* updateImeTarget */);
            }

            // Don't do layout here, the window must call
            // relayout to be displayed, so we'll do it there.
            win.getParent().assignChildLayers();

            if (focusChanged) {
                displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus,
                        false /*updateInputWindows*/);
            }
            displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);

            ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addWindow: New client %s"
                    + ": window=%s Callers=%s", client.asBinder(), win, Debug.getCallers(5));

            if (win.isVisibleOrAdding() && displayContent.updateOrientation()) {
                displayContent.sendNewConfiguration();
            }

            getInsetsSourceControls(win, outActiveControls);
        }

        Binder.restoreCallingIdentity(origId);

        return res;
    }

    private boolean unprivilegedAppCanCreateTokenWith(WindowState parentWindow,
            int callingUid, int type, int rootType, IBinder tokenForLog, String packageName) {
        if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
            ProtoLog.w(WM_ERROR, "Attempted to add application window with unknown token "
                    + "%s.  Aborting.", tokenForLog);
            return false;
        }
        if (rootType == TYPE_INPUT_METHOD) {
            ProtoLog.w(WM_ERROR, "Attempted to add input method window with unknown token "
                    + "%s.  Aborting.", tokenForLog);
            return false;
        }
        if (rootType == TYPE_VOICE_INTERACTION) {
            ProtoLog.w(WM_ERROR,
                    "Attempted to add voice interaction window with unknown token "
                            + "%s.  Aborting.", tokenForLog);
            return false;
        }
        if (rootType == TYPE_WALLPAPER) {
            ProtoLog.w(WM_ERROR, "Attempted to add wallpaper window with unknown token "
                    + "%s.  Aborting.", tokenForLog);
            return false;
        }
        if (rootType == TYPE_QS_DIALOG) {
            ProtoLog.w(WM_ERROR, "Attempted to add QS dialog window with unknown token "
                    + "%s.  Aborting.", tokenForLog);
            return false;
        }
        if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
            ProtoLog.w(WM_ERROR,
                    "Attempted to add Accessibility overlay window with unknown token "
                            + "%s.  Aborting.", tokenForLog);
            return false;
        }
        if (type == TYPE_TOAST) {
            // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
            if (doesAddToastWindowRequireToken(packageName, callingUid, parentWindow)) {
                ProtoLog.w(WM_ERROR, "Attempted to add a toast window with unknown token "
                        + "%s.  Aborting.", tokenForLog);
                return false;
            }
        }
        return true;
    }

    /**
     * Get existing {@link DisplayContent} or create a new one if the display is registered in
     * DisplayManager.
     *
     * NOTE: This should only be used in cases when there is a chance that a {@link DisplayContent}
     * that corresponds to a display just added to DisplayManager has not yet been created. This
     * usually means that the call of this method was initiated from outside of Activity or Window
     * Manager. In most cases the regular getter should be used.
     * @param displayId The preferred display Id.
     * @param token The window token associated with the window we are trying to get display for.
     *              if not null then the display of the window token will be returned. Set to null
     *              is there isn't an a token associated with the request.
     * @see RootWindowContainer#getDisplayContent(int)
     */
    private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) {
        if (token != null) {
            final WindowToken wToken = mRoot.getWindowToken(token);
            if (wToken != null) {
                return wToken.getDisplayContent();
            }
        }

        return mRoot.getDisplayContentOrCreate(displayId);
    }

    private boolean doesAddToastWindowRequireToken(String packageName, int callingUid,
            WindowState attachedWindow) {
        // Try using the target SDK of the root window
        if (attachedWindow != null) {
            return attachedWindow.mActivityRecord != null
                    && attachedWindow.mActivityRecord.mTargetSdk >= Build.VERSION_CODES.O;
        } else {
            // Otherwise, look at the package
            try {
                ApplicationInfo appInfo = mContext.getPackageManager()
                        .getApplicationInfoAsUser(packageName, 0,
                                UserHandle.getUserId(callingUid));
                if (appInfo.uid != callingUid) {
                    throw new SecurityException("Package " + packageName + " not in UID "
                            + callingUid);
                }
                if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
                    return true;
                }
            } catch (PackageManager.NameNotFoundException e) {
                /* ignore */
            }
        }
        return false;
    }

    /**
     * Returns true if we're done setting up any transitions.
     */
    private boolean prepareWindowReplacementTransition(ActivityRecord activity) {
        activity.clearAllDrawn();
        final WindowState replacedWindow = activity.getReplacingWindow();
        if (replacedWindow == null) {
            // We expect to already receive a request to remove the old window. If it did not
            // happen, let's just simply add a window.
            return false;
        }
        // We use the visible frame, because we want the animation to morph the window from what
        // was visible to the user to the final destination of the new window.
        Rect frame = replacedWindow.getVisibleFrameLw();
        // We treat this as if this activity was opening, so we can trigger the app transition
        // animation and piggy-back on existing transition animation infrastructure.
        final DisplayContent dc = activity.getDisplayContent();
        dc.mOpeningApps.add(activity);
        dc.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_RELAUNCH, ALWAYS_KEEP_CURRENT,
                0 /* flags */, false /* forceOverride */);
        dc.mAppTransition.overridePendingAppTransitionClipReveal(frame.left, frame.top,
                frame.width(), frame.height());
        dc.executeAppTransition();
        return true;
    }

    private void prepareNoneTransitionForRelaunching(ActivityRecord activity) {
        // Set up a none-transition and add the app to opening apps, so that the display
        // unfreeze wait for the apps to be drawn.
        // Note that if the display unfroze already because app unfreeze timed out,
        // we don't set up the transition anymore and just let it go.
        final DisplayContent dc = activity.getDisplayContent();
        if (mDisplayFrozen && !dc.mOpeningApps.contains(activity) && activity.isRelaunching()) {
            dc.mOpeningApps.add(activity);
            dc.prepareAppTransition(WindowManager.TRANSIT_NONE, !ALWAYS_KEEP_CURRENT, 0 /* flags */,
                    false /* forceOverride */);
            dc.executeAppTransition();
        }
    }

    /**
     * Set whether screen capture is disabled for all windows of a specific user from
     * the device policy cache.
     */
    @Override
    public void refreshScreenCaptureDisabled(int userId) {
        int callingUid = Binder.getCallingUid();
        if (callingUid != SYSTEM_UID) {
            throw new SecurityException("Only system can call refreshScreenCaptureDisabled.");
        }

        synchronized (mGlobalLock) {
            // Update secure surface for all windows belonging to this user.
            mRoot.setSecureSurfaceState(userId);
        }
    }

    void removeWindow(Session session, IWindow client) {
        synchronized (mGlobalLock) {
            WindowState win = windowForClientLocked(session, client, false);
            if (win != null) {
                win.removeIfPossible();
                return;
            }

            // Remove embedded window map if the token belongs to an embedded window
            mEmbeddedWindowController.remove(client);
        }
    }

    /**
     * Performs some centralized bookkeeping clean-up on the window that is being removed.
     * NOTE: Should only be called from {@link WindowState#removeImmediately()}
     * TODO: Maybe better handled with a method {@link WindowContainer#removeChild} if we can
     * figure-out a good way to have all parents of a WindowState doing the same thing without
     * forgetting to add the wiring when a new parent of WindowState is added.
     */
    void postWindowRemoveCleanupLocked(WindowState win) {
        ProtoLog.v(WM_DEBUG_ADD_REMOVE, "postWindowRemoveCleanupLocked: %s", win);
        mWindowMap.remove(win.mClient.asBinder());

        final DisplayContent dc = win.getDisplayContent();
        dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */);

        win.resetAppOpsState();

        if (dc.mCurrentFocus == null) {
            dc.mWinRemovedSinceNullFocus.add(win);
        }
        mEmbeddedWindowController.onWindowRemoved(win);
        mPendingRemove.remove(win);
        mResizingWindows.remove(win);
        updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */);
        mWindowsChanged = true;
        ProtoLog.v(WM_DEBUG_WINDOW_MOVEMENT, "Final remove of window: %s", win);

        final DisplayContent displayContent = win.getDisplayContent();
        if (displayContent.mInputMethodWindow == win) {
            displayContent.setInputMethodWindowLocked(null);
        }

        final WindowToken token = win.mToken;
        final ActivityRecord activity = win.mActivityRecord;
        ProtoLog.v(WM_DEBUG_ADD_REMOVE, "Removing %s from %s", win, token);
        // Window will already be removed from token before this post clean-up method is called.
        if (token.isEmpty()) {
            if (!token.mPersistOnEmpty) {
                token.removeImmediately();
            } else if (activity != null) {
                // TODO: Should this be moved into ActivityRecord.removeWindow? Might go away after
                // re-factor.
                activity.firstWindowDrawn = false;
                activity.clearAllDrawn();
                final ActivityStack stack = activity.getStack();
                if (stack != null) {
                    stack.mExitingActivities.remove(activity);
                }
            }
        }

        if (activity != null) {
            activity.postWindowRemoveStartingWindowCleanup(win);
        }

        if (win.mAttrs.type == TYPE_WALLPAPER) {
            dc.mWallpaperController.clearLastWallpaperTimeoutTime();
            dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
        } else if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
            dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
        }

        if (dc != null && !mWindowPlacerLocked.isInLayout()) {
            dc.assignWindowLayers(true /* setLayoutNeeded */);
            mWindowPlacerLocked.performSurfacePlacement();
            if (win.mActivityRecord != null) {
                win.mActivityRecord.updateReportedVisibilityLocked();
            }
        }

        dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
    }

    private void updateHiddenWhileSuspendedState(ArraySet<String> packages, boolean suspended) {
        synchronized (mGlobalLock) {
            mRoot.updateHiddenWhileSuspendedState(packages, suspended);
        }
    }

    private void updateAppOpsState() {
        synchronized (mGlobalLock) {
            mRoot.updateAppOpsState();
        }
    }

    static void logSurface(WindowState w, String msg, boolean withStackTrace) {
        String str = "  SURFACE " + msg + ": " + w;
        if (withStackTrace) {
            logWithStack(TAG, str);
        } else {
            Slog.i(TAG_WM, str);
        }
    }

    static void logWithStack(String tag, String s) {
        RuntimeException e = null;
        if (SHOW_STACK_CRAWLS) {
            e = new RuntimeException();
            e.fillInStackTrace();
        }
        Slog.i(tag, s, e);
    }

    void setTransparentRegionWindow(Session session, IWindow client, Region region) {
        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                WindowState w = windowForClientLocked(session, client, false);
                ProtoLog.i(WM_SHOW_TRANSACTIONS, "SURFACE transparentRegionHint=%s: %s",
                        region, w);

                if ((w != null) && w.mHasSurface) {
                    w.mWinAnimator.setTransparentRegionHintLocked(region);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets,
            Rect visibleInsets, Region touchableRegion) {
        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                WindowState w = windowForClientLocked(session, client, false);
                if (DEBUG_LAYOUT) Slog.d(TAG, "setInsetsWindow " + w
                        + ", contentInsets=" + w.mGivenContentInsets + " -> " + contentInsets
                        + ", visibleInsets=" + w.mGivenVisibleInsets + " -> " + visibleInsets
                        + ", touchableRegion=" + w.mGivenTouchableRegion + " -> " + touchableRegion
                        + ", touchableInsets " + w.mTouchableInsets + " -> " + touchableInsets);
                if (w != null) {
                    w.mGivenInsetsPending = false;
                    w.mGivenContentInsets.set(contentInsets);
                    w.mGivenVisibleInsets.set(visibleInsets);
                    w.mGivenTouchableRegion.set(touchableRegion);
                    w.mTouchableInsets = touchableInsets;
                    if (w.mGlobalScale != 1) {
                        w.mGivenContentInsets.scale(w.mGlobalScale);
                        w.mGivenVisibleInsets.scale(w.mGlobalScale);
                        w.mGivenTouchableRegion.scale(w.mGlobalScale);
                    }
                    w.setDisplayLayoutNeeded();
                    mWindowPlacerLocked.performSurfacePlacement();

                    // We need to report touchable region changes to accessibility.
                    if (mAccessibilityController != null) {
                        mAccessibilityController.onSomeWindowResizedOrMovedLocked(
                                w.getDisplayContent().getDisplayId());
                    }
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    public void getWindowDisplayFrame(Session session, IWindow client,
            Rect outDisplayFrame) {
        synchronized (mGlobalLock) {
            WindowState win = windowForClientLocked(session, client, false);
            if (win == null) {
                outDisplayFrame.setEmpty();
                return;
            }
            outDisplayFrame.set(win.getDisplayFrameLw());
            if (win.inSizeCompatMode()) {
                outDisplayFrame.scale(win.mInvGlobalScale);
            }
        }
    }

    public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
        synchronized (mGlobalLock) {
            if (mAccessibilityController != null) {
                WindowState window = mWindowMap.get(token);
                if (window != null) {
                    mAccessibilityController.onRectangleOnScreenRequestedLocked(
                            window.getDisplayId(), rectangle);
                }
            }
        }
    }

    public IWindowId getWindowId(IBinder token) {
        synchronized (mGlobalLock) {
            WindowState window = mWindowMap.get(token);
            return window != null ? window.mWindowId : null;
        }
    }

    public void pokeDrawLock(Session session, IBinder token) {
        synchronized (mGlobalLock) {
            WindowState window = windowForClientLocked(session, token, false);
            if (window != null) {
                window.pokeDrawLockLw(mDrawLockTimeoutMillis);
            }
        }
    }

    private boolean hasStatusBarPermission(int pid, int uid) {
        return mContext.checkPermission(permission.STATUS_BAR, pid, uid)
                        == PackageManager.PERMISSION_GRANTED;
    }

    public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            long frameNumber, Rect outFrame, Rect outContentInsets,
            Rect outVisibleInsets, Rect outStableInsets, Rect outBackdropFrame,
            DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState,
            InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
            SurfaceControl outBLASTSurfaceControl) {
        Arrays.fill(outActiveControls, null);
        int result = 0;
        boolean configChanged;
        final int pid = Binder.getCallingPid();
        final int uid = Binder.getCallingUid();
        long origId = Binder.clearCallingIdentity();
        synchronized (mGlobalLock) {
            final WindowState win = windowForClientLocked(session, client, false);
            if (win == null) {
                return 0;
            }
            final DisplayContent displayContent = win.getDisplayContent();
            final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();

            WindowStateAnimator winAnimator = win.mWinAnimator;
            if (viewVisibility != View.GONE) {
                win.setRequestedSize(requestedWidth, requestedHeight);
            }

            win.setFrameNumber(frameNumber);

            final DisplayContent dc = win.getDisplayContent();
            if (!dc.mWaitingForConfig) {
                win.finishSeamlessRotation(false /* timeout */);
            }

            if (win.useBLASTSync()) {
                result |= RELAYOUT_RES_BLAST_SYNC;
            }

            int attrChanges = 0;
            int flagChanges = 0;
            int privateFlagChanges = 0;
            if (attrs != null) {
                displayPolicy.adjustWindowParamsLw(win, attrs, pid, uid);
                win.mToken.adjustWindowParams(win, attrs);
                // if they don't have the permission, mask out the status bar bits
                if (seq == win.mSeq) {
                    int systemUiVisibility = attrs.systemUiVisibility
                            | attrs.subtreeSystemUiVisibility;
                    if ((systemUiVisibility & DISABLE_MASK) != 0) {
                        if (!hasStatusBarPermission(pid, uid)) {
                            systemUiVisibility &= ~DISABLE_MASK;
                        }
                    }
                    win.mSystemUiVisibility = systemUiVisibility;
                }
                if (win.mAttrs.type != attrs.type) {
                    throw new IllegalArgumentException(
                            "Window type can not be changed after the window is added.");
                }

                // Odd choice but less odd than embedding in copyFrom()
                if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY)
                        != 0) {
                    attrs.x = win.mAttrs.x;
                    attrs.y = win.mAttrs.y;
                    attrs.width = win.mAttrs.width;
                    attrs.height = win.mAttrs.height;
                }

                flagChanges = win.mAttrs.flags ^ attrs.flags;
                privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags;
                attrChanges = win.mAttrs.copyFrom(attrs);
                if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
                        | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
                    win.mLayoutNeeded = true;
                }
                if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
                        || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
                    win.mActivityRecord.checkKeyguardFlagsChanged();
                }
                if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0)
                        && (mAccessibilityController != null)) {
                    // No move or resize, but the controller checks for title changes as well
                    mAccessibilityController.onSomeWindowResizedOrMovedLocked(
                            win.getDisplayContent().getDisplayId());
                }

                if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
                    updateNonSystemOverlayWindowsVisibilityIfNeeded(
                            win, win.mWinAnimator.getShown());
                }
                if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) {
                    winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags
                            & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
                }
            }

            if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
                    + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
            winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
            if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
                winAnimator.mAlpha = attrs.alpha;
            }
            win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);

            if (win.mAttrs.surfaceInsets.left != 0
                    || win.mAttrs.surfaceInsets.top != 0
                    || win.mAttrs.surfaceInsets.right != 0
                    || win.mAttrs.surfaceInsets.bottom != 0) {
                winAnimator.setOpaqueLocked(false);
            }

            final int oldVisibility = win.mViewVisibility;

            // If the window is becoming visible, visibleOrAdding may change which may in turn
            // change the IME target.
            final boolean becameVisible =
                    (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)
                            && viewVisibility == View.VISIBLE;
            boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
                    || becameVisible;
            boolean focusMayChange = win.mViewVisibility != viewVisibility
                    || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
                    || (!win.mRelayoutCalled);

            boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                    && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
            wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
            if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
                winAnimator.mSurfaceController.setSecure(win.isSecureLocked());
            }

            win.mRelayoutCalled = true;
            win.mInRelayout = true;

            win.setViewVisibility(viewVisibility);
            ProtoLog.i(WM_DEBUG_SCREEN_ON,
                    "Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,
                            viewVisibility, new RuntimeException().fillInStackTrace());


            win.setDisplayLayoutNeeded();
            win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;

            // We should only relayout if the view is visible, it is a starting window, or the
            // associated appToken is not hidden.
            final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
                    (win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
                            || win.mActivityRecord.isClientVisible());

            // If we are not currently running the exit animation, we need to see about starting
            // one.
            // We don't want to animate visibility of windows which are pending replacement.
            // In the case of activity relaunch child windows could request visibility changes as
            // they are detached from the main application window during the tear down process.
            // If we satisfied these visibility changes though, we would cause a visual glitch
            // hiding the window before it's replacement was available. So we just do nothing on
            // our side.
            // This must be called before the call to performSurfacePlacement.
            if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
                if (DEBUG_VISIBILITY) {
                    Slog.i(TAG_WM,
                            "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
                }
                result |= RELAYOUT_RES_SURFACE_CHANGED;
                if (!win.mWillReplaceWindow) {
                    focusMayChange = tryStartExitingAnimation(win, winAnimator, focusMayChange);
                }
            }

            // We may be deferring layout passes at the moment, but since the client is interested
            // in the new out values right now we need to force a layout.
            mWindowPlacerLocked.performSurfacePlacement(true /* force */);

            if (shouldRelayout) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");

                result = win.relayoutVisibleWindow(result, attrChanges);

                try {
                    result = createSurfaceControl(outSurfaceControl, outBLASTSurfaceControl,
                            result, win, winAnimator);
                } catch (Exception e) {
                    displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);

                    ProtoLog.w(WM_ERROR,
                            "Exception thrown when creating surface for client %s (%s). %s",
                            client, win.mAttrs.getTitle(), e);
                    Binder.restoreCallingIdentity(origId);
                    return 0;
                }
                if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
                    focusMayChange = true;
                }
                if (win.mAttrs.type == TYPE_INPUT_METHOD
                        && displayContent.mInputMethodWindow == null) {
                    displayContent.setInputMethodWindowLocked(win);
                    imMayMove = true;
                }
                win.adjustStartingWindowFlags();
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            } else {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2");

                winAnimator.mEnterAnimationPending = false;
                winAnimator.mEnteringAnimation = false;

                if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
                    // We already told the client to go invisible, but the message may not be
                    // handled yet, or it might want to draw a last frame. If we already have a
                    // surface, let the client use that, but don't create new surface at this point.
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
                    winAnimator.mSurfaceController.getSurfaceControl(outSurfaceControl);
                    winAnimator.mSurfaceController.getBLASTSurfaceControl(outBLASTSurfaceControl);
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                } else {
                    if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);

                    try {
                        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
                                + win.mAttrs.getTitle());
                        outSurfaceControl.release();
                    } finally {
                        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                    }
                }

                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            }

            if (focusMayChange) {
                if (updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/)) {
                    imMayMove = false;
                }
            }

            // updateFocusedWindowLocked() already assigned layers so we only need to
            // reassign them at this point if the IM window state gets shuffled
            boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
            if (imMayMove) {
                displayContent.computeImeTarget(true /* updateImeTarget */);
                if (toBeDisplayed) {
                    // Little hack here -- we -should- be able to rely on the function to return
                    // true if the IME has moved and needs its layer recomputed. However, if the IME
                    // was hidden and isn't actually moved in the list, its layer may be out of data
                    // so we make sure to recompute it.
                    displayContent.assignWindowLayers(false /* setLayoutNeeded */);
                }
            }

            if (wallpaperMayMove) {
                displayContent.pendingLayoutChanges |=
                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
            }

            if (win.mActivityRecord != null) {
                displayContent.mUnknownAppVisibilityController.notifyRelayouted(win.mActivityRecord);
            }

            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: updateOrientation");
            configChanged = displayContent.updateOrientation();
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);

            if (toBeDisplayed && win.mIsWallpaper) {
                displayContent.mWallpaperController.updateWallpaperOffset(win, false /* sync */);
            }
            if (win.mActivityRecord != null) {
                win.mActivityRecord.updateReportedVisibilityLocked();
            }
            if (winAnimator.mReportSurfaceResized) {
                winAnimator.mReportSurfaceResized = false;
                result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED;
            }
            if (displayPolicy.areSystemBarsForcedShownLw(win)) {
                result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
            }
            if (!win.isGoneForLayoutLw()) {
                win.mResizedWhileGone = false;
            }

            // We must always send the latest {@link MergedConfiguration}, regardless of whether we
            // have already reported it. The client might not have processed the previous value yet
            // and needs process it before handling the corresponding window frame. the variable
            // {@code mergedConfiguration} is an out parameter that will be passed back to the
            // client over IPC and checked there.
            // Note: in the cases where the window is tied to an activity, we should not send a
            // configuration update when the window has requested to be hidden. Doing so can lead
            // to the client erroneously accepting a configuration that would have otherwise caused
            // an activity restart. We instead hand back the last reported
            // {@link MergedConfiguration}.
            if (shouldRelayout) {
                win.getMergedConfiguration(mergedConfiguration);
            } else {
                win.getLastReportedMergedConfiguration(mergedConfiguration);
            }

            win.setLastReportedMergedConfiguration(mergedConfiguration);

            // Update the last inset values here because the values are sent back to the client.
            // The last inset values represent the last client state
            win.updateLastInsetValues();

            win.getCompatFrame(outFrame);
            win.getInsetsForRelayout(outContentInsets, outVisibleInsets,
                    outStableInsets);
            outCutout.set(win.getWmDisplayCutout().getDisplayCutout());
            outBackdropFrame.set(win.getBackdropFrame(win.getFrameLw()));
            outInsetsState.set(win.getInsetsState(), win.isClientLocal());
            if (DEBUG) {
                Slog.v(TAG_WM, "Relayout given client " + client.asBinder()
                        + ", requestedWidth=" + requestedWidth
                        + ", requestedHeight=" + requestedHeight
                        + ", viewVisibility=" + viewVisibility
                        + "\nRelayout returning frame=" + outFrame
                        + ", surface=" + outSurfaceControl);
            }

            ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
                    win, focusMayChange);

            result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;

            if (DEBUG_LAYOUT) {
                Slog.v(TAG_WM,
                        "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
            }
            win.mInRelayout = false;

            if (configChanged) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
                        "relayoutWindow: postNewConfigurationToHandler");
                displayContent.sendNewConfiguration();
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            }
            if (winAnimator.mSurfaceController != null) {
                outSurfaceSize.set(winAnimator.mSurfaceController.getWidth(),
                                         winAnimator.mSurfaceController.getHeight());
            }
            getInsetsSourceControls(win, outActiveControls);
        }

        Binder.restoreCallingIdentity(origId);
        return result;
    }

    private void getInsetsSourceControls(WindowState win, InsetsSourceControl[] outControls) {
        final InsetsSourceControl[] controls =
                win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win);
        if (controls != null) {
            final int length = Math.min(controls.length, outControls.length);
            for (int i = 0; i < length; i++) {
                // We will leave the critical section before returning the leash to the client,
                // so we need to copy the leash to prevent others release the one that we are
                // about to return.
                // TODO: We will have an extra copy if the client is not local.
                //       For now, we rely on GC to release it.
                //       Maybe we can modify InsetsSourceControl.writeToParcel so it can release
                //       the extra leash as soon as possible.
                outControls[i] = controls[i] != null
                        ? new InsetsSourceControl(controls[i]) : null;
            }
        }
    }

    private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator,
            boolean focusMayChange) {
        // Try starting an animation; if there isn't one, we
        // can destroy the surface right away.
        int transit = WindowManagerPolicy.TRANSIT_EXIT;
        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
        }
        if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
            focusMayChange = true;
            win.mAnimatingExit = true;
        } else if (win.isAnimating(TRANSITION | PARENTS)) {
            // Currently in a hide animation... turn this into
            // an exit.
            win.mAnimatingExit = true;
        } else if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
            // If the wallpaper is currently behind this
            // window, we need to change both of them inside
            // of a transaction to avoid artifacts.
            win.mAnimatingExit = true;
        } else {
            boolean stopped = win.mActivityRecord != null ? win.mActivityRecord.mAppStopped : true;
            // We set mDestroying=true so ActivityRecord#notifyAppStopped in-to destroy surfaces
            // will later actually destroy the surface if we do not do so here. Normally we leave
            // this to the exit animation.
            win.mDestroying = true;
            win.destroySurface(false, stopped);
        }
        if (mAccessibilityController != null) {
            mAccessibilityController.onWindowTransitionLocked(win, transit);
        }

        // When we start the exit animation we take the Surface from the client
        // so it will stop perturbing it. We need to likewise takeaway the SurfaceFlinger
        // side child surfaces, so they will remain preserved in their current state
        // (rather than be cleaned up immediately by the app code).
        SurfaceControl.openTransaction();
        winAnimator.detachChildren();
        SurfaceControl.closeTransaction();

        return focusMayChange;
    }

    private int createSurfaceControl(SurfaceControl outSurfaceControl,
            SurfaceControl outBLASTSurfaceControl, int result,
            WindowState win, WindowStateAnimator winAnimator) {
        if (!win.mHasSurface) {
            result |= RELAYOUT_RES_SURFACE_CHANGED;
        }

        WindowSurfaceController surfaceController;
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
            surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
        if (surfaceController != null) {
            surfaceController.getSurfaceControl(outSurfaceControl);
            surfaceController.getBLASTSurfaceControl(outBLASTSurfaceControl);
            ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);

        } else {
            // For some reason there isn't a surface.  Clear the
            // caller's object so they see the same state.
            ProtoLog.w(WM_ERROR, "Failed to create surface control for %s", win);
            outSurfaceControl.release();
        }

        return result;
    }

    public boolean outOfMemoryWindow(Session session, IWindow client) {
        final long origId = Binder.clearCallingIdentity();

        try {
            synchronized (mGlobalLock) {
                WindowState win = windowForClientLocked(session, client, false);
                if (win == null) {
                    return false;
                }
                return mRoot.reclaimSomeSurfaceMemory(win.mWinAnimator, "from-client", false);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    void finishDrawingWindow(Session session, IWindow client,
            @Nullable SurfaceControl.Transaction postDrawTransaction) {
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                WindowState win = windowForClientLocked(session, client, false);
                ProtoLog.d(WM_DEBUG_ADD_REMOVE, "finishDrawingWindow: %s mDrawState=%s",
                        win, (win != null ? win.mWinAnimator.drawStateToString() : "null"));
                if (win != null && win.finishDrawing(postDrawTransaction)) {
                    if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
                        win.getDisplayContent().pendingLayoutChanges |=
                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                    }
                    win.setDisplayLayoutNeeded();
                    mWindowPlacerLocked.requestTraversal();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    boolean checkCallingPermission(String permission, String func) {
        // Quick check: if the calling permission is me, it's all okay.
        if (Binder.getCallingPid() == myPid()) {
            return true;
        }

        if (mContext.checkCallingPermission(permission)
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        ProtoLog.w(WM_ERROR, "Permission Denial: %s from pid=%d, uid=%d requires %s",
                func, Binder.getCallingPid(), Binder.getCallingUid(), permission);
        return false;
    }

    @Override
    public void addWindowToken(IBinder binder, int type, int displayId) {
        addWindowTokenWithOptions(binder, type, displayId, null /* options */,
                null /* packageName */, false /* fromClientToken */);
    }

    @Override
    public int addWindowTokenWithOptions(IBinder binder, int type, int displayId, Bundle options,
            String packageName) {
        if (tokenCountExceed()) {
            return ADD_TOO_MANY_TOKENS;
        }
        return addWindowTokenWithOptions(binder, type, displayId, options, packageName,
                true /* fromClientToken */);
    }

    private boolean tokenCountExceed() {
        final int callingUid = Binder.getCallingUid();
        // Don't check if caller is from system server.
        if (callingUid == myPid()) {
            return false;
        }
        final int limit =
                (checkCallingPermission(STATUS_BAR_SERVICE, "addWindowTokenWithOptions"))
                        ?  MAXIMUM_WINDOW_TOKEN_COUNT_WITHOUT_SURFACE * SYSTEM_UI_MULTIPLIER
                        : MAXIMUM_WINDOW_TOKEN_COUNT_WITHOUT_SURFACE;
        synchronized (mGlobalLock) {
            int[] count = new int[1];
            mRoot.forAllDisplays(d -> count[0] += d.getWindowTokensWithoutSurfaceCount(callingUid));
            return count[0] >= limit;
        }
    }

    private int addWindowTokenWithOptions(IBinder binder, int type, int displayId, Bundle options,
            String packageName, boolean fromClientToken) {
        final boolean callerCanManageAppTokens =
                checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()");
        // WindowContext users usually don't hold MANAGE_APP_TOKEN permission. Check permissions
        // by checkAddPermission.
        if (!callerCanManageAppTokens) {
            final int res = mPolicy.checkAddPermission(type, false /* isRoundedCornerOverlay */,
                    packageName, new int[1]);
            if (res != ADD_OKAY) {
                return res;
            }
        }

        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                if (!callerCanManageAppTokens) {
                    if (packageName == null || !unprivilegedAppCanCreateTokenWith(
                            null /* parentWindow */, callingUid, type, type, binder,
                            packageName)) {
                        throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
                    }
                }

                final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
                if (dc == null) {
                    ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add token: %s"
                            + " for non-exiting displayId=%d", binder, displayId);
                    return WindowManagerGlobal.ADD_INVALID_DISPLAY;
                }

                WindowToken token = dc.getWindowToken(binder);
                if (token != null) {
                    ProtoLog.w(WM_ERROR, "addWindowToken: Attempted to add binder token: %s"
                            + " for already created window token: %s"
                            + " displayId=%d", binder, token, displayId);
                    return WindowManagerGlobal.ADD_DUPLICATE_ADD;
                }
                // TODO(window-container): Clean up dead tokens
                if (type == TYPE_WALLPAPER) {
                    new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens);
                } else {
                    new WindowToken(this, binder, type, true, dc, callerCanManageAppTokens,
                            callingUid, false /* roundedCornerOverlay */, fromClientToken);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
        return WindowManagerGlobal.ADD_OKAY;
    }

    @Override
    public boolean isWindowToken(IBinder binder) {
        synchronized (mGlobalLock) {
            final WindowToken windowToken = mRoot.getWindowToken(binder);
            if (windowToken == null) {
                return false;
            }
            // We don't allow activity tokens in WindowContext. TODO(window-context): rename method
            return windowToken.asActivityRecord() == null;
        }
    }

    @Override
    public void removeWindowToken(IBinder binder, int displayId) {
        final boolean callerCanManageAppTokens =
                checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()");
        final WindowToken windowToken;
        synchronized (mGlobalLock) {
            windowToken = mRoot.getWindowToken(binder);
        }
        if (windowToken == null) {
            ProtoLog.w(WM_ERROR,
                    "removeWindowToken: Attempted to remove non-existing token: %s", binder);
            return;
        }
        final int callingUid = Binder.getCallingUid();

        // If MANAGE_APP_TOKEN permission is not held(usually from WindowContext), callers can only
        // remove the window tokens which they added themselves.
        if (!callerCanManageAppTokens && (windowToken.getOwnerUid() == INVALID_UID
                || callingUid != windowToken.getOwnerUid())) {
            throw new SecurityException("removeWindowToken: Requires MANAGE_APP_TOKENS permission"
                    + " to remove token owned by another uid");
        }

        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s"
                            + " for non-exiting displayId=%d", binder, displayId);
                    return;
                }

                dc.removeWindowToken(binder);
                dc.getInputMonitor().updateInputWindowsLw(true /*force*/);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    void setNewDisplayOverrideConfiguration(Configuration overrideConfig,
            @NonNull DisplayContent dc) {
        if (dc.mWaitingForConfig) {
            dc.mWaitingForConfig = false;
            mLastFinishedFreezeSource = "new-config";
        }

        mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, dc);
    }

    // TODO(multi-display): remove when no default display use case.
    // (i.e. KeyguardController / RecentsAnimation)
    @Override
    public void prepareAppTransition(@TransitionType int transit, boolean alwaysKeepCurrent) {
        if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
        }
        getDefaultDisplayContentLocked().prepareAppTransition(transit,
                alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
    }

    @Override
    public void overridePendingAppTransitionMultiThumbFuture(
            IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
            boolean scaleUp, int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                Slog.w(TAG, "Attempted to call overridePendingAppTransitionMultiThumbFuture"
                        + " for the display " + displayId + " that does not exist.");
                return;
            }
            displayContent.mAppTransition.overridePendingAppTransitionMultiThumbFuture(specsFuture,
                    callback, scaleUp);
        }
    }

    @Override
    public void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter,
            int displayId) {
        if (!checkCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
                "overridePendingAppTransitionRemote()")) {
            throw new SecurityException(
                    "Requires CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS permission");
        }
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                Slog.w(TAG, "Attempted to call overridePendingAppTransitionRemote"
                        + " for the display " + displayId + " that does not exist.");
                return;
            }
            displayContent.mAppTransition.overridePendingAppTransitionRemote(
                    remoteAnimationAdapter);
        }
    }

    @Override
    public void endProlongedAnimations() {
        // TODO: Remove once clients are updated.
    }

    // TODO(multi-display): remove when no default display use case.
    // (i.e. KeyguardController / RecentsAnimation)
    @Override
    public void executeAppTransition() {
        if (!checkCallingPermission(MANAGE_APP_TOKENS, "executeAppTransition()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
        }
        getDefaultDisplayContentLocked().executeAppTransition();
    }

    void initializeRecentsAnimation(int targetActivityType,
            IRecentsAnimationRunner recentsAnimationRunner,
            RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId,
            SparseBooleanArray recentTaskIds, ActivityRecord targetActivity) {
        mRecentsAnimationController = new RecentsAnimationController(this, recentsAnimationRunner,
                callbacks, displayId);
        mRoot.getDisplayContent(displayId).mAppTransition.updateBooster();
        mRecentsAnimationController.initialize(targetActivityType, recentTaskIds, targetActivity);
    }

    @VisibleForTesting
    void setRecentsAnimationController(RecentsAnimationController controller) {
        mRecentsAnimationController = controller;
    }

    RecentsAnimationController getRecentsAnimationController() {
        return mRecentsAnimationController;
    }

    void cancelRecentsAnimation(
            @RecentsAnimationController.ReorderMode int reorderMode, String reason) {
        if (mRecentsAnimationController != null) {
            // This call will call through to cleanupAnimation() below after the animation is
            // canceled
            mRecentsAnimationController.cancelAnimation(reorderMode, reason);
        }
    }

    void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
        if (mRecentsAnimationController != null) {
            final RecentsAnimationController controller = mRecentsAnimationController;
            mRecentsAnimationController = null;
            controller.cleanupAnimation(reorderMode);
            // TODO(mult-display): currently only default display support recents animation.
            getDefaultDisplayContentLocked().mAppTransition.updateBooster();
        }
    }

    void setWindowOpaqueLocked(IBinder token, boolean isOpaque) {
        final ActivityRecord wtoken = mRoot.getActivityRecord(token);
        if (wtoken != null) {
            wtoken.setMainWindowOpaque(isOpaque);
        }
    }

    boolean isValidPictureInPictureAspectRatio(DisplayContent displayContent, float aspectRatio) {
        return displayContent.getPinnedStackController().isValidPictureInPictureAspectRatio(
                aspectRatio);
    }

    void getStackBounds(int windowingMode, int activityType, Rect bounds) {
        final ActivityStack stack = mRoot.getStack(windowingMode, activityType);
        if (stack != null) {
            stack.getBounds(bounds);
            return;
        }
        bounds.setEmpty();
    }

    /**
     * Notifies window manager that {@link DisplayPolicy#isShowingDreamLw} has changed.
     */
    public void notifyShowingDreamChanged() {
        // TODO(multi-display): support show dream in multi-display.
        notifyKeyguardFlagsChanged(null /* callback */, DEFAULT_DISPLAY);
    }

    @Override
    public WindowManagerPolicy.WindowState getInputMethodWindowLw() {
        return mRoot.getCurrentInputMethodWindow();
    }

    @Override
    public void notifyKeyguardTrustedChanged() {
        mAtmInternal.notifyKeyguardTrustedChanged();
    }

    @Override
    public void screenTurningOff(ScreenOffListener listener) {
        mTaskSnapshotController.screenTurningOff(listener);
    }

    @Override
    public void triggerAnimationFailsafe() {
        mH.sendEmptyMessage(H.ANIMATION_FAILSAFE);
    }

    @Override
    public void onKeyguardShowingAndNotOccludedChanged() {
        mH.sendEmptyMessage(H.RECOMPUTE_FOCUS);
    }

    @Override
    public void onPowerKeyDown(boolean isScreenOn) {
        final PooledConsumer c = PooledLambda.obtainConsumer(
                DisplayPolicy::onPowerKeyDown, PooledLambda.__(), isScreenOn);
        mRoot.forAllDisplayPolicies(c);
        c.recycle();
    }

    @Override
    public void onUserSwitched() {
        mSettingsObserver.updateSystemUiSettings();
        synchronized (mGlobalLock) {
            // force a re-application of focused window sysui visibility on each display.
            mRoot.forAllDisplayPolicies(DisplayPolicy::resetSystemUiVisibilityLw);
        }
    }

    @Override
    public void moveDisplayToTop(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null && mRoot.getTopChild() != displayContent) {
                displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
                        true /* includingParents */);
            }
        }
        syncInputTransactions();
    }

    /**
     * Notifies activity manager that some Keyguard flags have changed and that it needs to
     * reevaluate the visibilities of the activities.
     * @param callback Runnable to be called when activity manager is done reevaluating visibilities
     */
    void notifyKeyguardFlagsChanged(@Nullable Runnable callback, int displayId) {
        mAtmInternal.notifyKeyguardFlagsChanged(callback, displayId);
    }

    public void setKeyguardGoingAway(boolean keyguardGoingAway) {
        synchronized (mGlobalLock) {
            mKeyguardGoingAway = keyguardGoingAway;
        }
    }

    public void setKeyguardOrAodShowingOnDefaultDisplay(boolean showing) {
        synchronized (mGlobalLock) {
            mKeyguardOrAodShowingOnDefaultDisplay = showing;
        }
    }

    // -------------------------------------------------------------
    // Misc IWindowSession methods
    // -------------------------------------------------------------

    @Override
    public void startFreezingScreen(int exitAnim, int enterAnim) {
        if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
                "startFreezingScreen()")) {
            throw new SecurityException("Requires FREEZE_SCREEN permission");
        }

        synchronized (mGlobalLock) {
            if (!mClientFreezingScreen) {
                mClientFreezingScreen = true;
                final long origId = Binder.clearCallingIdentity();
                try {
                    startFreezingDisplay(exitAnim, enterAnim);
                    mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
                    mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
                } finally {
                    Binder.restoreCallingIdentity(origId);
                }
            }
        }
    }

    @Override
    public void stopFreezingScreen() {
        if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
                "stopFreezingScreen()")) {
            throw new SecurityException("Requires FREEZE_SCREEN permission");
        }

        synchronized (mGlobalLock) {
            if (mClientFreezingScreen) {
                mClientFreezingScreen = false;
                mLastFinishedFreezeSource = "client";
                final long origId = Binder.clearCallingIdentity();
                try {
                    stopFreezingDisplayLocked();
                } finally {
                    Binder.restoreCallingIdentity(origId);
                }
            }
        }
    }

    @Override
    public void disableKeyguard(IBinder token, String tag, int userId) {
        userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false /* allowAll */, ALLOW_FULL_ONLY, "disableKeyguard", null);
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
        }
        final int callingUid = Binder.getCallingUid();
        final long origIdentity = Binder.clearCallingIdentity();
        try {
            mKeyguardDisableHandler.disableKeyguard(token, tag, callingUid, userId);
        } finally {
            Binder.restoreCallingIdentity(origIdentity);
        }
    }

    @Override
    public void reenableKeyguard(IBinder token, int userId) {
        userId = mAmInternal.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false /* allowAll */, ALLOW_FULL_ONLY, "reenableKeyguard", null);
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
        }
        Objects.requireNonNull(token, "token is null");
        final int callingUid = Binder.getCallingUid();
        final long origIdentity = Binder.clearCallingIdentity();
        try {
            mKeyguardDisableHandler.reenableKeyguard(token, callingUid, userId);
        } finally {
            Binder.restoreCallingIdentity(origIdentity);
        }
    }

    /**
     * @see android.app.KeyguardManager#exitKeyguardSecurely
     */
    @Override
    public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
            != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
        }

        if (callback == null) {
            throw new IllegalArgumentException("callback == null");
        }

        mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
            @Override
            public void onKeyguardExitResult(boolean success) {
                try {
                    callback.onKeyguardExitResult(success);
                } catch (RemoteException e) {
                    // Client has died, we don't care.
                }
            }
        });
    }

    @Override
    public boolean isKeyguardLocked() {
        return mPolicy.isKeyguardLocked();
    }

    public boolean isKeyguardShowingAndNotOccluded() {
        return mPolicy.isKeyguardShowingAndNotOccluded();
    }

    @Override
    public boolean isKeyguardSecure(int userId) {
        if (userId != UserHandle.getCallingUserId()
                && !checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS,
                "isKeyguardSecure")) {
            throw new SecurityException("Requires INTERACT_ACROSS_USERS permission");
        }

        long origId = Binder.clearCallingIdentity();
        try {
            return mPolicy.isKeyguardSecure(userId);
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message) {
        if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
            throw new SecurityException("Requires CONTROL_KEYGUARD permission");
        }
        synchronized (mGlobalLock) {
            mPolicy.dismissKeyguardLw(callback, message);
        }
    }

    @Override
    public void setSwitchingUser(boolean switching) {
        if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                "setSwitchingUser()")) {
            throw new SecurityException("Requires INTERACT_ACROSS_USERS_FULL permission");
        }
        mPolicy.setSwitchingUser(switching);
        synchronized (mGlobalLock) {
            mSwitchingUser = switching;
        }
    }

    @RequiresPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW)
    @Override
    public void showGlobalActions() {
        if (!checkCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW,
                "showGlobalActions()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }
        mPolicy.showGlobalActions();
    }

    @Override
    public void closeSystemDialogs(String reason) {
        synchronized (mGlobalLock) {
            mRoot.closeSystemDialogs(reason);
        }
    }

    static float fixScale(float scale) {
        if (scale < 0) scale = 0;
        else if (scale > 20) scale = 20;
        return Math.abs(scale);
    }

    @Override
    public void setAnimationScale(int which, float scale) {
        if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
                "setAnimationScale()")) {
            throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
        }

        scale = fixScale(scale);
        switch (which) {
            case 0: mWindowAnimationScaleSetting = scale; break;
            case 1: mTransitionAnimationScaleSetting = scale; break;
            case 2: mAnimatorDurationScaleSetting = scale; break;
        }

        // Persist setting
        mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
    }

    @Override
    public void setAnimationScales(float[] scales) {
        if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
                "setAnimationScale()")) {
            throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
        }

        if (scales != null) {
            if (scales.length >= 1) {
                mWindowAnimationScaleSetting = fixScale(scales[0]);
            }
            if (scales.length >= 2) {
                mTransitionAnimationScaleSetting = fixScale(scales[1]);
            }
            if (scales.length >= 3) {
                mAnimatorDurationScaleSetting = fixScale(scales[2]);
                dispatchNewAnimatorScaleLocked(null);
            }
        }

        // Persist setting
        mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
    }

    private void setAnimatorDurationScale(float scale) {
        mAnimatorDurationScaleSetting = scale;
        ValueAnimator.setDurationScale(scale);
    }

    public float getWindowAnimationScaleLocked() {
        return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting;
    }

    public float getTransitionAnimationScaleLocked() {
        return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting;
    }

    @Override
    public float getAnimationScale(int which) {
        switch (which) {
            case 0: return mWindowAnimationScaleSetting;
            case 1: return mTransitionAnimationScaleSetting;
            case 2: return mAnimatorDurationScaleSetting;
        }
        return 0;
    }

    @Override
    public float[] getAnimationScales() {
        return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting,
                mAnimatorDurationScaleSetting };
    }

    @Override
    public float getCurrentAnimatorScale() {
        synchronized (mGlobalLock) {
            return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting;
        }
    }

    void dispatchNewAnimatorScaleLocked(Session session) {
        mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget();
    }

    @Override
    public void registerPointerEventListener(PointerEventListener listener, int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null) {
                displayContent.registerPointerEventListener(listener);
            }
        }
    }

    @Override
    public void unregisterPointerEventListener(PointerEventListener listener, int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null) {
                displayContent.unregisterPointerEventListener(listener);
            }
        }
    }

    // Called by window manager policy. Not exposed externally.
    @Override
    public int getLidState() {
        int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
                InputManagerService.SW_LID);
        if (sw > 0) {
            // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
            return LID_CLOSED;
        } else if (sw == 0) {
            // Switch state: AKEY_STATE_UP.
            return LID_OPEN;
        } else {
            // Switch state: AKEY_STATE_UNKNOWN.
            return LID_ABSENT;
        }
    }

    // Called by window manager policy. Not exposed externally.
    @Override
    public void lockDeviceNow() {
        lockNow(null);
    }

    // Called by window manager policy. Not exposed externally.
    @Override
    public int getCameraLensCoverState() {
        int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
                InputManagerService.SW_CAMERA_LENS_COVER);
        if (sw > 0) {
            // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
            return CAMERA_LENS_COVERED;
        } else if (sw == 0) {
            // Switch state: AKEY_STATE_UP.
            return CAMERA_LENS_UNCOVERED;
        } else {
            // Switch state: AKEY_STATE_UNKNOWN.
            return CAMERA_LENS_COVER_ABSENT;
        }
    }

    // Called by window manager policy.  Not exposed externally.
    @Override
    public void switchKeyboardLayout(int deviceId, int direction) {
        mInputManager.switchKeyboardLayout(deviceId, direction);
    }

    // Called by window manager policy.  Not exposed externally.
    @Override
    public void shutdown(boolean confirm) {
        // Pass in the UI context, since ShutdownThread requires it (to show UI).
        ShutdownThread.shutdown(ActivityThread.currentActivityThread().getSystemUiContext(),
                PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
    }

    // Called by window manager policy.  Not exposed externally.
    @Override
    public void reboot(boolean confirm) {
        // Pass in the UI context, since ShutdownThread requires it (to show UI).
        ShutdownThread.reboot(ActivityThread.currentActivityThread().getSystemUiContext(),
                PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
    }

    // Called by window manager policy.  Not exposed externally.
    @Override
    public void rebootSafeMode(boolean confirm) {
        // Pass in the UI context, since ShutdownThread requires it (to show UI).
        ShutdownThread.rebootSafeMode(ActivityThread.currentActivityThread().getSystemUiContext(),
                confirm);
    }

    public void setCurrentProfileIds(final int[] currentProfileIds) {
        synchronized (mGlobalLock) {
            mCurrentProfileIds = currentProfileIds;
        }
    }

    public void setCurrentUser(final int newUserId, final int[] currentProfileIds) {
        synchronized (mGlobalLock) {
            mCurrentUserId = newUserId;
            mCurrentProfileIds = currentProfileIds;
            mPolicy.setCurrentUserLw(newUserId);
            mKeyguardDisableHandler.setCurrentUser(newUserId);

            // Hide windows that should not be seen by the new user.
            mRoot.switchUser(newUserId);
            mWindowPlacerLocked.performSurfacePlacement();

            // Notify whether the docked stack exists for the current user
            final DisplayContent displayContent = getDefaultDisplayContentLocked();

            mRoot.forAllDisplays(dc -> dc.mAppTransition.setCurrentUser(newUserId));

            // If the display is already prepared, update the density.
            // Otherwise, we'll update it when it's prepared.
            if (mDisplayReady) {
                final int forcedDensity = getForcedDisplayDensityForUserLocked(newUserId);
                final int targetDensity = forcedDensity != 0 ? forcedDensity
                        : displayContent.mInitialDisplayDensity;
                displayContent.setForcedDensity(targetDensity, UserHandle.USER_CURRENT);
            }
        }
    }

    /* Called by WindowState */
    boolean isCurrentProfile(int userId) {
        if (userId == mCurrentUserId) return true;
        for (int i = 0; i < mCurrentProfileIds.length; i++) {
            if (mCurrentProfileIds[i] == userId) return true;
        }
        return false;
    }

    public void enableScreenAfterBoot() {
        synchronized (mGlobalLock) {
            ProtoLog.i(WM_DEBUG_BOOT, "enableScreenAfterBoot: mDisplayEnabled=%b "
                            + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
                            + "%s",
                    mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
                    new RuntimeException("here").fillInStackTrace());
            if (mSystemBooted) {
                return;
            }
            mSystemBooted = true;
            hideBootMessagesLocked();
            // If the screen still doesn't come up after 30 seconds, give
            // up and turn it on.
            mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000);
        }

        mPolicy.systemBooted();

        performEnableScreen();
    }

    @Override
    public void enableScreenIfNeeded() {
        synchronized (mGlobalLock) {
            enableScreenIfNeededLocked();
        }
    }

    void enableScreenIfNeededLocked() {
        ProtoLog.i(WM_DEBUG_BOOT, "enableScreenIfNeededLocked: mDisplayEnabled=%b "
                        + "mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. "
                        + "%s",
                mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted,
                new RuntimeException("here").fillInStackTrace());
        if (mDisplayEnabled) {
            return;
        }
        if (!mSystemBooted && !mShowingBootMessages) {
            return;
        }
        mH.sendEmptyMessage(H.ENABLE_SCREEN);
    }

    public void performBootTimeout() {
        synchronized (mGlobalLock) {
            if (mDisplayEnabled) {
                return;
            }
            ProtoLog.w(WM_ERROR, "***** BOOT TIMEOUT: forcing display enabled");
            mForceDisplayEnabled = true;
        }
        performEnableScreen();
    }

    /**
     * Called when System UI has been started.
     */
    public void onSystemUiStarted() {
        mPolicy.onSystemUiStarted();
    }

    private void performEnableScreen() {
        synchronized (mGlobalLock) {
            ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b"
                            + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b"
                            + " mSystemBooted=%b mOnlyCore=%b. %s", mDisplayEnabled,
                    mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore,
                    new RuntimeException("here").fillInStackTrace());
            if (mDisplayEnabled) {
                return;
            }
            if (!mSystemBooted && !mShowingBootMessages) {
                return;
            }

            if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {
                return;
            }

            // Don't enable the screen until all existing windows have been drawn.
            if (!mForceDisplayEnabled) {
                for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
                    if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) {
                        return;
                    }
                }
            }

            if (!mBootAnimationStopped) {
                Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
                // stop boot animation
                // formerly we would just kill the process, but we now ask it to exit so it
                // can choose where to stop the animation.
                SystemProperties.set("service.bootanim.exit", "1");
                mBootAnimationStopped = true;
            }

            if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
                ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete");
                return;
            }

            try {
                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                if (surfaceFlinger != null) {
                    ProtoLog.i(WM_ERROR, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                    Parcel data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
                            data, null, 0);
                    data.recycle();
                }
            } catch (RemoteException ex) {
                ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!");
            }

            EventLogTags.writeWmBootAnimationDone(SystemClock.uptimeMillis());
            Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
            mDisplayEnabled = true;
            ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!");

            // Enable input dispatch.
            mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled);
        }

        try {
            mActivityManager.bootAnimationComplete();
        } catch (RemoteException e) {
        }

        mPolicy.enableScreenAfterBoot();

        // Make sure the last requested orientation has been applied.
        updateRotationUnchecked(false, false);
    }

    private boolean checkBootAnimationCompleteLocked() {
        if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
            mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
            mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
                    BOOT_ANIMATION_POLL_INTERVAL);
            ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Waiting for anim complete");
            return false;
        }
        ProtoLog.i(WM_DEBUG_BOOT, "checkBootAnimationComplete: Animation complete!");
        return true;
    }

    public void showBootMessage(final CharSequence msg, final boolean always) {
        boolean first = false;
        synchronized (mGlobalLock) {
            ProtoLog.i(WM_DEBUG_BOOT, "showBootMessage: msg=%s always=%b"
                            + " mAllowBootMessages=%b mShowingBootMessages=%b"
                            + " mSystemBooted=%b. %s", msg, always, mAllowBootMessages,
                    mShowingBootMessages, mSystemBooted,
                    new RuntimeException("here").fillInStackTrace());
            if (!mAllowBootMessages) {
                return;
            }
            if (!mShowingBootMessages) {
                if (!always) {
                    return;
                }
                first = true;
            }
            if (mSystemBooted) {
                return;
            }
            mShowingBootMessages = true;
            mPolicy.showBootMessage(msg, always);
        }
        if (first) {
            performEnableScreen();
        }
    }

    public void hideBootMessagesLocked() {
        ProtoLog.i(WM_DEBUG_BOOT, "hideBootMessagesLocked: mDisplayEnabled=%b"
                        + " mForceDisplayEnabled=%b mShowingBootMessages=%b"
                        + " mSystemBooted=%b. %s", mDisplayEnabled, mForceDisplayEnabled,
                mShowingBootMessages, mSystemBooted,
                new RuntimeException("here").fillInStackTrace());
        if (mShowingBootMessages) {
            mShowingBootMessages = false;
            mPolicy.hideBootMessages();
        }
    }

    @Override
    public void setInTouchMode(boolean mode) {
        synchronized (mGlobalLock) {
            mInTouchMode = mode;
        }
        mInputManager.setInTouchMode(mode);
    }

    boolean getInTouchMode() {
        synchronized (mGlobalLock) {
            return mInTouchMode;
        }
    }

    public void showEmulatorDisplayOverlayIfNeeded() {
        if (mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay)
                && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false)
                && Build.IS_EMULATOR) {
            mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY));
        }
    }

    public void showEmulatorDisplayOverlay() {
        synchronized (mGlobalLock) {

            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM, ">>> showEmulatorDisplayOverlay");
            if (mEmulatorDisplayOverlay == null) {
                mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(mSurfaceFactory, mContext,
                        getDefaultDisplayContentLocked(),
                        mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER)
                                * TYPE_LAYER_MULTIPLIER + 10, mTransaction);
            }
            mEmulatorDisplayOverlay.setVisibility(true, mTransaction);
            mTransaction.apply();
        }
    }

    // TODO: more accounting of which pid(s) turned it on, keep count,
    // only allow disables from pids which have count on, etc.
    @Override
    public void showStrictModeViolation(boolean on) {
        final int pid = Binder.getCallingPid();
        if (on) {
            // Show the visualization, and enqueue a second message to tear it
            // down if we don't hear back from the app.
            mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 1, pid));
            mH.sendMessageDelayed(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid),
                    DateUtils.SECOND_IN_MILLIS);
        } else {
            mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid));
        }
    }

    private void showStrictModeViolation(int arg, int pid) {
        final boolean on = arg != 0;
        synchronized (mGlobalLock) {
            // Ignoring requests to enable the red border from clients which aren't on screen.
            // (e.g. Broadcast Receivers in the background..)
            if (on && !mRoot.canShowStrictModeViolation(pid)) {
                return;
            }

            if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM, ">>> showStrictModeViolation");
            // TODO: Modify this to use the surface trace once it is not going crazy.
            // b/31532461
            // TODO(multi-display): support multiple displays
            if (mStrictModeFlash == null) {
                mStrictModeFlash = new StrictModeFlash(mSurfaceFactory,
                        getDefaultDisplayContentLocked(), mTransaction);
            }
            mStrictModeFlash.setVisibility(on, mTransaction);
            mTransaction.apply();
        }
    }

    @Override
    public void setStrictModeVisualIndicatorPreference(String value) {
        SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
    }

    @Override
    public Bitmap screenshotWallpaper() {
        if (!checkCallingPermission(READ_FRAME_BUFFER, "screenshotWallpaper()")) {
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
            synchronized (mGlobalLock) {
                // TODO(b/115486823) Screenshot at secondary displays if needed.
                final DisplayContent dc = mRoot.getDisplayContent(DEFAULT_DISPLAY);
                return dc.mWallpaperController.screenshotWallpaperLocked();
            }
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

    /**
     * Takes a snapshot of the screen.  In landscape mode this grabs the whole screen.
     * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
     * of the target image.
     */
    @Override
    public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) {
        if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) {
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }

        final Bitmap bm;
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(DEFAULT_DISPLAY);
            if (displayContent == null) {
                if (DEBUG_SCREENSHOT) {
                    Slog.i(TAG_WM, "Screenshot returning null. No Display for displayId="
                            + DEFAULT_DISPLAY);
                }
                bm = null;
            } else {
                bm = displayContent.screenshotDisplayLocked(Bitmap.Config.ARGB_8888);
            }
        }

        FgThread.getHandler().post(() -> {
            try {
                receiver.onHandleAssistScreenshot(bm);
            } catch (RemoteException e) {
            }
        });

        return true;
    }

    /**
     * Retrieves a snapshot. If restoreFromDisk equals equals {@code true}, DO NOT HOLD THE WINDOW
     * MANAGER LOCK WHEN CALLING THIS METHOD!
     */
    public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean isLowResolution,
            boolean restoreFromDisk) {
        return mTaskSnapshotController.getSnapshot(taskId, userId, restoreFromDisk,
                isLowResolution);
    }

    /**
     * In case a task write/delete operation was lost because the system crashed, this makes sure to
     * clean up the directory to remove obsolete files.
     *
     * @param persistentTaskIds A set of task ids that exist in our in-memory model.
     * @param runningUserIds The ids of the list of users that have tasks loaded in our in-memory
     *                       model.
     */
    public void removeObsoleteTaskFiles(ArraySet<Integer> persistentTaskIds, int[] runningUserIds) {
        synchronized (mGlobalLock) {
            mTaskSnapshotController.removeObsoleteTaskFiles(persistentTaskIds, runningUserIds);
        }
    }

    @Override
    public void setFixedToUserRotation(int displayId, int fixedToUserRotation) {
        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                "freezeRotation()")) {
            throw new SecurityException("Requires SET_ORIENTATION permission");
        }
        synchronized (mGlobalLock) {
            final DisplayContent display = mRoot.getDisplayContent(displayId);
            if (display == null) {
                Slog.w(TAG, "Trying to set rotate for app for a missing display.");
                return;
            }
            display.getDisplayRotation().setFixedToUserRotation(fixedToUserRotation);
        }
    }

    @Override
    public void freezeRotation(int rotation) {
        freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation);
    }

    /**
     * Freeze rotation changes.  (Enable "rotation lock".)
     * Persists across reboots.
     * @param displayId The ID of the display to freeze.
     * @param rotation The desired rotation to freeze to, or -1 to use the current rotation.
     */
    @Override
    public void freezeDisplayRotation(int displayId, int rotation) {
        // TODO(multi-display): Track which display is rotated.
        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                "freezeRotation()")) {
            throw new SecurityException("Requires SET_ORIENTATION permission");
        }
        if (rotation < -1 || rotation > Surface.ROTATION_270) {
            throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
                    + "rotation constant.");
        }

        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent display = mRoot.getDisplayContent(displayId);
                if (display == null) {
                    Slog.w(TAG, "Trying to freeze rotation for a missing display.");
                    return;
                }
                display.getDisplayRotation().freezeRotation(rotation);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        updateRotationUnchecked(false, false);
    }

    @Override
    public void thawRotation() {
        thawDisplayRotation(Display.DEFAULT_DISPLAY);
    }

    /**
     * Thaw rotation changes.  (Disable "rotation lock".)
     * Persists across reboots.
     */
    @Override
    public void thawDisplayRotation(int displayId) {
        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                "thawRotation()")) {
            throw new SecurityException("Requires SET_ORIENTATION permission");
        }

        ProtoLog.v(WM_DEBUG_ORIENTATION, "thawRotation: mRotation=%d", getDefaultDisplayRotation());

        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent display = mRoot.getDisplayContent(displayId);
                if (display == null) {
                    Slog.w(TAG, "Trying to thaw rotation for a missing display.");
                    return;
                }
                display.getDisplayRotation().thawRotation();
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        updateRotationUnchecked(false, false);
    }

    @Override
    public boolean isRotationFrozen() {
        return isDisplayRotationFrozen(Display.DEFAULT_DISPLAY);
    }

    @Override
    public boolean isDisplayRotationFrozen(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent display = mRoot.getDisplayContent(displayId);
            if (display == null) {
                Slog.w(TAG, "Trying to thaw rotation for a missing display.");
                return false;
            }
            return display.getDisplayRotation().isRotationFrozen();
        }
    }

    /**
     * Recalculate the current rotation.
     *
     * Called by the window manager policy whenever the state of the system changes
     * such that the current rotation might need to be updated, such as when the
     * device is docked or rotated into a new posture.
     */
    @Override
    public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
        updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
    }

    private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
        ProtoLog.v(WM_DEBUG_ORIENTATION, "updateRotationUnchecked:"
                        + " alwaysSendConfiguration=%b forceRelayout=%b",
                alwaysSendConfiguration, forceRelayout);

        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");

        long origId = Binder.clearCallingIdentity();

        try {
            synchronized (mGlobalLock) {
                boolean layoutNeeded = false;
                final int displayCount = mRoot.mChildren.size();
                for (int i = 0; i < displayCount; ++i) {
                    final DisplayContent displayContent = mRoot.mChildren.get(i);
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
                    final boolean rotationChanged = displayContent.updateRotationUnchecked();
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);

                    if (rotationChanged) {
                        mAtmService.getTaskChangeNotificationController()
                                .notifyOnActivityRotation(displayContent.mDisplayId);
                    }

                    if (!rotationChanged || forceRelayout) {
                        displayContent.setLayoutNeeded();
                        layoutNeeded = true;
                    }
                    if (rotationChanged || alwaysSendConfiguration) {
                        displayContent.sendNewConfiguration();
                    }
                }

                if (layoutNeeded) {
                    Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
                            "updateRotation: performSurfacePlacement");
                    mWindowPlacerLocked.performSurfacePlacement();
                    Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

    @Override
    public int getDefaultDisplayRotation() {
        synchronized (mGlobalLock) {
            return getDefaultDisplayContentLocked().getRotation();
        }
    }

    @Override
    public void setDisplayWindowRotationController(IDisplayWindowRotationController controller) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_ACTIVITY_STACKS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_ACTIVITY_STACKS);
        }
        try {
            synchronized (mGlobalLock) {
                if (mDisplayRotationController != null) {
                    mDisplayRotationController.asBinder().unlinkToDeath(
                            mDisplayRotationControllerDeath, 0);
                    mDisplayRotationController = null;
                }
                controller.asBinder().linkToDeath(mDisplayRotationControllerDeath, 0);
                mDisplayRotationController = controller;
            }
        } catch (RemoteException e) {
            throw new RuntimeException("Unable to set rotation controller");
        }
    }

    @Override
    public SurfaceControl addShellRoot(int displayId, IWindow client, int windowType) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    return null;
                }
                return dc.addShellRoot(client, windowType);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public void setShellRootAccessibilityWindow(int displayId, int windowType, IWindow target) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    return;
                }
                ShellRoot root = dc.mShellRoots.get(windowType);
                if (root == null) {
                    return;
                }
                root.setAccessibilityWindow(target);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public void setDisplayWindowInsetsController(
            int displayId, IDisplayWindowInsetsController insetsController) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    return;
                }
                dc.setRemoteInsetsController(insetsController);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public void modifyDisplayWindowInsets(int displayId, InsetsState state) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null || dc.mRemoteInsetsControlTarget == null) {
                    return;
                }
                dc.getInsetsStateController().onInsetsModified(
                        dc.mRemoteInsetsControlTarget, state);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public int watchRotation(IRotationWatcher watcher, int displayId) {
        final DisplayContent displayContent;
        synchronized (mGlobalLock) {
            displayContent = mRoot.getDisplayContent(displayId);
        }
        if (displayContent == null) {
            throw new IllegalArgumentException("Trying to register rotation event "
                    + "for invalid display: " + displayId);
        }

        final IBinder watcherBinder = watcher.asBinder();
        IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
            @Override
            public void binderDied() {
                synchronized (mGlobalLock) {
                    for (int i=0; i<mRotationWatchers.size(); i++) {
                        if (watcherBinder == mRotationWatchers.get(i).mWatcher.asBinder()) {
                            RotationWatcher removed = mRotationWatchers.remove(i);
                            IBinder binder = removed.mWatcher.asBinder();
                            if (binder != null) {
                                binder.unlinkToDeath(this, 0);
                            }
                            i--;
                        }
                    }
                }
            }
        };

        synchronized (mGlobalLock) {
            try {
                watcher.asBinder().linkToDeath(dr, 0);
                mRotationWatchers.add(new RotationWatcher(watcher, dr, displayId));
            } catch (RemoteException e) {
                // Client died, no cleanup needed.
            }

            return displayContent.getRotation();
        }
    }

    @Override
    public void removeRotationWatcher(IRotationWatcher watcher) {
        final IBinder watcherBinder = watcher.asBinder();
        synchronized (mGlobalLock) {
            for (int i=0; i<mRotationWatchers.size(); i++) {
                RotationWatcher rotationWatcher = mRotationWatchers.get(i);
                if (watcherBinder == rotationWatcher.mWatcher.asBinder()) {
                    RotationWatcher removed = mRotationWatchers.remove(i);
                    IBinder binder = removed.mWatcher.asBinder();
                    if (binder != null) {
                        binder.unlinkToDeath(removed.mDeathRecipient, 0);
                    }
                    i--;
                }
            }
        }
    }

    @Override
    public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
            int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                throw new IllegalArgumentException("Trying to register visibility event "
                        + "for invalid display: " + displayId);
            }
            mWallpaperVisibilityListeners.registerWallpaperVisibilityListener(listener, displayId);
            return displayContent.mWallpaperController.isWallpaperVisible();
        }
    }

    @Override
    public void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
            int displayId) {
        synchronized (mGlobalLock) {
            mWallpaperVisibilityListeners
                    .unregisterWallpaperVisibilityListener(listener, displayId);
        }
    }

    @Override
    public void registerSystemGestureExclusionListener(ISystemGestureExclusionListener listener,
            int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                throw new IllegalArgumentException("Trying to register visibility event "
                        + "for invalid display: " + displayId);
            }
            displayContent.registerSystemGestureExclusionListener(listener);
        }
    }

    @Override
    public void unregisterSystemGestureExclusionListener(ISystemGestureExclusionListener listener,
            int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                throw new IllegalArgumentException("Trying to register visibility event "
                        + "for invalid display: " + displayId);
            }
            displayContent.unregisterSystemGestureExclusionListener(listener);
        }
    }

    void reportSystemGestureExclusionChanged(Session session, IWindow window,
            List<Rect> exclusionRects) {
        synchronized (mGlobalLock) {
            final WindowState win = windowForClientLocked(session, window, true);
            if (win.setSystemGestureExclusion(exclusionRects)) {
                win.getDisplayContent().updateSystemGestureExclusion();
            }
        }
    }

    @Override
    public void registerDisplayFoldListener(IDisplayFoldListener listener) {
        mPolicy.registerDisplayFoldListener(listener);
    }

    @Override
    public void unregisterDisplayFoldListener(IDisplayFoldListener listener) {
        mPolicy.unregisterDisplayFoldListener(listener);
    }

    /**
     * Overrides the folded area.
     *
     * @param area the overriding folded area or an empty {@code Rect} to clear the override.
     */
    void setOverrideFoldedArea(@NonNull Rect area) {
        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
        }

        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                mPolicy.setOverrideFoldedArea(area);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    /**
     * Get the display folded area.
     */
    @NonNull Rect getFoldedArea() {
        long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                return mPolicy.getFoldedArea();
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    /** Registers a hierarchy listener that gets callbacks when the hierarchy changes. */
    @Override
    public void registerDisplayWindowListener(IDisplayWindowListener listener) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_ACTIVITY_STACKS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_ACTIVITY_STACKS);
        }
        long ident = Binder.clearCallingIdentity();
        try {
            mDisplayNotificationController.registerListener(listener);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    /** Unregister a hierarchy listener so that it stops receiving callbacks. */
    @Override
    public void unregisterDisplayWindowListener(IDisplayWindowListener listener) {
        if (mContext.checkCallingOrSelfPermission(MANAGE_ACTIVITY_STACKS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + MANAGE_ACTIVITY_STACKS);
        }
        mDisplayNotificationController.unregisterListener(listener);
    }

    @Override
    public int getPreferredOptionsPanelGravity(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                return Gravity.CENTER | Gravity.BOTTOM;
            }
            return displayContent.getPreferredOptionsPanelGravity();
        }
    }

    /**
     * Starts the view server on the specified port.
     *
     * @param port The port to listener to.
     *
     * @return True if the server was successfully started, false otherwise.
     *
     * @see com.android.server.wm.ViewServer
     * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
     */
    @Override
    public boolean startViewServer(int port) {
        if (isSystemSecure()) {
            return false;
        }

        if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
            return false;
        }

        if (port < 1024) {
            return false;
        }

        if (mViewServer != null) {
            if (!mViewServer.isRunning()) {
                try {
                    return mViewServer.start();
                } catch (IOException e) {
                    ProtoLog.w(WM_ERROR, "View server did not start");
                }
            }
            return false;
        }

        try {
            mViewServer = new ViewServer(this, port);
            return mViewServer.start();
        } catch (IOException e) {
            ProtoLog.w(WM_ERROR, "View server did not start");
        }
        return false;
    }

    private boolean isSystemSecure() {
        return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
                "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
    }

    /**
     * Stops the view server if it exists.
     *
     * @return True if the server stopped, false if it wasn't started or
     *         couldn't be stopped.
     *
     * @see com.android.server.wm.ViewServer
     */
    @Override
    public boolean stopViewServer() {
        if (isSystemSecure()) {
            return false;
        }

        if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
            return false;
        }

        if (mViewServer != null) {
            return mViewServer.stop();
        }
        return false;
    }

    /**
     * Indicates whether the view server is running.
     *
     * @return True if the server is running, false otherwise.
     *
     * @see com.android.server.wm.ViewServer
     */
    @Override
    public boolean isViewServerRunning() {
        if (isSystemSecure()) {
            return false;
        }

        if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
            return false;
        }

        return mViewServer != null && mViewServer.isRunning();
    }

    /**
     * Lists all available windows in the system. The listing is written in the specified Socket's
     * output stream with the following syntax: windowHashCodeInHexadecimal windowName
     * Each line of the output represents a different window.
     *
     * @param client The remote client to send the listing to.
     * @return false if an error occurred, true otherwise.
     */
    boolean viewServerListWindows(Socket client) {
        if (isSystemSecure()) {
            return false;
        }

        boolean result = true;

        final ArrayList<WindowState> windows = new ArrayList();
        synchronized (mGlobalLock) {
            mRoot.forAllWindows(w -> {
                windows.add(w);
            }, false /* traverseTopToBottom */);
        }

        BufferedWriter out = null;

        // Any uncaught exception will crash the system process
        try {
            OutputStream clientStream = client.getOutputStream();
            out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);

            final int count = windows.size();
            for (int i = 0; i < count; i++) {
                final WindowState w = windows.get(i);
                out.write(Integer.toHexString(System.identityHashCode(w)));
                out.write(' ');
                out.append(w.mAttrs.getTitle());
                out.write('\n');
            }

            out.write("DONE.\n");
            out.flush();
        } catch (Exception e) {
            result = false;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    result = false;
                }
            }
        }

        return result;
    }

    // TODO(multidisplay): Extend to multiple displays.
    /**
     * Returns the focused window in the following format:
     * windowHashCodeInHexadecimal windowName
     *
     * @param client The remote client to send the listing to.
     * @return False if an error occurred, true otherwise.
     */
    boolean viewServerGetFocusedWindow(Socket client) {
        if (isSystemSecure()) {
            return false;
        }

        boolean result = true;

        WindowState focusedWindow = getFocusedWindow();

        BufferedWriter out = null;

        // Any uncaught exception will crash the system process
        try {
            OutputStream clientStream = client.getOutputStream();
            out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);

            if(focusedWindow != null) {
                out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
                out.write(' ');
                out.append(focusedWindow.mAttrs.getTitle());
            }
            out.write('\n');
            out.flush();
        } catch (Exception e) {
            result = false;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    result = false;
                }
            }
        }

        return result;
    }

    /**
     * Sends a command to a target window. The result of the command, if any, will be
     * written in the output stream of the specified socket.
     *
     * The parameters must follow this syntax:
     * windowHashcode extra
     *
     * Where XX is the length in characeters of the windowTitle.
     *
     * The first parameter is the target window. The window with the specified hashcode
     * will be the target. If no target can be found, nothing happens. The extra parameters
     * will be delivered to the target window and as parameters to the command itself.
     *
     * @param client The remote client to sent the result, if any, to.
     * @param command The command to execute.
     * @param parameters The command parameters.
     *
     * @return True if the command was successfully delivered, false otherwise. This does
     *         not indicate whether the command itself was successful.
     */
    boolean viewServerWindowCommand(Socket client, String command, String parameters) {
        if (isSystemSecure()) {
            return false;
        }

        boolean success = true;
        Parcel data = null;
        Parcel reply = null;

        BufferedWriter out = null;

        // Any uncaught exception will crash the system process
        try {
            // Find the hashcode of the window
            int index = parameters.indexOf(' ');
            if (index == -1) {
                index = parameters.length();
            }
            final String code = parameters.substring(0, index);
            int hashCode = (int) Long.parseLong(code, 16);

            // Extract the command's parameter after the window description
            if (index < parameters.length()) {
                parameters = parameters.substring(index + 1);
            } else {
                parameters = "";
            }

            final WindowState window = findWindow(hashCode);
            if (window == null) {
                return false;
            }

            data = Parcel.obtain();
            data.writeInterfaceToken("android.view.IWindow");
            data.writeString(command);
            data.writeString(parameters);
            data.writeInt(1);
            ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);

            reply = Parcel.obtain();

            final IBinder binder = window.mClient.asBinder();
            // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
            binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);

            reply.readException();

            if (!client.isOutputShutdown()) {
                out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
                out.write("DONE\n");
                out.flush();
            }

        } catch (Exception e) {
            ProtoLog.w(WM_ERROR, "Could not send command %s with parameters %s. %s", command,
                    parameters, e);
            success = false;
        } finally {
            if (data != null) {
                data.recycle();
            }
            if (reply != null) {
                reply.recycle();
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {

                }
            }
        }

        return success;
    }

    public void addWindowChangeListener(WindowChangeListener listener) {
        synchronized (mGlobalLock) {
            mWindowChangeListeners.add(listener);
        }
    }

    public void removeWindowChangeListener(WindowChangeListener listener) {
        synchronized (mGlobalLock) {
            mWindowChangeListeners.remove(listener);
        }
    }

    private void notifyWindowsChanged() {
        WindowChangeListener[] windowChangeListeners;
        synchronized (mGlobalLock) {
            if(mWindowChangeListeners.isEmpty()) {
                return;
            }
            windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
            windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
        }
        int N = windowChangeListeners.length;
        for(int i = 0; i < N; i++) {
            windowChangeListeners[i].windowsChanged();
        }
    }

    private void notifyFocusChanged() {
        WindowChangeListener[] windowChangeListeners;
        synchronized (mGlobalLock) {
            if(mWindowChangeListeners.isEmpty()) {
                return;
            }
            windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
            windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
        }
        int N = windowChangeListeners.length;
        for(int i = 0; i < N; i++) {
            windowChangeListeners[i].focusChanged();
        }
    }

    private WindowState findWindow(int hashCode) {
        if (hashCode == -1) {
            // TODO(multidisplay): Extend to multiple displays.
            return getFocusedWindow();
        }

        synchronized (mGlobalLock) {
            return mRoot.getWindow((w) -> System.identityHashCode(w) == hashCode);
        }
    }

    public Configuration computeNewConfiguration(int displayId) {
        synchronized (mGlobalLock) {
            return computeNewConfigurationLocked(displayId);
        }
    }

    private Configuration computeNewConfigurationLocked(int displayId) {
        if (!mDisplayReady) {
            return null;
        }
        final Configuration config = new Configuration();
        final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
        displayContent.computeScreenConfiguration(config);
        return config;
    }

    void notifyHardKeyboardStatusChange() {
        final boolean available;
        final WindowManagerInternal.OnHardKeyboardStatusChangeListener listener;
        synchronized (mGlobalLock) {
            listener = mHardKeyboardStatusChangeListener;
            available = mHardKeyboardAvailable;
        }
        if (listener != null) {
            listener.onHardKeyboardStatusChange(available);
        }
    }

    // -------------------------------------------------------------
    // Input Events and Focus Management
    // -------------------------------------------------------------

    final InputManagerCallback mInputManagerCallback = new InputManagerCallback(this);
    private boolean mEventDispatchingEnabled;

    @Override
    public void setEventDispatching(boolean enabled) {
        if (!checkCallingPermission(MANAGE_APP_TOKENS, "setEventDispatching()")) {
            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
        }

        synchronized (mGlobalLock) {
            mEventDispatchingEnabled = enabled;
            if (mDisplayEnabled) {
                mInputManagerCallback.setEventDispatchingLw(enabled);
            }
        }
    }

    private WindowState getFocusedWindow() {
        synchronized (mGlobalLock) {
            return getFocusedWindowLocked();
        }
    }

    private WindowState getFocusedWindowLocked() {
        // Return the focused window in the focused display.
        return mRoot.getTopFocusedDisplayContent().mCurrentFocus;
    }

    ActivityStack getImeFocusStackLocked() {
        // Don't use mCurrentFocus.getStack() because it returns home stack for system windows.
        // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE
        // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved
        // to make room for IME, but the window is not the focused window that's taking input.
        // TODO (b/111080190): Consider the case of multiple IMEs on multi-display.
        final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent();
        final ActivityRecord focusedApp = topFocusedDisplay.mFocusedApp;
        return (focusedApp != null && focusedApp.getTask() != null)
                ? focusedApp.getTask().getStack() : null;
    }

    public boolean detectSafeMode() {
        if (!mInputManagerCallback.waitForInputDevicesReady(
                INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
            ProtoLog.w(WM_ERROR, "Devices still not ready after waiting %d"
                            + " milliseconds before attempting to detect safe mode.",
                    INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS);
        }

        if (Settings.Global.getInt(
                mContext.getContentResolver(), Settings.Global.SAFE_BOOT_DISALLOWED, 0) != 0) {
            return false;
        }

        int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
                KeyEvent.KEYCODE_MENU);
        int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
        int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
                KeyEvent.KEYCODE_DPAD_CENTER);
        int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
                InputManagerService.BTN_MOUSE);
        int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
                KeyEvent.KEYCODE_VOLUME_DOWN);
        mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
                || volumeDownState > 0;
        try {
            if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0
                    || SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) != 0) {
                mSafeMode = true;
                SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
            }
        } catch (IllegalArgumentException e) {
        }
        if (mSafeMode) {
            ProtoLog.i(WM_ERROR, "SAFE MODE ENABLED (menu=%d s=%d dpad=%d"
                    + " trackball=%d)", menuState, sState, dpadState, trackballState);
            // May already be set if (for instance) this process has crashed
            if (SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) == 0) {
                SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1");
            }
        } else {
            ProtoLog.i(WM_ERROR, "SAFE MODE not enabled");
        }
        mPolicy.setSafeMode(mSafeMode);
        return mSafeMode;
    }

    public void displayReady() {
        synchronized (mGlobalLock) {
            if (mMaxUiWidth > 0) {
                mRoot.forAllDisplays(displayContent -> displayContent.setMaxUiWidth(mMaxUiWidth));
            }
            applyForcedPropertiesForDefaultDisplay();
            mAnimator.ready();
            mDisplayReady = true;
            // Reconfigure all displays to make sure that forced properties and
            // DisplayWindowSettings are applied.
            mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
            mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_TOUCHSCREEN);
        }

        try {
            mActivityTaskManager.updateConfiguration(null);
        } catch (RemoteException e) {
        }
    }

    public void systemReady() {
        mSystemReady = true;
        mPolicy.systemReady();
        mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
        mTaskSnapshotController.systemReady();
        mHasWideColorGamutSupport = queryWideColorGamutSupport();
        mHasHdrSupport = queryHdrSupport();
        UiThread.getHandler().post(mSettingsObserver::loadSettings);
        IVrManager vrManager = IVrManager.Stub.asInterface(
                ServiceManager.getService(Context.VR_SERVICE));
        if (vrManager != null) {
            try {
                final boolean vrModeEnabled = vrManager.getVrModeState();
                synchronized (mGlobalLock) {
                    vrManager.registerListener(mVrStateCallbacks);
                    if (vrModeEnabled) {
                        mVrModeEnabled = vrModeEnabled;
                        mVrStateCallbacks.onVrStateChanged(vrModeEnabled);
                    }
                }
            } catch (RemoteException e) {
                // Ignore, we cannot do anything if we failed to register VR mode listener
            }
        }
    }

    private static boolean queryWideColorGamutSupport() {
        boolean defaultValue = false;
        Optional<Boolean> hasWideColorProp = SurfaceFlingerProperties.has_wide_color_display();
        if (hasWideColorProp.isPresent()) {
            return hasWideColorProp.get();
        }
        try {
            ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
            OptionalBool hasWideColor = surfaceFlinger.hasWideColorDisplay();
            if (hasWideColor != null) {
                return hasWideColor.value;
            }
        } catch (RemoteException e) {
            // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
        } catch (NoSuchElementException e) {
            return defaultValue;
        }
        return false;
    }

    private static boolean queryHdrSupport() {
        boolean defaultValue = false;
        Optional<Boolean> hasHdrProp = SurfaceFlingerProperties.has_HDR_display();
        if (hasHdrProp.isPresent()) {
            return hasHdrProp.get();
        }
        try {
            ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
            OptionalBool hasHdr = surfaceFlinger.hasHDRDisplay();
            if (hasHdr != null) {
                return hasHdr.value;
            }
        } catch (RemoteException e) {
            // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
        } catch (NoSuchElementException e) {
            return defaultValue;
        }
        return false;
    }

    // -------------------------------------------------------------
    // Async Handler
    // -------------------------------------------------------------

    final class H extends android.os.Handler {
        public static final int REPORT_FOCUS_CHANGE = 2;
        public static final int REPORT_LOSING_FOCUS = 3;
        public static final int WINDOW_FREEZE_TIMEOUT = 11;

        public static final int PERSIST_ANIMATION_SCALE = 14;
        public static final int FORCE_GC = 15;
        public static final int ENABLE_SCREEN = 16;
        public static final int APP_FREEZE_TIMEOUT = 17;
        public static final int REPORT_WINDOWS_CHANGE = 19;

        public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
        public static final int BOOT_TIMEOUT = 23;
        public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
        public static final int SHOW_STRICT_MODE_VIOLATION = 25;

        public static final int CLIENT_FREEZE_TIMEOUT = 30;
        public static final int NOTIFY_ACTIVITY_DRAWN = 32;

        public static final int ALL_WINDOWS_DRAWN = 33;

        public static final int NEW_ANIMATOR_SCALE = 34;

        public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36;

        public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37;
        public static final int RESET_ANR_MESSAGE = 38;
        public static final int WALLPAPER_DRAW_PENDING_TIMEOUT = 39;

        public static final int UPDATE_MULTI_WINDOW_STACKS = 41;

        public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;

        public static final int UPDATE_ANIMATION_SCALE = 51;
        public static final int WINDOW_HIDE_TIMEOUT = 52;
        public static final int SEAMLESS_ROTATION_TIMEOUT = 54;
        public static final int RESTORE_POINTER_ICON = 55;
        public static final int SET_HAS_OVERLAY_UI = 58;
        public static final int ANIMATION_FAILSAFE = 60;
        public static final int RECOMPUTE_FOCUS = 61;
        public static final int ON_POINTER_DOWN_OUTSIDE_FOCUS = 62;
        public static final int LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED = 63;
        public static final int WINDOW_STATE_BLAST_SYNC_TIMEOUT = 64;

        /**
         * Used to denote that an integer field in a message will not be used.
         */
        public static final int UNUSED = 0;

        @Override
        public void handleMessage(Message msg) {
            if (DEBUG_WINDOW_TRACE) {
                Slog.v(TAG_WM, "handleMessage: entry what=" + msg.what);
            }
            switch (msg.what) {
                case REPORT_FOCUS_CHANGE: {
                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                    WindowState lastFocus;
                    WindowState newFocus;

                    AccessibilityController accessibilityController = null;

                    synchronized (mGlobalLock) {
                        if (mAccessibilityController != null) {
                            accessibilityController = mAccessibilityController;
                        }

                        lastFocus = displayContent.mLastFocus;
                        newFocus = displayContent.mCurrentFocus;
                        if (lastFocus == newFocus) {
                            // Focus is not changing, so nothing to do.
                            return;
                        }
                        displayContent.mLastFocus = newFocus;
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Focus moving from %s"
                                        + " to %s displayId=%d", lastFocus, newFocus,
                                displayContent.getDisplayId());
                        if (newFocus != null && lastFocus != null && !newFocus.isDisplayedLw()) {
                            ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Delaying loss of focus...");
                            displayContent.mLosingFocus.add(lastFocus);
                            lastFocus = null;
                        }
                    }

                    // First notify the accessibility manager for the change so it has
                    // the windows before the newly focused one starts firing events.
                    if (accessibilityController != null) {
                        accessibilityController.onWindowFocusChangedNotLocked(
                                displayContent.getDisplayId());
                    }

                    if (newFocus != null) {
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Gaining focus: %s", newFocus);
                        newFocus.reportFocusChangedSerialized(true);
                        notifyFocusChanged();
                    }

                    if (lastFocus != null) {
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing focus: %s", lastFocus);
                        lastFocus.reportFocusChangedSerialized(false);
                    }
                    break;
                }

                case REPORT_LOSING_FOCUS: {
                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                    ArrayList<WindowState> losers;

                    synchronized (mGlobalLock) {
                        losers = displayContent.mLosingFocus;
                        displayContent.mLosingFocus = new ArrayList<>();
                    }

                    final int N = losers.size();
                    for (int i = 0; i < N; i++) {
                        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing delayed focus: %s",
                                losers.get(i));
                        losers.get(i).reportFocusChangedSerialized(false);
                    }
                    break;
                }

                case WINDOW_FREEZE_TIMEOUT: {
                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                    synchronized (mGlobalLock) {
                        displayContent.onWindowFreezeTimeout();
                    }
                    break;
                }

                case PERSIST_ANIMATION_SCALE: {
                    Settings.Global.putFloat(mContext.getContentResolver(),
                            Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
                    Settings.Global.putFloat(mContext.getContentResolver(),
                            Settings.Global.TRANSITION_ANIMATION_SCALE,
                            mTransitionAnimationScaleSetting);
                    Settings.Global.putFloat(mContext.getContentResolver(),
                            Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting);
                    break;
                }

                case UPDATE_ANIMATION_SCALE: {
                    @UpdateAnimationScaleMode
                    final int mode = msg.arg1;
                    switch (mode) {
                        case WINDOW_ANIMATION_SCALE: {
                            mWindowAnimationScaleSetting = Settings.Global.getFloat(
                                    mContext.getContentResolver(),
                                    Settings.Global.WINDOW_ANIMATION_SCALE,
                                    mWindowAnimationScaleSetting);
                            break;
                        }
                        case TRANSITION_ANIMATION_SCALE: {
                            mTransitionAnimationScaleSetting = Settings.Global.getFloat(
                                    mContext.getContentResolver(),
                                    Settings.Global.TRANSITION_ANIMATION_SCALE,
                                    mTransitionAnimationScaleSetting);
                            break;
                        }
                        case ANIMATION_DURATION_SCALE: {
                            mAnimatorDurationScaleSetting = Settings.Global.getFloat(
                                    mContext.getContentResolver(),
                                    Settings.Global.ANIMATOR_DURATION_SCALE,
                                    mAnimatorDurationScaleSetting);
                            dispatchNewAnimatorScaleLocked(null);
                            break;
                        }
                    }
                    break;
                }

                case FORCE_GC: {
                    synchronized (mGlobalLock) {
                        // Since we're holding both mWindowMap and mAnimator we don't need to
                        // hold mAnimator.mLayoutToAnim.
                        if (mAnimator.isAnimationScheduled()) {
                            // If we are animating, don't do the gc now but
                            // delay a bit so we don't interrupt the animation.
                            sendEmptyMessageDelayed(H.FORCE_GC, 2000);
                            return;
                        }
                        // If we are currently rotating the display, it will
                        // schedule a new message when done.
                        if (mDisplayFrozen) {
                            return;
                        }
                    }
                    Runtime.getRuntime().gc();
                    break;
                }

                case ENABLE_SCREEN: {
                    performEnableScreen();
                    break;
                }

                case APP_FREEZE_TIMEOUT: {
                    synchronized (mGlobalLock) {
                        ProtoLog.w(WM_ERROR, "App freeze timeout expired.");
                        mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
                        for (int i = mAppFreezeListeners.size() - 1; i >= 0; --i) {
                            mAppFreezeListeners.get(i).onAppFreezeTimeout();
                        }
                    }
                    break;
                }

                case CLIENT_FREEZE_TIMEOUT: {
                    synchronized (mGlobalLock) {
                        if (mClientFreezingScreen) {
                            mClientFreezingScreen = false;
                            mLastFinishedFreezeSource = "client-timeout";
                            stopFreezingDisplayLocked();
                        }
                    }
                    break;
                }

                case REPORT_WINDOWS_CHANGE: {
                    if (mWindowsChanged) {
                        synchronized (mGlobalLock) {
                            mWindowsChanged = false;
                        }
                        notifyWindowsChanged();
                    }
                    break;
                }

                case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
                    notifyHardKeyboardStatusChange();
                    break;
                }

                case BOOT_TIMEOUT: {
                    performBootTimeout();
                    break;
                }

                case WAITING_FOR_DRAWN_TIMEOUT: {
                    Runnable callback = null;
                    final WindowContainer container = (WindowContainer) msg.obj;
                    synchronized (mGlobalLock) {
                        ProtoLog.w(WM_ERROR, "Timeout waiting for drawn: undrawn=%s",
                                container.mWaitingForDrawn);
                        container.mWaitingForDrawn.clear();
                        callback = mWaitingForDrawnCallbacks.remove(container);
                    }
                    if (callback != null) {
                        callback.run();
                    }
                    break;
                }

                case SHOW_STRICT_MODE_VIOLATION: {
                    showStrictModeViolation(msg.arg1, msg.arg2);
                    break;
                }

                case SHOW_EMULATOR_DISPLAY_OVERLAY: {
                    showEmulatorDisplayOverlay();
                    break;
                }

                case NOTIFY_ACTIVITY_DRAWN: {
                    try {
                        mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj);
                    } catch (RemoteException e) {
                    }
                    break;
                }
                case ALL_WINDOWS_DRAWN: {
                    Runnable callback;
                    final WindowContainer container = (WindowContainer) msg.obj;
                    synchronized (mGlobalLock) {
                        callback = mWaitingForDrawnCallbacks.remove(container);
                    }
                    if (callback != null) {
                        callback.run();
                    }
                    break;
                }
                case NEW_ANIMATOR_SCALE: {
                    float scale = getCurrentAnimatorScale();
                    ValueAnimator.setDurationScale(scale);
                    Session session = (Session)msg.obj;
                    if (session != null) {
                        try {
                            session.mCallback.onAnimatorScaleChanged(scale);
                        } catch (RemoteException e) {
                        }
                    } else {
                        ArrayList<IWindowSessionCallback> callbacks
                                = new ArrayList<IWindowSessionCallback>();
                        synchronized (mGlobalLock) {
                            for (int i=0; i<mSessions.size(); i++) {
                                callbacks.add(mSessions.valueAt(i).mCallback);
                            }

                        }
                        for (int i=0; i<callbacks.size(); i++) {
                            try {
                                callbacks.get(i).onAnimatorScaleChanged(scale);
                            } catch (RemoteException e) {
                            }
                        }
                    }
                    break;
                }
                case CHECK_IF_BOOT_ANIMATION_FINISHED: {
                    final boolean bootAnimationComplete;
                    synchronized (mGlobalLock) {
                        ProtoLog.i(WM_DEBUG_BOOT, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
                        bootAnimationComplete = checkBootAnimationCompleteLocked();
                    }
                    if (bootAnimationComplete) {
                        performEnableScreen();
                    }
                    break;
                }
                case RESET_ANR_MESSAGE: {
                    synchronized (mGlobalLock) {
                        mLastANRState = null;
                    }
                    mAtmInternal.clearSavedANRState();
                    break;
                }
                case WALLPAPER_DRAW_PENDING_TIMEOUT: {
                    synchronized (mGlobalLock) {
                        final WallpaperController wallpaperController =
                                (WallpaperController) msg.obj;
                        if (wallpaperController != null
                                && wallpaperController.processWallpaperDrawPendingTimeout()) {
                            mWindowPlacerLocked.performSurfacePlacement();
                        }
                    }
                    break;
                }
                case UPDATE_MULTI_WINDOW_STACKS: {
                    synchronized (mGlobalLock) {
                        final DisplayContent displayContent = getDefaultDisplayContentLocked();
                        if (displayContent != null) {
                            displayContent.adjustForImeIfNeeded();
                        }
                    }
                    break;
                }
                case WINDOW_REPLACEMENT_TIMEOUT: {
                    synchronized (mGlobalLock) {
                        for (int i = mWindowReplacementTimeouts.size() - 1; i >= 0; i--) {
                            final ActivityRecord activity = mWindowReplacementTimeouts.get(i);
                            activity.onWindowReplacementTimeout();
                        }
                        mWindowReplacementTimeouts.clear();
                    }
                    break;
                }
                case WINDOW_HIDE_TIMEOUT: {
                    final WindowState window = (WindowState) msg.obj;
                    synchronized (mGlobalLock) {
                        // TODO: This is all about fixing b/21693547
                        // where partially initialized Toasts get stuck
                        // around and keep the screen on. We'd like
                        // to just remove the toast...but this can cause clients
                        // who miss the timeout due to normal circumstances (e.g.
                        // running under debugger) to crash (b/29105388). The windows will
                        // eventually be removed when the client process finishes.
                        // The best we can do for now is remove the FLAG_KEEP_SCREEN_ON
                        // and prevent the symptoms of b/21693547. Since apps don't
                        // support windows being removed under them we hide the window
                        // and it will be removed when the app dies.
                        window.mAttrs.flags &= ~FLAG_KEEP_SCREEN_ON;
                        window.hidePermanentlyLw();
                        window.setDisplayLayoutNeeded();
                        mWindowPlacerLocked.performSurfacePlacement();
                    }
                    break;
                }
                case RESTORE_POINTER_ICON: {
                    synchronized (mGlobalLock) {
                        restorePointerIconLocked((DisplayContent)msg.obj, msg.arg1, msg.arg2);
                    }
                    break;
                }
                case SEAMLESS_ROTATION_TIMEOUT: {
                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                    synchronized (mGlobalLock) {
                        displayContent.getDisplayRotation().onSeamlessRotationTimeout();
                    }
                    break;
                }
                case SET_HAS_OVERLAY_UI: {
                    mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
                    break;
                }
                case ANIMATION_FAILSAFE: {
                    synchronized (mGlobalLock) {
                        if (mRecentsAnimationController != null) {
                            mRecentsAnimationController.scheduleFailsafe();
                        }
                    }
                    break;
                }
                case RECOMPUTE_FOCUS: {
                    synchronized (mGlobalLock) {
                        updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
                                true /* updateInputWindows */);
                    }
                    break;
                }
                case ON_POINTER_DOWN_OUTSIDE_FOCUS: {
                    synchronized (mGlobalLock) {
                        final IBinder touchedToken = (IBinder) msg.obj;
                        onPointerDownOutsideFocusLocked(touchedToken);
                    }
                    break;
                }
                case LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED: {
                    synchronized (mGlobalLock) {
                        final DisplayContent displayContent = (DisplayContent) msg.obj;
                        displayContent.layoutAndAssignWindowLayersIfNeeded();
                    }
                    break;
                }
                case WINDOW_STATE_BLAST_SYNC_TIMEOUT: {
                    synchronized (mGlobalLock) {
                      final WindowState ws = (WindowState) msg.obj;
                      ws.finishDrawing(null);
                    }
                    break;
                }
            }
            if (DEBUG_WINDOW_TRACE) {
                Slog.v(TAG_WM, "handleMessage: exit");
            }
        }

        /** Remove the previous messages with the same 'what' and 'obj' then send the new one. */
        void sendNewMessageDelayed(int what, Object obj, long delayMillis) {
            removeMessages(what, obj);
            sendMessageDelayed(obtainMessage(what, obj), delayMillis);
        }
    }

    void destroyPreservedSurfaceLocked() {
        for (int i = mDestroyPreservedSurface.size() - 1; i >= 0 ; i--) {
            final WindowState w = mDestroyPreservedSurface.get(i);
            w.mWinAnimator.destroyPreservedSurfaceLocked();
        }
        mDestroyPreservedSurface.clear();
    }

    // -------------------------------------------------------------
    // IWindowManager API
    // -------------------------------------------------------------

    @Override
    public IWindowSession openSession(IWindowSessionCallback callback) {
        return new Session(this, callback);
    }

    @Override
    public boolean useBLAST() {
        return mUseBLAST;
    }

    @Override
    public void getInitialDisplaySize(int displayId, Point size) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                size.x = displayContent.mInitialDisplayWidth;
                size.y = displayContent.mInitialDisplayHeight;
            }
        }
    }

    @Override
    public void getBaseDisplaySize(int displayId, Point size) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                size.x = displayContent.mBaseDisplayWidth;
                size.y = displayContent.mBaseDisplayHeight;
            }
        }
    }

    @Override
    public void setForcedDisplaySize(int displayId, int width, int height) {
        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
        }

        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.setForcedSize(width, height);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    @Override
    public void setForcedDisplayScalingMode(int displayId, int mode) {
        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
        }

        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.setForcedScalingMode(mode);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    /** The global settings only apply to default display. */
    private boolean applyForcedPropertiesForDefaultDisplay() {
        boolean changed = false;
        final DisplayContent displayContent = getDefaultDisplayContentLocked();
        // Display size.
        String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
                Settings.Global.DISPLAY_SIZE_FORCED);
        if (sizeStr == null || sizeStr.length() == 0) {
            sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
        }
        if (sizeStr != null && sizeStr.length() > 0) {
            final int pos = sizeStr.indexOf(',');
            if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
                int width, height;
                try {
                    width = Integer.parseInt(sizeStr.substring(0, pos));
                    height = Integer.parseInt(sizeStr.substring(pos + 1));
                    if (displayContent.mBaseDisplayWidth != width
                            || displayContent.mBaseDisplayHeight != height) {
                        ProtoLog.i(WM_ERROR, "FORCED DISPLAY SIZE: %dx%d", width, height);
                        displayContent.updateBaseDisplayMetrics(width, height,
                                displayContent.mBaseDisplayDensity);
                        changed = true;
                    }
                } catch (NumberFormatException ex) {
                }
            }
        }

        // Display density.
        final int density = getForcedDisplayDensityForUserLocked(mCurrentUserId);
        if (density != 0 && density != displayContent.mBaseDisplayDensity) {
            displayContent.mBaseDisplayDensity = density;
            changed = true;
        }

        // Display scaling mode.
        int mode = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.DISPLAY_SCALING_FORCE, 0);
        if (displayContent.mDisplayScalingDisabled != (mode != 0)) {
            ProtoLog.i(WM_ERROR, "FORCED DISPLAY SCALING DISABLED");
            displayContent.mDisplayScalingDisabled = true;
            changed = true;
        }
        return changed;
    }

    @Override
    public void clearForcedDisplaySize(int displayId) {
        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
        }

        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.setForcedSize(displayContent.mInitialDisplayWidth,
                            displayContent.mInitialDisplayHeight);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    @Override
    public int getInitialDisplayDensity(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                return displayContent.mInitialDisplayDensity;
            }
        }
        return -1;
    }

    @Override
    public int getBaseDisplayDensity(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
                return displayContent.mBaseDisplayDensity;
            }
        }
        return -1;
    }

    @Override
    public void setForcedDisplayDensityForUser(int displayId, int density, int userId) {
        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
        }

        final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser",
                null);
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.setForcedDensity(density, targetUserId);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    @Override
    public void clearForcedDisplayDensityForUser(int displayId, int userId) {
        if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
        }

        final int callingUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                Binder.getCallingUid(), userId, false, true, "clearForcedDisplayDensityForUser",
                null);
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.setForcedDensity(displayContent.mInitialDisplayDensity,
                            callingUserId);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    /**
     * @param userId the ID of the user
     * @return the forced display density for the specified user, if set, or
     *         {@code 0} if not set
     */
    private int getForcedDisplayDensityForUserLocked(int userId) {
        String densityStr = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                Settings.Secure.DISPLAY_DENSITY_FORCED, userId);
        if (densityStr == null || densityStr.length() == 0) {
            densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
        }
        if (densityStr != null && densityStr.length() > 0) {
            try {
                return Integer.parseInt(densityStr);
            } catch (NumberFormatException ex) {
            }
        }
        return 0;
    }

    @Override
    public void startWindowTrace(){
        mWindowTracing.startTrace(null /* printwriter */);
    }

    @Override
    public void stopWindowTrace(){
        mWindowTracing.stopTrace(null /* printwriter */);
    }

    @Override
    public boolean isWindowTraceEnabled() {
        return mWindowTracing.isEnabled();
    }

    // -------------------------------------------------------------
    // Internals
    // -------------------------------------------------------------

    final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) {
        return windowForClientLocked(session, client.asBinder(), throwOnError);
    }

    final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
        WindowState win = mWindowMap.get(client);
        if (DEBUG) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
        if (win == null) {
            if (throwOnError) {
                throw new IllegalArgumentException(
                        "Requested window " + client + " does not exist");
            }
            ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
                    Debug.getCallers(3));
            return null;
        }
        if (session != null && win.mSession != session) {
            if (throwOnError) {
                throw new IllegalArgumentException("Requested window " + client + " is in session "
                        + win.mSession + ", not " + session);
            }
            ProtoLog.w(WM_ERROR, "Failed looking up window session=%s callers=%s", session,
                    Debug.getCallers(3));
            return null;
        }

        return win;
    }

    void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
        // If the screen is currently frozen or off, then keep
        // it frozen/off until this window draws at its new
        // orientation.
        if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
            ProtoLog.v(WM_DEBUG_ORIENTATION, "Changing surface while display frozen: %s", w);
            w.setOrientationChanging(true);
            w.mLastFreezeDuration = 0;
            mRoot.mOrientationChangeComplete = false;
            if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
                mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
                // XXX should probably keep timeout from
                // when we first froze the display.
                mH.sendNewMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, w.getDisplayContent(),
                        WINDOW_FREEZE_TIMEOUT_DURATION);
            }
        }
    }

    void checkDrawnWindowsLocked() {
        if (mWaitingForDrawnCallbacks.isEmpty()) {
            return;
        }
        mWaitingForDrawnCallbacks.forEach((container, callback) -> {
            for (int j = container.mWaitingForDrawn.size() - 1; j >= 0; j--) {
                final WindowState win = (WindowState) container.mWaitingForDrawn.get(j);
                ProtoLog.i(WM_DEBUG_SCREEN_ON,
                        "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
                        win, win.mRemoved, win.isVisibleLw(), win.mHasSurface,
                        win.mWinAnimator.mDrawState);
                if (win.mRemoved || !win.mHasSurface || !win.isVisibleByPolicy()) {
                    // Window has been removed or hidden; no draw will now happen, so stop waiting.
                    ProtoLog.w(WM_DEBUG_SCREEN_ON, "Aborted waiting for drawn: %s", win);
                    container.mWaitingForDrawn.remove(win);
                } else if (win.hasDrawnLw()) {
                    // Window is now drawn (and shown).
                    ProtoLog.d(WM_DEBUG_SCREEN_ON, "Window drawn win=%s", win);
                    container.mWaitingForDrawn.remove(win);
                }
            }
            if (container.mWaitingForDrawn.isEmpty()) {
                ProtoLog.d(WM_DEBUG_SCREEN_ON, "All windows drawn!");
                mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
                mH.sendMessage(mH.obtainMessage(H.ALL_WINDOWS_DRAWN, container));
            }
        });
    }

    void setHoldScreenLocked(final Session newHoldScreen) {
        final boolean hold = newHoldScreen != null;

        if (hold && mHoldingScreenOn != newHoldScreen) {
            mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
        }
        mHoldingScreenOn = newHoldScreen;

        final boolean state = mHoldingScreenWakeLock.isHeld();
        if (hold != state) {
            if (hold) {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to %s",
                            mRoot.mHoldScreenWindow);
                mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow;
                mLastWakeLockObscuringWindow = null;
                mHoldingScreenWakeLock.acquire();
                mPolicy.keepScreenOnStartedLw();
            } else {
                ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by %s",
                            mRoot.mObscuringWindow);
                mLastWakeLockHoldingWindow = null;
                mLastWakeLockObscuringWindow = mRoot.mObscuringWindow;
                mPolicy.keepScreenOnStoppedLw();
                mHoldingScreenWakeLock.release();
            }
        }
    }

    void requestTraversal() {
        mWindowPlacerLocked.requestTraversal();
    }

    /** Note that Locked in this case is on mLayoutToAnim */
    void scheduleAnimationLocked() {
        if (mAnimator != null) {
            mAnimator.scheduleAnimation();
        }
    }

    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
        boolean changed = mRoot.updateFocusedWindowLocked(mode, updateInputWindows);
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        return changed;
    }

    void startFreezingDisplay(int exitAnim, int enterAnim) {
        startFreezingDisplay(exitAnim, enterAnim, getDefaultDisplayContentLocked());
    }

    void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent) {
        startFreezingDisplay(exitAnim, enterAnim, displayContent,
                ROTATION_UNDEFINED /* overrideOriginalRotation */);
    }

    void startFreezingDisplay(int exitAnim, int enterAnim, DisplayContent displayContent,
            int overrideOriginalRotation) {
        if (mDisplayFrozen || displayContent.getDisplayRotation().isRotatingSeamlessly()) {
            return;
        }

        if (!displayContent.isReady() || !mPolicy.isScreenOn() || !displayContent.okToAnimate()) {
            // No need to freeze the screen before the display is ready,  if the screen is off,
            // or we can't currently animate.
            return;
        }

        ProtoLog.d(WM_DEBUG_ORIENTATION,
                            "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s",
                            exitAnim, enterAnim, Debug.getCallers(8));
        mScreenFrozenLock.acquire();

        mDisplayFrozen = true;
        mDisplayFreezeTime = SystemClock.elapsedRealtime();
        mLastFinishedFreezeSource = null;

        // {@link mDisplayFrozen} prevents us from freezing on multiple displays at the same time.
        // As a result, we only track the display that has initially froze the screen.
        mFrozenDisplayId = displayContent.getDisplayId();

        mInputManagerCallback.freezeInputDispatchingLw();

        if (displayContent.mAppTransition.isTransitionSet()) {
            displayContent.mAppTransition.freeze();
        }

        if (PROFILE_ORIENTATION) {
            File file = new File("/data/system/frozen");
            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
        }

        mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
        mExitAnimId = exitAnim;
        mEnterAnimId = enterAnim;

        displayContent.updateDisplayInfo();
        final int originalRotation = overrideOriginalRotation != ROTATION_UNDEFINED
                ? overrideOriginalRotation
                : displayContent.getDisplayInfo().rotation;
        displayContent.setRotationAnimation(new ScreenRotationAnimation(displayContent,
                originalRotation));
    }

    void stopFreezingDisplayLocked() {
        if (!mDisplayFrozen) {
            return;
        }

        final DisplayContent displayContent = mRoot.getDisplayContent(mFrozenDisplayId);
        final boolean waitingForConfig = displayContent != null && displayContent.mWaitingForConfig;
        final int numOpeningApps = displayContent != null ? displayContent.mOpeningApps.size() : 0;
        if (waitingForConfig || mAppsFreezingScreen > 0
                || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
                || mClientFreezingScreen || numOpeningApps > 0) {
            ProtoLog.d(WM_DEBUG_ORIENTATION,
                                "stopFreezingDisplayLocked: Returning mWaitingForConfig=%b, "
                                        + "mAppsFreezingScreen=%d, mWindowsFreezingScreen=%d, "
                                        + "mClientFreezingScreen=%b, mOpeningApps.size()=%d",
                                waitingForConfig, mAppsFreezingScreen, mWindowsFreezingScreen,
                                mClientFreezingScreen, numOpeningApps);
            return;
        }

        ProtoLog.d(WM_DEBUG_ORIENTATION,
                    "stopFreezingDisplayLocked: Unfreezing now");


        // We must make a local copy of the displayId as it can be potentially overwritten later on
        // in this method. For example, {@link startFreezingDisplayLocked} may be called as a result
        // of update rotation, but we reference the frozen display after that call in this method.
        final int displayId = mFrozenDisplayId;
        mFrozenDisplayId = INVALID_DISPLAY;
        mDisplayFrozen = false;
        mInputManagerCallback.thawInputDispatchingLw();
        mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
        StringBuilder sb = new StringBuilder(128);
        sb.append("Screen frozen for ");
        TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
        if (mLastFinishedFreezeSource != null) {
            sb.append(" due to ");
            sb.append(mLastFinishedFreezeSource);
        }
        ProtoLog.i(WM_ERROR, "%s", sb.toString());
        mH.removeMessages(H.APP_FREEZE_TIMEOUT);
        mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
        if (PROFILE_ORIENTATION) {
            Debug.stopMethodTracing();
        }

        boolean updateRotation = false;

        ScreenRotationAnimation screenRotationAnimation = displayContent == null ? null
                : displayContent.getRotationAnimation();
        if (screenRotationAnimation != null && screenRotationAnimation.hasScreenshot()) {
            ProtoLog.i(WM_DEBUG_ORIENTATION, "**** Dismissing screen rotation animation");
            DisplayInfo displayInfo = displayContent.getDisplayInfo();
            // Get rotation animation again, with new top window
            if (!displayContent.getDisplayRotation().validateRotationAnimation(
                    mExitAnimId, mEnterAnimId, false /* forceDefault */)) {
                mExitAnimId = mEnterAnimId = 0;
            }
            if (screenRotationAnimation.dismiss(mTransaction, MAX_ANIMATION_DURATION,
                    getTransitionAnimationScaleLocked(), displayInfo.logicalWidth,
                        displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
                mTransaction.apply();
            } else {
                screenRotationAnimation.kill();
                displayContent.setRotationAnimation(null);
                updateRotation = true;
            }
        } else {
            if (screenRotationAnimation != null) {
                screenRotationAnimation.kill();
                displayContent.setRotationAnimation(null);
            }
            updateRotation = true;
        }

        boolean configChanged;

        // While the display is frozen we don't re-compute the orientation
        // to avoid inconsistent states.  However, something interesting
        // could have actually changed during that time so re-evaluate it
        // now to catch that.
        configChanged = displayContent != null && displayContent.updateOrientation();

        // A little kludge: a lot could have happened while the
        // display was frozen, so now that we are coming back we
        // do a gc so that any remote references the system
        // processes holds on others can be released if they are
        // no longer needed.
        mH.removeMessages(H.FORCE_GC);
        mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);

        mScreenFrozenLock.release();

        if (updateRotation && displayContent != null) {
            ProtoLog.d(WM_DEBUG_ORIENTATION, "Performing post-rotate rotation");
            configChanged |= displayContent.updateRotationUnchecked();
        }

        if (configChanged) {
            displayContent.sendNewConfiguration();
        }
        mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN);
    }

    static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
            DisplayMetrics dm) {
        if (index < tokens.length) {
            String str = tokens[index];
            if (str != null && str.length() > 0) {
                try {
                    int val = Integer.parseInt(str);
                    return val;
                } catch (Exception e) {
                }
            }
        }
        if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
            return defDps;
        }
        int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
        return val;
    }

    void createWatermark() {
        if (mWatermark != null) {
            return;
        }

        File file = new File("/system/etc/setup.conf");
        FileInputStream in = null;
        DataInputStream ind = null;
        try {
            in = new FileInputStream(file);
            ind = new DataInputStream(in);
            String line = ind.readLine();
            if (line != null) {
                String[] toks = line.split("%");
                if (toks != null && toks.length > 0) {
                    // TODO(multi-display): Show watermarks on secondary displays.
                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
                    mWatermark = new Watermark(mSurfaceFactory, displayContent,
                            displayContent.mRealDisplayMetrics, toks, mTransaction);
                    mTransaction.apply();
                }
            }
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        } finally {
            if (ind != null) {
                try {
                    ind.close();
                } catch (IOException e) {
                }
            } else if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

    @Override
    public void setRecentsVisibility(boolean visible) {
        mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
                "setRecentsVisibility()");
        synchronized (mGlobalLock) {
            mPolicy.setRecentsVisibilityLw(visible);
        }
    }

    @Override
    public void setPipVisibility(boolean visible) {
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Caller does not hold permission "
                    + android.Manifest.permission.STATUS_BAR);
        }

        synchronized (mGlobalLock) {
            mPolicy.setPipVisibilityLw(visible);
        }
    }

    @Override
    public void statusBarVisibilityChanged(int displayId, int visibility) {
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Caller does not hold permission "
                    + android.Manifest.permission.STATUS_BAR);
        }

        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null) {
                displayContent.statusBarVisibilityChanged(visibility);
            } else {
                Slog.w(TAG, "statusBarVisibilityChanged with invalid displayId=" + displayId);
            }
        }
    }

    @Override
    public void hideTransientBars(int displayId) {
        mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
                "hideTransientBars()");
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent != null) {
                displayContent.hideTransientBars();
            } else {
                Slog.w(TAG, "hideTransientBars with invalid displayId=" + displayId);
            }
        }
    }

    @Override
    public void setForceShowSystemBars(boolean show) {
        boolean isAutomotive = mContext.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_AUTOMOTIVE);
        if (!isAutomotive) {
            throw new UnsupportedOperationException("Force showing system bars is only supported"
                    + "for Automotive use cases.");
        }
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Caller does not hold permission "
                    + android.Manifest.permission.STATUS_BAR);
        }
        synchronized (mGlobalLock) {
            final PooledConsumer c = PooledLambda.obtainConsumer(
                    DisplayPolicy::setForceShowSystemBars, PooledLambda.__(), show);
            mRoot.forAllDisplayPolicies(c);
            c.recycle();
        }
    }

    public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Caller does not hold permission "
                    + android.Manifest.permission.STATUS_BAR);
        }

        synchronized (mGlobalLock) {
            mPolicy.setNavBarVirtualKeyHapticFeedbackEnabledLw(enabled);
        }
    }

    /**
     * Used by ActivityManager to determine where to position an app with aspect ratio shorter then
     * the screen is.
     * @see DisplayPolicy#getNavBarPosition()
     */
    @Override
    @WindowManagerPolicy.NavigationBarPosition
    public int getNavBarPosition(int displayId) {
        synchronized (mGlobalLock) {
            // Perform layout if it was scheduled before to make sure that we get correct nav bar
            // position when doing rotations.
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                Slog.w(TAG, "getNavBarPosition with invalid displayId=" + displayId
                        + " callers=" + Debug.getCallers(3));
                return NAV_BAR_INVALID;
            }
            displayContent.performLayout(false /* initial */,
                    false /* updateInputWindows */);
            return displayContent.getDisplayPolicy().getNavBarPosition();
        }
    }

    @Override
    public void createInputConsumer(IBinder token, String name, int displayId,
            InputChannel inputChannel) {
        synchronized (mGlobalLock) {
            DisplayContent display = mRoot.getDisplayContent(displayId);
            if (display != null) {
                display.getInputMonitor().createInputConsumer(token, name, inputChannel,
                        Binder.getCallingPid(), Binder.getCallingUserHandle());
            }
        }
    }

    @Override
    public boolean destroyInputConsumer(String name, int displayId) {
        synchronized (mGlobalLock) {
            DisplayContent display = mRoot.getDisplayContent(displayId);
            if (display != null) {
                return display.getInputMonitor().destroyInputConsumer(name);
            }
            return false;
        }
    }

    @Override
    public Region getCurrentImeTouchRegion() {
        if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
            throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
        }
        synchronized (mGlobalLock) {
            final Region r = new Region();
            // TODO(b/111080190): this method is only return the recent focused IME touch region,
            // For Multi-Session IME, will need to add API for given display Id to
            // get the right IME touch region.
            for (int i = mRoot.mChildren.size() - 1; i >= 0; --i) {
                final DisplayContent displayContent = mRoot.mChildren.get(i);
                if (displayContent.mInputMethodWindow != null) {
                    displayContent.mInputMethodWindow.getTouchableRegion(r);
                    return r;
                }
            }
            return r;
        }
    }

    @Override
    public boolean hasNavigationBar(int displayId) {
        synchronized (mGlobalLock) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            if (dc == null) {
                return false;
            }
            return dc.getDisplayPolicy().hasNavigationBar();
        }
    }

    @Override
    public void lockNow(Bundle options) {
        mPolicy.lockNow(options);
    }

    public void showRecentApps() {
        mPolicy.showRecentApps();
    }

    @Override
    public boolean isSafeModeEnabled() {
        return mSafeMode;
    }

    @Override
    public boolean clearWindowContentFrameStats(IBinder token) {
        if (!checkCallingPermission(Manifest.permission.FRAME_STATS,
                "clearWindowContentFrameStats()")) {
            throw new SecurityException("Requires FRAME_STATS permission");
        }
        synchronized (mGlobalLock) {
            WindowState windowState = mWindowMap.get(token);
            if (windowState == null) {
                return false;
            }
            WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
            if (surfaceController == null) {
                return false;
            }
            return surfaceController.clearWindowContentFrameStats();
        }
    }

    @Override
    public WindowContentFrameStats getWindowContentFrameStats(IBinder token) {
        if (!checkCallingPermission(Manifest.permission.FRAME_STATS,
                "getWindowContentFrameStats()")) {
            throw new SecurityException("Requires FRAME_STATS permission");
        }
        synchronized (mGlobalLock) {
            WindowState windowState = mWindowMap.get(token);
            if (windowState == null) {
                return null;
            }
            WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
            if (surfaceController == null) {
                return null;
            }
            if (mTempWindowRenderStats == null) {
                mTempWindowRenderStats = new WindowContentFrameStats();
            }
            WindowContentFrameStats stats = mTempWindowRenderStats;
            if (!surfaceController.getWindowContentFrameStats(stats)) {
                return null;
            }
            return stats;
        }
    }

    private void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
        pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
        mPolicy.dump("    ", pw, args);
    }

    private void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
        pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
        mAnimator.dumpLocked(pw, "    ", dumpAll);
    }

    private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
        pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
        mRoot.dumpTokens(pw, dumpAll);
    }


    private void dumpHighRefreshRateBlacklist(PrintWriter pw) {
        pw.println("WINDOW MANAGER HIGH REFRESH RATE BLACKLIST (dumpsys window refresh)");
        mHighRefreshRateBlacklist.dump(pw);
    }

    private void dumpTraceStatus(PrintWriter pw) {
        pw.println("WINDOW MANAGER TRACE (dumpsys window trace)");
        pw.print(mWindowTracing.getStatus() + "\n");
    }

    private void dumpLogStatus(PrintWriter pw) {
        pw.println("WINDOW MANAGER LOGGING (dumpsys window logging)");
        pw.println(ProtoLogImpl.getSingleInstance().getStatus());
    }

    private void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
        pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
        for (int i=0; i<mSessions.size(); i++) {
            Session s = mSessions.valueAt(i);
            pw.print("  Session "); pw.print(s); pw.println(':');
            s.dump(pw, "    ");
        }
    }

    /**
     * Write to a protocol buffer output stream. Protocol buffer message definition is at
     * {@link com.android.server.wm.WindowManagerServiceDumpProto}.
     *
     * @param proto     Stream to write the WindowContainer object to.
     * @param logLevel  Determines the amount of data to be written to the Protobuf.
     */
    void dumpDebugLocked(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {
        mPolicy.dumpDebug(proto, POLICY);
        mRoot.dumpDebug(proto, ROOT_WINDOW_CONTAINER, logLevel);
        final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent();
        if (topFocusedDisplayContent.mCurrentFocus != null) {
            topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
        }
        if (topFocusedDisplayContent.mFocusedApp != null) {
            topFocusedDisplayContent.mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
        }
        final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
        if (imeWindow != null) {
            imeWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW);
        }
        proto.write(DISPLAY_FROZEN, mDisplayFrozen);
        final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
        proto.write(ROTATION, defaultDisplayContent.getRotation());
        proto.write(LAST_ORIENTATION, defaultDisplayContent.getLastOrientation());
        proto.write(FOCUSED_DISPLAY_ID, topFocusedDisplayContent.getDisplayId());
    }

    private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
            ArrayList<WindowState> windows) {
        pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
        dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
    }

    private void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
            ArrayList<WindowState> windows) {
        mRoot.dumpWindowsNoHeader(pw, dumpAll, windows);

        if (!mHidingNonSystemOverlayWindows.isEmpty()) {
            pw.println();
            pw.println("  Hiding System Alert Windows:");
            for (int i = mHidingNonSystemOverlayWindows.size() - 1; i >= 0; i--) {
                final WindowState w = mHidingNonSystemOverlayWindows.get(i);
                pw.print("  #"); pw.print(i); pw.print(' ');
                pw.print(w);
                if (dumpAll) {
                    pw.println(":");
                    w.dump(pw, "    ", true);
                } else {
                    pw.println();
                }
            }
        }
        if (mPendingRemove.size() > 0) {
            pw.println();
            pw.println("  Remove pending for:");
            for (int i=mPendingRemove.size()-1; i>=0; i--) {
                WindowState w = mPendingRemove.get(i);
                if (windows == null || windows.contains(w)) {
                    pw.print("  Remove #"); pw.print(i); pw.print(' ');
                            pw.print(w);
                    if (dumpAll) {
                        pw.println(":");
                        w.dump(pw, "    ", true);
                    } else {
                        pw.println();
                    }
                }
            }
        }
        if (mForceRemoves != null && mForceRemoves.size() > 0) {
            pw.println();
            pw.println("  Windows force removing:");
            for (int i=mForceRemoves.size()-1; i>=0; i--) {
                WindowState w = mForceRemoves.get(i);
                pw.print("  Removing #"); pw.print(i); pw.print(' ');
                        pw.print(w);
                if (dumpAll) {
                    pw.println(":");
                    w.dump(pw, "    ", true);
                } else {
                    pw.println();
                }
            }
        }
        if (mDestroySurface.size() > 0) {
            pw.println();
            pw.println("  Windows waiting to destroy their surface:");
            for (int i=mDestroySurface.size()-1; i>=0; i--) {
                WindowState w = mDestroySurface.get(i);
                if (windows == null || windows.contains(w)) {
                    pw.print("  Destroy #"); pw.print(i); pw.print(' ');
                            pw.print(w);
                    if (dumpAll) {
                        pw.println(":");
                        w.dump(pw, "    ", true);
                    } else {
                        pw.println();
                    }
                }
            }
        }
        if (mResizingWindows.size() > 0) {
            pw.println();
            pw.println("  Windows waiting to resize:");
            for (int i=mResizingWindows.size()-1; i>=0; i--) {
                WindowState w = mResizingWindows.get(i);
                if (windows == null || windows.contains(w)) {
                    pw.print("  Resizing #"); pw.print(i); pw.print(' ');
                            pw.print(w);
                    if (dumpAll) {
                        pw.println(":");
                        w.dump(pw, "    ", true);
                    } else {
                        pw.println();
                    }
                }
            }
        }
        if (!mWaitingForDrawnCallbacks.isEmpty()) {
            pw.println();
            pw.println("  Clients waiting for these windows to be drawn:");
            mWaitingForDrawnCallbacks.forEach((wc, callback) -> {
                pw.print("  WindowContainer ");
                pw.println(wc.getName());
                for (int i = wc.mWaitingForDrawn.size() - 1; i >= 0; i--) {
                    final WindowState win = (WindowState) wc.mWaitingForDrawn.get(i);
                    pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
                }
            });

        }
        pw.println();
        pw.print("  mGlobalConfiguration="); pw.println(mRoot.getConfiguration());
        pw.print("  mHasPermanentDpad="); pw.println(mHasPermanentDpad);
        mRoot.dumpTopFocusedDisplayId(pw);
        mRoot.forAllDisplays(dc -> {
            final int displayId = dc.getDisplayId();
            final WindowState inputMethodTarget = dc.mInputMethodTarget;
            final WindowState inputMethodInputTarget = dc.mInputMethodInputTarget;
            final InsetsControlTarget inputMethodControlTarget = dc.mInputMethodControlTarget;
            if (inputMethodTarget != null) {
                pw.print("  mInputMethodTarget in display# "); pw.print(displayId);
                pw.print(' '); pw.println(inputMethodTarget);
            }
            if (inputMethodInputTarget != null) {
                pw.print("  mInputMethodInputTarget in display# "); pw.print(displayId);
                pw.print(' '); pw.println(inputMethodInputTarget);
            }
            if (inputMethodControlTarget != null) {
                pw.print("  inputMethodControlTarget in display# "); pw.print(displayId);
                pw.print(' '); pw.println(inputMethodControlTarget.getWindow());
            }
        });
        pw.print("  mInTouchMode="); pw.println(mInTouchMode);
        pw.print("  mLastDisplayFreezeDuration=");
                TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
                if ( mLastFinishedFreezeSource != null) {
                    pw.print(" due to ");
                    pw.print(mLastFinishedFreezeSource);
                }
                pw.println();
        pw.print("  mLastWakeLockHoldingWindow=");pw.print(mLastWakeLockHoldingWindow);
                pw.print(" mLastWakeLockObscuringWindow="); pw.print(mLastWakeLockObscuringWindow);
                pw.println();

        mInputManagerCallback.dump(pw, "  ");
        mTaskSnapshotController.dump(pw, "  ");
        if (mAccessibilityController != null) {
            mAccessibilityController.dump(pw, "  ");
        }

        if (dumpAll) {
            final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
            if (imeWindow != null) {
                pw.print("  mInputMethodWindow="); pw.println(imeWindow);
            }
            mWindowPlacerLocked.dump(pw, "  ");
            pw.print("  mSystemBooted="); pw.print(mSystemBooted);
                    pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);

            mRoot.dumpLayoutNeededDisplayIds(pw);

            pw.print("  mTransactionSequence="); pw.println(mTransactionSequence);
            pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
                    pw.print(" windows="); pw.print(mWindowsFreezingScreen);
                    pw.print(" client="); pw.print(mClientFreezingScreen);
                    pw.print(" apps="); pw.print(mAppsFreezingScreen);
            final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
            pw.print("  mRotation="); pw.print(defaultDisplayContent.getRotation());
            pw.print("  mLastOrientation=");
                    pw.println(defaultDisplayContent.getLastOrientation());
            pw.print(" waitingForConfig=");
                    pw.println(defaultDisplayContent.mWaitingForConfig);

            pw.print("  Animation settings: disabled="); pw.print(mAnimationsDisabled);
                    pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
                    pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
                    pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
            if (mRecentsAnimationController != null) {
                pw.print("  mRecentsAnimationController="); pw.println(mRecentsAnimationController);
                mRecentsAnimationController.dump(pw, "    ");
            }
            PolicyControl.dump("  ", pw);
        }
    }

    private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti,
            boolean dumpAll) {
        final ArrayList<WindowState> windows = new ArrayList();
        if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
            final boolean appsOnly = name.contains("apps");
            final boolean visibleOnly = name.contains("visible");
            synchronized (mGlobalLock) {
                if (appsOnly) {
                    mRoot.dumpDisplayContents(pw);
                }

                mRoot.forAllWindows((w) -> {
                    if ((!visibleOnly || w.isVisible())
                            && (!appsOnly || w.mActivityRecord != null)) {
                        windows.add(w);
                    }
                }, true /* traverseTopToBottom */);
            }
        } else {
            synchronized (mGlobalLock) {
                mRoot.getWindowsByName(windows, name);
            }
        }

        if (windows.size() <= 0) {
            return false;
        }

        synchronized (mGlobalLock) {
            dumpWindowsLocked(pw, dumpAll, windows);
        }
        return true;
    }

    private void dumpLastANRLocked(PrintWriter pw) {
        pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
        if (mLastANRState == null) {
            pw.println("  <no ANR has occurred since boot>");
        } else {
            pw.println(mLastANRState);
        }
    }

    /**
     * Saves information about the state of the window manager at
     * the time an ANR occurred before anything else in the system changes
     * in response.
     *
     * @param activity The application that ANR'd, may be null.
     * @param windowState The window that ANR'd, may be null.
     * @param reason The reason for the ANR, may be null.
     */
    void saveANRStateLocked(ActivityRecord activity, WindowState windowState, String reason) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new FastPrintWriter(sw, false, 1024);
        pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
        if (activity != null) {
            pw.println("  Application at fault: " + activity.stringName);
        }
        if (windowState != null) {
            pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
        }
        if (reason != null) {
            pw.println("  Reason: " + reason);
        }
        for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
            final DisplayContent dc = mRoot.getChildAt(i);
            final int displayId = dc.getDisplayId();
            if (!dc.mWinAddedSinceNullFocus.isEmpty()) {
                pw.println("  Windows added in display #" + displayId + " since null focus: "
                        + dc.mWinAddedSinceNullFocus);
            }
            if (!dc.mWinRemovedSinceNullFocus.isEmpty()) {
                pw.println("  Windows removed in display #" + displayId + " since null focus: "
                        + dc.mWinRemovedSinceNullFocus);
            }
        }
        pw.println();
        dumpWindowsNoHeaderLocked(pw, true, null);
        pw.println();
        pw.println("Last ANR continued");
        mRoot.dumpDisplayContents(pw);
        pw.close();
        mLastANRState = sw.toString();

        mH.removeMessages(H.RESET_ANR_MESSAGE);
        mH.sendEmptyMessageDelayed(H.RESET_ANR_MESSAGE, LAST_ANR_LIFETIME_DURATION_MSECS);
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        PriorityDump.dump(mPriorityDumper, fd, pw, args);
    }

    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
        boolean dumpAll = false;

        int opti = 0;
        while (opti < args.length) {
            String opt = args[opti];
            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
                break;
            }
            opti++;
            if ("-a".equals(opt)) {
                dumpAll = true;
            } else if ("-h".equals(opt)) {
                pw.println("Window manager dump options:");
                pw.println("  [-a] [-h] [cmd] ...");
                pw.println("  cmd may be one of:");
                pw.println("    l[astanr]: last ANR information");
                pw.println("    p[policy]: policy state");
                pw.println("    a[animator]: animator state");
                pw.println("    s[essions]: active sessions");
                pw.println("    surfaces: active surfaces (debugging enabled only)");
                pw.println("    d[isplays]: active display contents");
                pw.println("    t[okens]: token list");
                pw.println("    w[indows]: window list");
                pw.println("    trace: print trace status and write Winscope trace to file");
                pw.println("  cmd may also be a NAME to dump windows.  NAME may");
                pw.println("    be a partial substring in a window name, a");
                pw.println("    Window hex object identifier, or");
                pw.println("    \"all\" for all windows, or");
                pw.println("    \"visible\" for the visible windows.");
                pw.println("    \"visible-apps\" for the visible app windows.");
                pw.println("  -a: include all available server state.");
                pw.println("  --proto: output dump in protocol buffer format.");
                return;
            } else {
                pw.println("Unknown argument: " + opt + "; use -h for help");
            }
        }

        if (useProto) {
            final ProtoOutputStream proto = new ProtoOutputStream(fd);
            synchronized (mGlobalLock) {
                dumpDebugLocked(proto, WindowTraceLogLevel.ALL);
            }
            proto.flush();
            return;
        }
        // Is the caller requesting to dump a particular piece of data?
        if (opti < args.length) {
            String cmd = args[opti];
            opti++;
            if ("lastanr".equals(cmd) || "l".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpLastANRLocked(pw);
                }
                return;
            } else if ("policy".equals(cmd) || "p".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpPolicyLocked(pw, args, true);
                }
                return;
            } else if ("animator".equals(cmd) || "a".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpAnimatorLocked(pw, args, true);
                }
                return;
            } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpSessionsLocked(pw, true);
                }
                return;
            } else if ("displays".equals(cmd) || "d".equals(cmd)) {
                synchronized (mGlobalLock) {
                    mRoot.dumpDisplayContents(pw);
                }
                return;
            } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpTokensLocked(pw, true);
                }
                return;
            } else if ("windows".equals(cmd) || "w".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpWindowsLocked(pw, true, null);
                }
                return;
            } else if ("all".equals(cmd)) {
                synchronized (mGlobalLock) {
                    dumpWindowsLocked(pw, true, null);
                }
                return;
            } else if ("containers".equals(cmd)) {
                synchronized (mGlobalLock) {
                    mRoot.dumpChildrenNames(pw, " ");
                    pw.println(" ");
                    mRoot.forAllWindows(w -> {pw.println(w);}, true /* traverseTopToBottom */);
                }
                return;
            } else if ("trace".equals(cmd)) {
                dumpTraceStatus(pw);
                return;
            } else if ("logging".equals(cmd)) {
                dumpLogStatus(pw);
                return;
            } else if ("refresh".equals(cmd)) {
                dumpHighRefreshRateBlacklist(pw);
                return;
            } else if ("constants".equals(cmd)) {
                mConstants.dump(pw);
                return;
            } else {
                // Dumping a single name?
                if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
                    pw.println("Bad window command, or no windows match: " + cmd);
                    pw.println("Use -h for help.");
                }
                return;
            }
        }

        synchronized (mGlobalLock) {
            pw.println();
            final String separator = "---------------------------------------------------------"
                    + "----------------------";
            if (dumpAll) {
                pw.println(separator);
            }
            dumpLastANRLocked(pw);
            pw.println();
            if (dumpAll) {
                pw.println(separator);
            }
            dumpPolicyLocked(pw, args, dumpAll);
            pw.println();
            if (dumpAll) {
                pw.println(separator);
            }
            dumpAnimatorLocked(pw, args, dumpAll);
            pw.println();
            if (dumpAll) {
                pw.println(separator);
            }
            dumpSessionsLocked(pw, dumpAll);
            pw.println();
            if (dumpAll) {
                pw.println(separator);
            }
            if (dumpAll) {
                pw.println(separator);
            }
            mRoot.dumpDisplayContents(pw);
            pw.println();
            if (dumpAll) {
                pw.println(separator);
            }
            dumpTokensLocked(pw, dumpAll);
            pw.println();
            if (dumpAll) {
                pw.println(separator);
            }
            dumpWindowsLocked(pw, dumpAll, null);
            if (dumpAll) {
                pw.println(separator);
            }
            dumpTraceStatus(pw);
            if (dumpAll) {
                pw.println(separator);
            }
            dumpLogStatus(pw);
            if (dumpAll) {
                pw.println(separator);
            }
            dumpHighRefreshRateBlacklist(pw);
            if (dumpAll) {
                pw.println(separator);
            }
            mConstants.dump(pw);
        }
    }

    // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
    @Override
    public void monitor() {
        synchronized (mGlobalLock) { }
    }

    // There is an inherent assumption that this will never return null.
    // TODO(multi-display): Inspect all the call-points of this method to see if they make sense to
    // support non-default display.
    DisplayContent getDefaultDisplayContentLocked() {
        return mRoot.getDisplayContent(DEFAULT_DISPLAY);
    }

    public void onOverlayChanged() {
        synchronized (mGlobalLock) {
            mRoot.forAllDisplays(displayContent -> {
                displayContent.getDisplayPolicy().onOverlayChangedLw();
                displayContent.updateDisplayInfo();
            });
            requestTraversal();
        }
    }

    @Override
    public Object getWindowManagerLock() {
        return mGlobalLock;
    }

    /**
     * Hint to a token that its activity will relaunch, which will trigger removal and addition of
     * a window.
     *
     * @param token Application token for which the activity will be relaunched.
     */
    void setWillReplaceWindow(IBinder token, boolean animate) {
        final ActivityRecord activity = mRoot.getActivityRecord(token);
        if (activity == null) {
            ProtoLog.w(WM_ERROR, "Attempted to set replacing window on non-existing app token %s",
                    token);
            return;
        }
        if (!activity.hasContentToDisplay()) {
            ProtoLog.w(WM_ERROR,
                    "Attempted to set replacing window on app token with no content %s",
                    token);
            return;
        }
        activity.setWillReplaceWindows(animate);
    }

    /**
     * Hint to a token that its windows will be replaced across activity relaunch.
     * The windows would otherwise be removed  shortly following this as the
     * activity is torn down.
     * @param token Application token for which the activity will be relaunched.
     * @param childrenOnly Whether to mark only child windows for replacement
     *                     (for the case where main windows are being preserved/
     *                     reused rather than replaced).
     *
     */
    // TODO: The s at the end of the method name is the only difference with the name of the method
    // above. We should combine them or find better names.
    void setWillReplaceWindows(IBinder token, boolean childrenOnly) {
        synchronized (mGlobalLock) {
            final ActivityRecord activity = mRoot.getActivityRecord(token);
            if (activity == null) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to set replacing window on non-existing app token %s",
                        token);
                return;
            }
            if (!activity.hasContentToDisplay()) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to set replacing window on app token with no content %s",
                        token);
                return;
            }

            if (childrenOnly) {
                activity.setWillReplaceChildWindows();
            } else {
                activity.setWillReplaceWindows(false /* animate */);
            }

            scheduleClearWillReplaceWindows(token, true /* replacing */);
        }
    }

    /**
     * If we're replacing the window, schedule a timer to clear the replaced window
     * after a timeout, in case the replacing window is not coming.
     *
     * If we're not replacing the window, clear the replace window settings of the app.
     *
     * @param token     Application token for the activity whose window might be replaced.
     * @param replacing Whether the window is being replaced or not.
     */
    void scheduleClearWillReplaceWindows(IBinder token, boolean replacing) {
        final ActivityRecord activity = mRoot.getActivityRecord(token);
        if (activity == null) {
            ProtoLog.w(WM_ERROR, "Attempted to reset replacing window on non-existing app token %s",
                    token);
            return;
        }
        if (replacing) {
            scheduleWindowReplacementTimeouts(activity);
        } else {
            activity.clearWillReplaceWindows();
        }
    }

    void scheduleWindowReplacementTimeouts(ActivityRecord activity) {
        if (!mWindowReplacementTimeouts.contains(activity)) {
            mWindowReplacementTimeouts.add(activity);
        }
        mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT);
        mH.sendEmptyMessageDelayed(
                H.WINDOW_REPLACEMENT_TIMEOUT, WINDOW_REPLACEMENT_TIMEOUT_DURATION);
    }

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

    void setDockedStackResizing(boolean resizing) {
        getDefaultDisplayContentLocked().getDockedDividerController().setResizing(resizing);
        requestTraversal();
    }

    @Override
    public void setDockedStackDividerTouchRegion(Rect touchRegion) {
        synchronized (mGlobalLock) {
            final DisplayContent dc = getDefaultDisplayContentLocked();
            dc.getDockedDividerController().setTouchRegion(touchRegion);
            dc.updateTouchExcludeRegion();
        }
    }

    void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) {
        synchronized (mGlobalLock) {
            mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays;
        }
    }

    @VisibleForTesting
    void setIsPc(boolean isPc) {
        synchronized (mGlobalLock) {
            mIsPc = isPc;
        }
    }

    static int dipToPixel(int dip, DisplayMetrics displayMetrics) {
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
    }

    @Override
    public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) {
        if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
                "registerPinnedStackListener()")) {
            return;
        }
        if (!mAtmService.mSupportsPictureInPicture) {
            return;
        }
        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            displayContent.getPinnedStackController().registerPinnedStackListener(listener);
        }
    }

    @Override
    public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
        try {
            WindowState focusedWindow = getFocusedWindow();
            if (focusedWindow != null && focusedWindow.mClient != null) {
                getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId);
            }
        } catch (RemoteException e) {
        }
    }

    @Override
    public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
        synchronized (mGlobalLock) {
            getStableInsetsLocked(displayId, outInsets);
        }
    }

    void getStableInsetsLocked(int displayId, Rect outInsets) {
        outInsets.setEmpty();
        final DisplayContent dc = mRoot.getDisplayContent(displayId);
        if (dc != null) {
            final DisplayInfo di = dc.getDisplayInfo();
            dc.getDisplayPolicy().getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
                    di.displayCutout, outInsets);
        }
    }

    @Override
    public void setForwardedInsets(int displayId, Insets insets) throws RemoteException {
        synchronized (mGlobalLock) {
            final DisplayContent dc = mRoot.getDisplayContent(displayId);
            if (dc == null) {
                return;
            }
            final int callingUid = Binder.getCallingUid();
            final int displayOwnerUid = dc.getDisplay().getOwnerUid();
            if (callingUid != displayOwnerUid) {
                throw new SecurityException(
                        "Only owner of the display can set ForwardedInsets to it.");
            }
            dc.setForwardedInsets(insets);
        }
    }

    void intersectDisplayInsetBounds(Rect display, Rect insets, Rect inOutBounds) {
        mTmpRect3.set(display);
        mTmpRect3.inset(insets);
        inOutBounds.intersect(mTmpRect3);
    }

    MousePositionTracker mMousePositionTracker = new MousePositionTracker();

    private static class MousePositionTracker implements PointerEventListener {
        private boolean mLatestEventWasMouse;
        private float mLatestMouseX;
        private float mLatestMouseY;

        void updatePosition(float x, float y) {
            synchronized (this) {
                mLatestEventWasMouse = true;
                mLatestMouseX = x;
                mLatestMouseY = y;
            }
        }

        @Override
        public void onPointerEvent(MotionEvent motionEvent) {
            if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) {
                updatePosition(motionEvent.getRawX(), motionEvent.getRawY());
            } else {
                synchronized (this) {
                    mLatestEventWasMouse = false;
                }
            }
        }
    };

    void updatePointerIcon(IWindow client) {
        float mouseX, mouseY;

        synchronized(mMousePositionTracker) {
            if (!mMousePositionTracker.mLatestEventWasMouse) {
                return;
            }
            mouseX = mMousePositionTracker.mLatestMouseX;
            mouseY = mMousePositionTracker.mLatestMouseY;
        }

        synchronized (mGlobalLock) {
            if (mDragDropController.dragDropActiveLocked()) {
                // Drag cursor overrides the app cursor.
                return;
            }
            WindowState callingWin = windowForClientLocked(null, client, false);
            if (callingWin == null) {
                ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
                return;
            }
            final DisplayContent displayContent = callingWin.getDisplayContent();
            if (displayContent == null) {
                return;
            }
            WindowState windowUnderPointer =
                    displayContent.getTouchableWinAtPointLocked(mouseX, mouseY);
            if (windowUnderPointer != callingWin) {
                return;
            }
            try {
                windowUnderPointer.mClient.updatePointerIcon(
                        windowUnderPointer.translateToWindowX(mouseX),
                        windowUnderPointer.translateToWindowY(mouseY));
            } catch (RemoteException e) {
                ProtoLog.w(WM_ERROR, "unable to update pointer icon");
            }
        }
    }

    void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) {
        // Mouse position tracker has not been getting updates while dragging, update it now.
        mMousePositionTracker.updatePosition(latestX, latestY);

        WindowState windowUnderPointer =
                displayContent.getTouchableWinAtPointLocked(latestX, latestY);
        if (windowUnderPointer != null) {
            try {
                windowUnderPointer.mClient.updatePointerIcon(
                        windowUnderPointer.translateToWindowX(latestX),
                        windowUnderPointer.translateToWindowY(latestY));
            } catch (RemoteException e) {
                ProtoLog.w(WM_ERROR, "unable to restore pointer icon");
            }
        } else {
            InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_DEFAULT);
        }
    }

    private void checkCallerOwnsDisplay(int displayId) {
        final Display display = mDisplayManager.getDisplay(displayId);
        if (display == null) {
            throw new IllegalArgumentException(
                    "Cannot find display for non-existent displayId: " + displayId);
        }

        final int callingUid = Binder.getCallingUid();
        final int displayOwnerUid = display.getOwnerUid();
        if (callingUid != displayOwnerUid) {
            throw new SecurityException("The caller doesn't own the display.");
        }
    }

    /** @see Session#reparentDisplayContent(IWindow, SurfaceControl, int)  */
    void reparentDisplayContent(IWindow client, SurfaceControl sc, int displayId) {
        checkCallerOwnsDisplay(displayId);

        synchronized (mGlobalLock) {
            final long token = Binder.clearCallingIdentity();
            try {
                final WindowState win = windowForClientLocked(null, client, false);
                if (win == null) {
                    ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
                    return;
                }
                getDisplayContentOrCreate(displayId, null).reparentDisplayContent(win, sc);
                // Notifies AccessibilityController to re-compute the window observer of
                // this embedded display
                if (mAccessibilityController != null) {
                    mAccessibilityController.handleWindowObserverOfEmbeddedDisplayLocked(displayId,
                            win);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }
    }

    /** @see Session#updateDisplayContentLocation(IWindow, int, int, int)  */
    void updateDisplayContentLocation(IWindow client, int x, int y, int displayId) {
        checkCallerOwnsDisplay(displayId);

        synchronized (mGlobalLock) {
            final long token = Binder.clearCallingIdentity();
            try {
                final WindowState win = windowForClientLocked(null, client, false);
                if (win == null) {
                    ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
                    return;
                }
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                if (displayContent != null) {
                    displayContent.updateLocation(win, x, y);
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }
    }

    /**
     * Update a tap exclude region in the window identified by the provided id. Touches down on this
     * region will not:
     * <ol>
     * <li>Switch focus to this window.</li>
     * <li>Move the display of this window to top.</li>
     * <li>Send the touch events to this window.</li>
     * </ol>
     * Passing an invalid region will remove the area from the exclude region of this window.
     */
    void updateTapExcludeRegion(IWindow client, Region region) {
        synchronized (mGlobalLock) {
            final WindowState callingWin = windowForClientLocked(null, client, false);
            if (callingWin == null) {
                ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
                return;
            }
            callingWin.updateTapExcludeRegion(region);
        }
    }

    /**
     * Forwards a scroll capture request to the appropriate window, if available.
     *
     * @param displayId the display for the request
     * @param behindClient token for a window, used to filter the search to windows behind it
     * @param taskId specifies the id of a task the result must belong to or -1 to ignore task ids
     * @param controller the controller to receive results; a call to either
     *      {@link IScrollCaptureController#onClientConnected} or
     *      {@link IScrollCaptureController#onClientUnavailable}.
     */
    public void requestScrollCapture(int displayId, @Nullable IBinder behindClient, int taskId,
            IScrollCaptureController controller) {
        if (!checkCallingPermission(READ_FRAME_BUFFER, "requestScrollCapture()")) {
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }
        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    ProtoLog.e(WM_ERROR,
                            "Invalid displayId for requestScrollCapture: %d", displayId);
                    controller.onClientUnavailable();
                    return;
                }
                WindowState topWindow = null;
                if (behindClient != null) {
                    topWindow = windowForClientLocked(null, behindClient, /* throwOnError*/ true);
                }
                WindowState targetWindow = dc.findScrollCaptureTargetWindow(topWindow, taskId);
                if (targetWindow == null) {
                    controller.onClientUnavailable();
                    return;
                }
                // Forward to the window for handling.
                try {
                    targetWindow.mClient.requestScrollCapture(controller);
                } catch (RemoteException e) {
                    ProtoLog.w(WM_ERROR,
                            "requestScrollCapture: caught exception dispatching to window."
                                    + "token=%s", targetWindow.mClient.asBinder());
                    controller.onClientUnavailable();
                }
            }
        } catch (RemoteException e) {
            ProtoLog.w(WM_ERROR,
                    "requestScrollCapture: caught exception dispatching callback: %s", e);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public void dontOverrideDisplayInfo(int displayId) {
        final long token = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
                if (dc == null) {
                    throw new IllegalArgumentException(
                            "Trying to configure a non existent display.");
                }
                // We usually set the override info in DisplayManager so that we get consistent
                // values when displays are changing. However, we don't do this for displays that
                // serve as containers for ActivityViews because we don't want letter-/pillar-boxing
                // during resize.
                dc.mShouldOverrideDisplayConfiguration = false;
                mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId,
                        null /* info */);
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public int getWindowingMode(int displayId) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getWindowingMode()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to get windowing mode of a display that does not exist: %d",
                        displayId);
                return WindowConfiguration.WINDOWING_MODE_UNDEFINED;
            }
            return mDisplayWindowSettings.getWindowingModeLocked(displayContent);
        }
    }

    @Override
    public void setWindowingMode(int displayId, int mode) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setWindowingMode()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
                if (displayContent == null) {
                    ProtoLog.w(WM_ERROR,
                            "Attempted to set windowing mode to a display that does not exist: %d",
                            displayId);
                    return;
                }

                int lastWindowingMode = displayContent.getWindowingMode();
                mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);

                displayContent.reconfigureDisplayLocked();

                if (lastWindowingMode != displayContent.getWindowingMode()) {
                    // reconfigure won't detect this change in isolation because the windowing mode
                    // is already set on the display, so fire off a new config now.
                    displayContent.sendNewConfiguration();
                    // Now that all configurations are updated, execute pending transitions.
                    displayContent.executeAppTransition();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public @RemoveContentMode int getRemoveContentMode(int displayId) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getRemoveContentMode()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                ProtoLog.w(WM_ERROR,
                        "Attempted to get remove mode of a display that does not exist: %d",
                        displayId);
                return REMOVE_CONTENT_MODE_UNDEFINED;
            }
            return mDisplayWindowSettings.getRemoveContentModeLocked(displayContent);
        }
    }

    @Override
    public void setRemoveContentMode(int displayId, @RemoveContentMode int mode) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setRemoveContentMode()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
                if (displayContent == null) {
                    ProtoLog.w(WM_ERROR,
                            "Attempted to set remove mode to a display that does not exist: %d",
                            displayId);
                    return;
                }

                mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
                displayContent.reconfigureDisplayLocked();
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public boolean shouldShowWithInsecureKeyguard(int displayId) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowWithInsecureKeyguard()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                ProtoLog.w(WM_ERROR, "Attempted to get flag of a display that does not exist: %d",
                        displayId);
                return false;
            }
            return mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(displayContent);
        }
    }

    @Override
    public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW,
                "setShouldShowWithInsecureKeyguard()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
                if (displayContent == null) {
                    ProtoLog.w(WM_ERROR, "Attempted to set flag to a display that does not exist: "
                            + "%d", displayId);
                    return;
                }

                mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(displayContent,
                        shouldShow);

                displayContent.reconfigureDisplayLocked();
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public boolean shouldShowSystemDecors(int displayId) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowSystemDecors()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }

        synchronized (mGlobalLock) {
            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                ProtoLog.w(WM_ERROR, "Attempted to get system decors flag of a display that does "
                        + "not exist: %d", displayId);
                return false;
            }
            return displayContent.supportsSystemDecorations();
        }
    }

    @Override
    public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
                if (displayContent == null) {
                    ProtoLog.w(WM_ERROR, "Attempted to set system decors flag to a display that "
                            + "does not exist: %d", displayId);
                    return;
                }
                if (!displayContent.isTrusted()) {
                    throw new SecurityException("Attempted to set system decors flag to an "
                            + "untrusted virtual display: " + displayId);
                }

                mDisplayWindowSettings.setShouldShowSystemDecorsLocked(displayContent, shouldShow);

                displayContent.reconfigureDisplayLocked();
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public boolean shouldShowIme(int displayId) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowIme()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }
        boolean show;
        final DisplayContent dc = mRoot.getDisplayContent(displayId);
        if (dc == null) {
            ProtoLog.w(WM_ERROR,
                    "Attempted to get IME flag of a display that does not exist: %d",
                    displayId);
            return false;
        }
        synchronized (mGlobalLock) {
            show = dc.canShowIme();
        }

        return show;
    }

    @Override
    public void setShouldShowIme(int displayId, boolean shouldShow) {
        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowIme()")) {
            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
        }
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
                if (displayContent == null) {
                    ProtoLog.w(WM_ERROR, "Attempted to set IME flag to a display that does not "
                            + "exist: %d", displayId);
                    return;
                }
                if (!displayContent.isTrusted()) {
                    throw new SecurityException("Attempted to set IME flag to an untrusted "
                            + "virtual display: " + displayId);
                }

                mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow);

                displayContent.reconfigureDisplayLocked();
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

    @Override
    public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
            throws RemoteException {
        if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) {
            throw new SecurityException(
                    "Requires REGISTER_WINDOW_MANAGER_LISTENERS permission");
        }
        mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver);
    }

    private final class LocalService extends WindowManagerInternal {

        @Override
        public void clearSnapshotCache() {
            synchronized (mGlobalLock) {
                mTaskSnapshotController.clearSnapshotCache();
            }
        }

        @Override
        public void requestTraversalFromDisplayManager() {
            synchronized (mGlobalLock) {
                requestTraversal();
            }
        }

        @Override
        public void setMagnificationSpec(int displayId, MagnificationSpec spec) {
            synchronized (mGlobalLock) {
                if (mAccessibilityController != null) {
                    mAccessibilityController.setMagnificationSpecLocked(displayId, spec);
                } else {
                    throw new IllegalStateException("Magnification callbacks not set!");
                }
            }
            if (Binder.getCallingPid() != myPid()) {
                spec.recycle();
            }
        }

        @Override
        public void setForceShowMagnifiableBounds(int displayId, boolean show) {
            synchronized (mGlobalLock) {
                if (mAccessibilityController != null) {
                    mAccessibilityController.setForceShowMagnifiableBoundsLocked(displayId, show);
                } else {
                    throw new IllegalStateException("Magnification callbacks not set!");
                }
            }
        }

        @Override
        public void getMagnificationRegion(int displayId, @NonNull Region magnificationRegion) {
            synchronized (mGlobalLock) {
                if (mAccessibilityController != null) {
                    mAccessibilityController.getMagnificationRegionLocked(displayId,
                            magnificationRegion);
                } else {
                    throw new IllegalStateException("Magnification callbacks not set!");
                }
            }
        }

        @Override
        public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
            synchronized (mGlobalLock) {
                WindowState windowState = mWindowMap.get(windowToken);
                if (windowState == null) {
                    return null;
                }
                MagnificationSpec spec = null;
                if (mAccessibilityController != null) {
                    spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState);
                }
                if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
                    return null;
                }
                spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
                spec.scale *= windowState.mGlobalScale;
                return spec;
            }
        }

        @Override
        public boolean setMagnificationCallbacks(int displayId,
                @Nullable MagnificationCallbacks callbacks) {
            synchronized (mGlobalLock) {
                if (mAccessibilityController == null) {
                    mAccessibilityController = new AccessibilityController(
                            WindowManagerService.this);
                }
                boolean result = mAccessibilityController.setMagnificationCallbacksLocked(
                        displayId, callbacks);
                if (!mAccessibilityController.hasCallbacksLocked()) {
                    mAccessibilityController = null;
                }
                return result;
            }
        }

        @Override
        public boolean setWindowsForAccessibilityCallback(int displayId,
                WindowsForAccessibilityCallback callback) {
            synchronized (mGlobalLock) {
                if (mAccessibilityController == null) {
                    mAccessibilityController = new AccessibilityController(
                            WindowManagerService.this);
                }
                final boolean result =
                        mAccessibilityController.setWindowsForAccessibilityCallbackLocked(
                        displayId, callback);
                if (!mAccessibilityController.hasCallbacksLocked()) {
                    mAccessibilityController = null;
                }
                return result;
            }
        }

        @Override
        public void setInputFilter(IInputFilter filter) {
            mInputManager.setInputFilter(filter);
        }

        @Override
        public IBinder getFocusedWindowToken() {
            synchronized (mGlobalLock) {
                WindowState windowState = getFocusedWindowLocked();
                if (windowState != null) {
                    return windowState.mClient.asBinder();
                }
                return null;
            }
        }

        @Override
        public boolean isKeyguardLocked() {
            return WindowManagerService.this.isKeyguardLocked();
        }

        @Override
        public boolean isKeyguardShowingAndNotOccluded() {
            return WindowManagerService.this.isKeyguardShowingAndNotOccluded();
        }

        @Override
        public void showGlobalActions() {
            WindowManagerService.this.showGlobalActions();
        }

        @Override
        public void getWindowFrame(IBinder token, Rect outBounds) {
            synchronized (mGlobalLock) {
                WindowState windowState = mWindowMap.get(token);
                if (windowState != null) {
                    outBounds.set(windowState.getFrameLw());
                } else {
                    outBounds.setEmpty();
                }
            }
        }

        @Override
        public void waitForAllWindowsDrawn(Runnable callback, long timeout, int displayId) {
            final WindowContainer container = displayId == INVALID_DISPLAY
                    ? mRoot : mRoot.getDisplayContent(displayId);
            if (container == null) {
                // The waiting container doesn't exist, no need to wait to run the callback. Run and
                // return;
                callback.run();
                return;
            }
            boolean allWindowsDrawn = false;
            synchronized (mGlobalLock) {
                container.waitForAllWindowsDrawn();
                mWindowPlacerLocked.requestTraversal();
                mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
                if (container.mWaitingForDrawn.isEmpty()) {
                    allWindowsDrawn = true;
                } else {
                    mWaitingForDrawnCallbacks.put(container, callback);
                    mH.sendNewMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, container, timeout);
                    checkDrawnWindowsLocked();
                }
            }
            if (allWindowsDrawn) {
                callback.run();
            }
        }

        @Override
        public void setForcedDisplaySize(int displayId, int width, int height) {
            WindowManagerService.this.setForcedDisplaySize(displayId, width, height);
        }

        @Override
        public void clearForcedDisplaySize(int displayId) {
            WindowManagerService.this.clearForcedDisplaySize(displayId);
        }

        @Override
        public void addWindowToken(IBinder token, int type, int displayId) {
            WindowManagerService.this.addWindowToken(token, type, displayId);
        }

        @Override
        public void removeWindowToken(IBinder binder, boolean removeWindows, int displayId) {
            synchronized (mGlobalLock) {
                if (removeWindows) {
                    final DisplayContent dc = mRoot.getDisplayContent(displayId);
                    if (dc == null) {
                        ProtoLog.w(WM_ERROR, "removeWindowToken: Attempted to remove token: %s"
                                + " for non-exiting displayId=%d", binder, displayId);
                        return;
                    }

                    final WindowToken token = dc.removeWindowToken(binder);
                    if (token == null) {
                        ProtoLog.w(WM_ERROR,
                                "removeWindowToken: Attempted to remove non-existing token: %s",
                                binder);
                        return;
                    }

                    token.removeAllWindowsIfPossible();
                }
                WindowManagerService.this.removeWindowToken(binder, displayId);
            }
        }

        // TODO(multi-display): currently only used by PWM to notify keyguard transitions as well
        // forwarding it to SystemUI for synchronizing status and navigation bar animations.
        @Override
        public void registerAppTransitionListener(AppTransitionListener listener) {
            synchronized (mGlobalLock) {
                getDefaultDisplayContentLocked().mAppTransition.registerListenerLocked(listener);
            }
        }

        @Override
        public void reportPasswordChanged(int userId) {
            mKeyguardDisableHandler.updateKeyguardEnabled(userId);
        }

        @Override
        public int getInputMethodWindowVisibleHeight(int displayId) {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                return dc.mDisplayFrames.getInputMethodWindowVisibleHeight();
            }
        }

        @Override
        public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
                boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed) {
            mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed);
        }

        @Override
        public void updateInputMethodTargetWindow(@NonNull IBinder imeToken,
                @NonNull IBinder imeTargetWindowToken) {
            // TODO (b/34628091): Use this method to address the window animation issue.
            if (DEBUG_INPUT_METHOD) {
                Slog.w(TAG_WM, "updateInputMethodTargetWindow: imeToken=" + imeToken
                        + " imeTargetWindowToken=" + imeTargetWindowToken);
            }
            synchronized (mGlobalLock) {
                final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
                if (imeTarget != null) {
                    imeTarget.getDisplayContent().setInputMethodInputTarget(imeTarget);
                }
            }
        }

        @Override
        public boolean isHardKeyboardAvailable() {
            synchronized (mGlobalLock) {
                return mHardKeyboardAvailable;
            }
        }

        @Override
        public void setOnHardKeyboardStatusChangeListener(
                OnHardKeyboardStatusChangeListener listener) {
            synchronized (mGlobalLock) {
                mHardKeyboardStatusChangeListener = listener;
            }
        }

        @Override
        public boolean isStackVisibleLw(int windowingMode) {
            // TODO(b/153090332): Support multiple task display areas & displays
            final TaskDisplayArea tc = mRoot.getDefaultTaskDisplayArea();
            return tc.isStackVisible(windowingMode);
        }

        @Override
        public void computeWindowsForAccessibility(int displayId) {
            final AccessibilityController accessibilityController;
            synchronized (mGlobalLock) {
                accessibilityController = mAccessibilityController;
            }
            if (accessibilityController != null) {
                accessibilityController.performComputeChangedWindowsNotLocked(displayId, true);
            }
        }

        @Override
        public void setVr2dDisplayId(int vr2dDisplayId) {
            if (DEBUG_DISPLAY) {
                Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
            }
            synchronized (mGlobalLock) {
                mVr2dDisplayId = vr2dDisplayId;
            }
        }

        @Override
        public void registerDragDropControllerCallback(IDragDropCallback callback) {
            mDragDropController.registerCallback(callback);
        }

        @Override
        public void lockNow() {
            WindowManagerService.this.lockNow(null);
        }

        @Override
        public int getWindowOwnerUserId(IBinder token) {
            synchronized (mGlobalLock) {
                WindowState window = mWindowMap.get(token);
                if (window != null) {
                    return window.mShowUserId;
                }
                return UserHandle.USER_NULL;
            }
        }

        @Override
        public boolean isUidFocused(int uid) {
            synchronized (mGlobalLock) {
                for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
                    final DisplayContent displayContent = mRoot.getChildAt(i);
                    if (displayContent.mCurrentFocus != null
                            && uid == displayContent.mCurrentFocus.getOwningUid()) {
                        return true;
                    }
                }
                return false;
            }
        }

        @Override
        public boolean isInputMethodClientFocus(int uid, int pid, int displayId) {
            if (displayId == Display.INVALID_DISPLAY) {
                return false;
            }
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getTopFocusedDisplayContent();
                if (displayContent == null
                        || displayContent.getDisplayId() != displayId
                        || !displayContent.hasAccess(uid)) {
                    return false;
                }
                if (displayContent.isInputMethodClientFocus(uid, pid)) {
                    return true;
                }
                // Okay, how about this...  what is the current focus?
                // It seems in some cases we may not have moved the IM
                // target window, such as when it was in a pop-up window,
                // so let's also look at the current focus.  (An example:
                // go to Gmail, start searching so the keyboard goes up,
                // press home.  Sometimes the IME won't go down.)
                // Would be nice to fix this more correctly, but it's
                // way at the end of a release, and this should be good enough.
                final WindowState currentFocus = displayContent.mCurrentFocus;
                if (currentFocus != null && currentFocus.mSession.mUid == uid
                        && currentFocus.mSession.mPid == pid) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public void showImePostLayout(IBinder imeTargetWindowToken) {
            synchronized (mGlobalLock) {
                WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
                if (imeTarget == null) {
                    return;
                }
                imeTarget = imeTarget.getImeControlTarget().getWindow();
                // If InsetsControlTarget doesn't have a window, its using remoteControlTarget which
                // is controlled by default display
                final DisplayContent dc = imeTarget != null
                        ? imeTarget.getDisplayContent() : getDefaultDisplayContentLocked();
                dc.getInsetsStateController().getImeSourceProvider()
                        .scheduleShowImePostLayout(imeTarget);
            }
        }

        @Override
        public void hideIme(IBinder imeTargetWindowToken) {
            synchronized (mGlobalLock) {
                WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
                if (imeTarget == null) {
                    // The target window no longer exists.
                    return;
                }
                imeTarget = imeTarget.getImeControlTarget().getWindow();
                final DisplayContent dc = imeTarget != null
                        ? imeTarget.getDisplayContent() : getDefaultDisplayContentLocked();
                // If there was a pending IME show(), reset it as IME has been
                // requested to be hidden.
                dc.getInsetsStateController().getImeSourceProvider().abortShowImePostLayout();
                if (dc.mInputMethodControlTarget == null) {
                    return;
                }
                dc.mInputMethodControlTarget.hideInsets(
                        WindowInsets.Type.ime(), true /* fromIme */);
            }
        }

        @Override
        public boolean isUidAllowedOnDisplay(int displayId, int uid) {
            if (displayId == Display.DEFAULT_DISPLAY) {
                return true;
            }
            if (displayId == Display.INVALID_DISPLAY) {
                return false;
            }
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                return displayContent != null && displayContent.hasAccess(uid);
            }
        }

        @Override
        public int getDisplayIdForWindow(IBinder windowToken) {
            synchronized (mGlobalLock) {
                final WindowState window = mWindowMap.get(windowToken);
                if (window != null) {
                    return window.getDisplayContent().getDisplayId();
                }
                return Display.INVALID_DISPLAY;
            }
        }

        @Override
        public int getTopFocusedDisplayId() {
            synchronized (mGlobalLock) {
                return mRoot.getTopFocusedDisplayContent().getDisplayId();
            }
        }

        @Override
        public Context getTopFocusedDisplayUiContext() {
            synchronized (mGlobalLock) {
                return mRoot.getTopFocusedDisplayContent().getDisplayUiContext();
            }
        }

        @Override
        public boolean shouldShowSystemDecorOnDisplay(int displayId) {
            synchronized (mGlobalLock) {
                return WindowManagerService.this.shouldShowSystemDecors(displayId);
            }
        }

        @Override
        public boolean shouldShowIme(int displayId) {
            synchronized (mGlobalLock) {
                return WindowManagerService.this.shouldShowIme(displayId);
            }
        }

        @Override
        public void addNonHighRefreshRatePackage(@NonNull String packageName) {
            synchronized (mGlobalLock) {
                mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
                        .addNonHighRefreshRatePackage(packageName));
            }
        }

        @Override
        public void removeNonHighRefreshRatePackage(@NonNull String packageName) {
            synchronized (mGlobalLock) {
                mRoot.forAllDisplays(dc -> dc.getDisplayPolicy().getRefreshRatePolicy()
                        .removeNonHighRefreshRatePackage(packageName));
            }
        }

        @Override
        public boolean isTouchableDisplay(int displayId) {
            synchronized (mGlobalLock) {
                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
                final Configuration configuration =
                        displayContent != null ? displayContent.getConfiguration() : null;
                return configuration != null
                        && configuration.touchscreen == Configuration.TOUCHSCREEN_FINGER;
            }
        }

        @Override
        public @Nullable KeyInterceptionInfo getKeyInterceptionInfoFromToken(IBinder inputToken) {
            return mKeyInterceptionInfoForToken.get(inputToken);
        }

        @Override
        public void setAccessibilityIdToSurfaceMetadata(
                IBinder windowToken, int accessibilityWindowId) {
            synchronized (mGlobalLock) {
                final WindowState state = mWindowMap.get(windowToken);
                if (state == null) {
                    Slog.w(TAG, "Cannot find window which accessibility connection is added to");
                    return;
                }
                mTransaction.setMetadata(state.mSurfaceControl,
                        SurfaceControl.METADATA_ACCESSIBILITY_ID, accessibilityWindowId).apply();
            }
        }

        @Override
        public String getWindowName(@NonNull IBinder binder) {
            synchronized (mGlobalLock) {
                final WindowState w = mWindowMap.get(binder);
                return w != null ? w.getName() : null;
            }
        }

        @Override
        public String getImeControlTargetNameForLogging(int displayId) {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    return null;
                }
                final InsetsControlTarget target = dc.mInputMethodControlTarget;
                if (target == null) {
                    return null;
                }
                final WindowState win = target.getWindow();
                return win != null ? win.getName() : target.toString();
            }
        }

        @Override
        public String getImeTargetNameForLogging(int displayId) {
            synchronized (mGlobalLock) {
                final DisplayContent dc = mRoot.getDisplayContent(displayId);
                if (dc == null) {
                    return null;
                }
                return dc.mInputMethodTarget != null ? dc.mInputMethodTarget.getName() : null;
            }
        }
    }

    void registerAppFreezeListener(AppFreezeListener listener) {
        if (!mAppFreezeListeners.contains(listener)) {
            mAppFreezeListeners.add(listener);
        }
    }

    void unregisterAppFreezeListener(AppFreezeListener listener) {
        mAppFreezeListeners.remove(listener);
    }

    /**
     * WARNING: This interrupts surface updates, be careful! Don't
     * execute within the transaction for longer than you would
     * execute on an animation thread.
     * WARNING: This method contains locks known to the State of California
     * to cause Deadlocks and other conditions.
     *
     * Begins a surface transaction with which the AM can batch operations.
     * All Surface updates performed by the WindowManager following this
     * will not appear on screen until after the call to
     * closeSurfaceTransaction.
     *
     * ActivityManager can use this to ensure multiple 'commands' will all
     * be reflected in a single frame. For example when reparenting a window
     * which was previously hidden due to it's parent properties, we may
     * need to ensure it is hidden in the same frame that the properties
     * from the new parent are inherited, otherwise it could be revealed
     * mistakenly.
     *
     * TODO(b/36393204): We can investigate totally replacing #deferSurfaceLayout
     * with something like this but it seems that some existing cases of
     * deferSurfaceLayout may be a little too broad, in particular the total
     * enclosure of startActivityUnchecked which could run for quite some time.
     */
    void inSurfaceTransaction(Runnable exec) {
        SurfaceControl.openTransaction();
        try {
            exec.run();
        } finally {
            SurfaceControl.closeTransaction();
        }
    }

    /** Called to inform window manager if non-Vr UI shoul be disabled or not. */
    public void disableNonVrUi(boolean disable) {
        synchronized (mGlobalLock) {
            // Allow alert window notifications to be shown if non-vr UI is enabled.
            final boolean showAlertWindowNotifications = !disable;
            if (showAlertWindowNotifications == mShowAlertWindowNotifications) {
                return;
            }
            mShowAlertWindowNotifications = showAlertWindowNotifications;

            for (int i = mSessions.size() - 1; i >= 0; --i) {
                final Session s = mSessions.valueAt(i);
                s.setShowingAlertWindowNotificationAllowed(mShowAlertWindowNotifications);
            }
        }
    }

    boolean hasWideColorGamutSupport() {
        return mHasWideColorGamutSupport &&
                SystemProperties.getInt("persist.sys.sf.native_mode", 0) != 1;
    }

    boolean hasHdrSupport() {
        return mHasHdrSupport && hasWideColorGamutSupport();
    }

    void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
        if (!win.hideNonSystemOverlayWindowsWhenVisible()
                && !mHidingNonSystemOverlayWindows.contains(win)) {
            return;
        }
        final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
        if (surfaceShown && win.hideNonSystemOverlayWindowsWhenVisible()) {
            if (!mHidingNonSystemOverlayWindows.contains(win)) {
                mHidingNonSystemOverlayWindows.add(win);
            }
        } else {
            mHidingNonSystemOverlayWindows.remove(win);
        }

        final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();

        if (systemAlertWindowsHidden == hideSystemAlertWindows) {
            return;
        }

        mRoot.forAllWindows((w) -> {
            w.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
        }, false /* traverseTopToBottom */);
    }

    /** Called from Accessibility Controller to apply magnification spec */
    public void applyMagnificationSpecLocked(int displayId, MagnificationSpec spec) {
        final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
        if (displayContent != null) {
            displayContent.applyMagnificationSpec(spec);
        }
    }

    SurfaceControl.Builder makeSurfaceBuilder(SurfaceSession s) {
        return mSurfaceControlFactory.apply(s);
    }

    /**
     * Called when the state of lock task mode changes. This should be used to disable immersive
     * mode confirmation.
     *
     * @param lockTaskState the new lock task mode state. One of
     *                      {@link ActivityManager#LOCK_TASK_MODE_NONE},
     *                      {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
     *                      {@link ActivityManager#LOCK_TASK_MODE_PINNED}.
     */
    void onLockTaskStateChanged(int lockTaskState) {
        // TODO: pass in displayId to determine which display the lock task state changed
        synchronized (mGlobalLock) {
            final PooledConsumer c = PooledLambda.obtainConsumer(
                    DisplayPolicy::onLockTaskStateChangedLw, PooledLambda.__(), lockTaskState);
            mRoot.forAllDisplayPolicies(c);
            c.recycle();
        }
    }

    /**
     * Updates {@link WindowManagerPolicy} with new value about whether AOD  is showing. If AOD
     * has changed, this will trigger a {@link WindowSurfacePlacer#performSurfacePlacement} to
     * ensure the new value takes effect.
     */
    public void setAodShowing(boolean aodShowing) {
        synchronized (mGlobalLock) {
            if (mPolicy.setAodShowing(aodShowing)) {
                mWindowPlacerLocked.performSurfacePlacement();
            }
        }
    }

    @Override
    public boolean injectInputAfterTransactionsApplied(InputEvent ev, int mode) {
        boolean isDown;
        boolean isUp;

        if (ev instanceof KeyEvent) {
            KeyEvent keyEvent = (KeyEvent) ev;
            isDown = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
            isUp = keyEvent.getAction() == KeyEvent.ACTION_UP;
        } else {
            MotionEvent motionEvent = (MotionEvent) ev;
            isDown = motionEvent.getAction() == MotionEvent.ACTION_DOWN;
            isUp = motionEvent.getAction() == MotionEvent.ACTION_UP;
        }
        final boolean isMouseEvent = ev.getSource() == InputDevice.SOURCE_MOUSE;

        // For ACTION_DOWN, syncInputTransactions before injecting input.
        // For all mouse events, also sync before injecting.
        // For ACTION_UP, sync after injecting.
        if (isDown || isMouseEvent) {
            syncInputTransactions();
        }
        final boolean result =
                LocalServices.getService(InputManagerInternal.class).injectInputEvent(ev, mode);
        if (isUp) {
            syncInputTransactions();
        }
        return result;
    }

    @Override
    public void syncInputTransactions() {
        long token = Binder.clearCallingIdentity();
        try {
            waitForAnimationsToComplete();

            // Collect all input transactions from all displays to make sure we could sync all input
            // windows at same time.
            final SurfaceControl.Transaction t = mTransactionFactory.get();
            synchronized (mGlobalLock) {
                mWindowPlacerLocked.performSurfacePlacementIfScheduled();
                mRoot.forAllDisplays(displayContent ->
                        displayContent.getInputMonitor().updateInputWindowsImmediately(t));
            }

            t.syncInputWindows().apply();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    /**
     * Wait until all container animations and surface operations behalf of WindowManagerService
     * complete.
     */
    private void waitForAnimationsToComplete() {
        synchronized (mGlobalLock) {
            long timeoutRemaining = ANIMATION_COMPLETED_TIMEOUT_MS;
            // This could prevent if there is no container animation, we still have to apply the
            // pending transaction and exit waiting.
            mAnimator.mNotifyWhenNoAnimation = true;
            while ((mAnimator.isAnimationScheduled()
                    || mRoot.isAnimating(TRANSITION | CHILDREN)) && timeoutRemaining > 0) {
                long startTime = System.currentTimeMillis();
                try {
                    mGlobalLock.wait(timeoutRemaining);
                } catch (InterruptedException e) {
                }
                timeoutRemaining -= (System.currentTimeMillis() - startTime);
            }
            mAnimator.mNotifyWhenNoAnimation = false;

            if (mAnimator.isAnimationScheduled()
                    || mRoot.isAnimating(TRANSITION | CHILDREN)) {
                Slog.w(TAG, "Timed out waiting for animations to complete.");
            }
        }
    }

    void onAnimationFinished() {
        synchronized (mGlobalLock) {
            mGlobalLock.notifyAll();
        }
    }

    private void onPointerDownOutsideFocusLocked(IBinder touchedToken) {
        WindowState touchedWindow = mInputToWindowMap.get(touchedToken);
        if (touchedWindow == null) {
            // if a user taps outside the currently focused window onto an embedded window, treat
            // it as if the host window was tapped.
            touchedWindow = mEmbeddedWindowController.getHostWindow(touchedToken);
        }

        if (touchedWindow == null || !touchedWindow.canReceiveKeys(true /* fromUserTouch */)) {
            // If the window that received the input event cannot receive keys, don't move the
            // display it's on to the top since that window won't be able to get focus anyway.
            return;
        }

        final DisplayContent displayContent = touchedWindow.getDisplayContent();
        if (!displayContent.isOnTop()) {
            displayContent.positionDisplayAt(WindowContainer.POSITION_TOP,
                    true /* includingParents */);
        }
        handleTaskFocusChange(touchedWindow.getTask());
    }

    @VisibleForTesting
    void handleTaskFocusChange(Task task) {
        if (task == null) {
            return;
        }

        // We ignore home stack since we don't want home stack to move to front when touched.
        // Specifically, in freeform we don't want tapping on home to cause the freeform apps to go
        // behind home. See b/117376413
        if (task.isActivityTypeHome()) {
            // Only ignore home stack if the requested focus home Task is in the same
            // TaskDisplayArea as the current focus Task.
            TaskDisplayArea homeTda = task.getDisplayArea();
            WindowState curFocusedWindow = getFocusedWindow();
            if (curFocusedWindow != null && homeTda != null
                    && curFocusedWindow.isDescendantOf(homeTda)) {
                return;
            }
        }

        try {
            mActivityTaskManager.setFocusedTask(task.mTaskId);
        } catch (RemoteException e) {
        }
    }

    /**
     * Assigns an InputChannel to a SurfaceControl and configures it to receive
     * touch input according to it's on-screen geometry.
     *
     * Used by WindowlessWindowManager to enable input on SurfaceControl embedded
     * views.
     */
    void grantInputChannel(int callingUid, int callingPid, int displayId, SurfaceControl surface,
            IWindow window, IBinder hostInputToken, int flags, int type,
            InputChannel outInputChannel) {
        final InputApplicationHandle applicationHandle;
        final String name;
        final InputChannel clientChannel;
        synchronized (mGlobalLock) {
            EmbeddedWindowController.EmbeddedWindow win =
                    new EmbeddedWindowController.EmbeddedWindow(this, window,
                            mInputToWindowMap.get(hostInputToken), callingUid, callingPid, type);
            clientChannel = win.openInputChannel();
            mEmbeddedWindowController.add(clientChannel.getToken(), win);
            applicationHandle = win.getApplicationHandle();
            name = win.getName();
        }

        updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
                name, applicationHandle, flags, type, null /* region */);

        clientChannel.transferTo(outInputChannel);
        clientChannel.dispose();
    }

    private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
            int displayId, SurfaceControl surface, String name,
            InputApplicationHandle applicationHandle, int flags, int type, Region region) {
        InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
        h.token = channelToken;
        h.name = name;

        final int sanitizedFlags = flags & (LayoutParams.FLAG_NOT_TOUCHABLE
                | LayoutParams.FLAG_SLIPPERY);
        h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | sanitizedFlags;
        h.layoutParamsType = type;
        h.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
        h.canReceiveKeys = false;
        h.hasFocus = false;
        h.hasWallpaper = false;
        h.paused = false;

        h.ownerUid = callingUid;
        h.ownerPid = callingPid;

        h.inputFeatures = 0;

        if (region == null) {
            h.replaceTouchableRegionWithCrop(null);
        } else {
            h.touchableRegion.set(region);
            h.replaceTouchableRegionWithCrop = false;
            h.setTouchableRegionCrop(surface);
        }

        SurfaceControl.Transaction t = mTransactionFactory.get();
        t.setInputWindowInfo(surface, h);
        t.apply();
        t.close();
        surface.release();
    }

    /**
     * Updates the flags on an existing surface's input channel. This assumes the surface provided
     * is the one associated with the provided input-channel. If this isn't the case, behavior
     * is undefined.
     */
    void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
            int flags, Region region) {
        final InputApplicationHandle applicationHandle;
        final String name;
        final EmbeddedWindowController.EmbeddedWindow win;
        synchronized (mGlobalLock) {
            win = mEmbeddedWindowController.get(channelToken);
            if (win == null) {
                Slog.e(TAG, "Couldn't find window for provided channelToken.");
                return;
            }
            name = win.getName();
            applicationHandle = win.getApplicationHandle();
        }

        updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
                applicationHandle, flags, win.mWindowType, region);
    }

    /** Return whether layer tracing is enabled */
    public boolean isLayerTracing() {
        mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.DUMP,
                "isLayerTracing");
        long token = Binder.clearCallingIdentity();
        try {
            Parcel data = null;
            Parcel reply = null;
            try {
                IBinder sf = ServiceManager.getService("SurfaceFlinger");
                if (sf != null) {
                    reply = Parcel.obtain();
                    data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    sf.transact(/* LAYER_TRACE_STATUS_CODE */ 1026, data, reply, 0 /* flags */);
                    return reply.readBoolean();
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to get layer tracing");
            } finally {
                if (data != null) {
                    data.recycle();
                }
                if (reply != null) {
                    reply.recycle();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        return false;
    }

    /** Enable or disable layer tracing */
    public void setLayerTracing(boolean enabled) {
        mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.DUMP,
                "setLayerTracing");
        long token = Binder.clearCallingIdentity();
        try {
            Parcel data = null;
            try {
                IBinder sf = ServiceManager.getService("SurfaceFlinger");
                if (sf != null) {
                    data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    data.writeInt(enabled ? 1 : 0);
                    sf.transact(/* LAYER_TRACE_CONTROL_CODE */ 1025, data, null, 0 /* flags */);
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to set layer tracing");
            } finally {
                if (data != null) {
                    data.recycle();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    /** Set layer tracing flags. */
    public void setLayerTracingFlags(int flags) {
        mAtmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.DUMP,
                "setLayerTracingFlags");
        long token = Binder.clearCallingIdentity();
        try {
            Parcel data = null;
            try {
                IBinder sf = ServiceManager.getService("SurfaceFlinger");
                if (sf != null) {
                    data = Parcel.obtain();
                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
                    data.writeInt(flags);
                    sf.transact(1033 /* LAYER_TRACE_FLAGS_CODE */, data, null, 0 /* flags */);
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to set layer tracing flags");
            } finally {
                if (data != null) {
                    data.recycle();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public boolean mirrorDisplay(int displayId, SurfaceControl outSurfaceControl) {
        if (!checkCallingPermission(READ_FRAME_BUFFER, "mirrorDisplay()")) {
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }

        final SurfaceControl displaySc;
        synchronized (mGlobalLock) {
            DisplayContent displayContent = mRoot.getDisplayContent(displayId);
            if (displayContent == null) {
                Slog.e(TAG, "Invalid displayId " + displayId + " for mirrorDisplay");
                return false;
            }

            displaySc = displayContent.getWindowingLayer();
        }

        final SurfaceControl mirror = SurfaceControl.mirrorSurface(displaySc);
        outSurfaceControl.copyFrom(mirror);

        return true;
    }

    @Override
    public boolean getWindowInsets(WindowManager.LayoutParams attrs,
            int displayId, Rect outContentInsets, Rect outStableInsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InsetsState outInsetsState) {
        final long origId = Binder.clearCallingIdentity();
        try {
            synchronized (mGlobalLock) {
                final DisplayContent dc = getDisplayContentOrCreate(displayId, attrs.token);
                if (dc == null) {
                    throw new WindowManager.InvalidDisplayException("Display#" + displayId
                            + "could not be found!");
                }
                final WindowToken windowToken = dc.getWindowToken(attrs.token);
                final InsetsStateController insetsStateController =
                        dc.getInsetsStateController();
                outInsetsState.set(insetsStateController.getInsetsForWindowMetrics(attrs));

                return dc.getDisplayPolicy().getLayoutHint(attrs, windowToken,
                        mTmpRect /* outFrame */, outContentInsets, outStableInsets,
                        outDisplayCutout);
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }
}
