Home | History | Annotate | Download | only in wm
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.wm;
     18 
     19 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
     20 import static android.Manifest.permission.MANAGE_APP_TOKENS;
     21 import static android.Manifest.permission.READ_FRAME_BUFFER;
     22 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
     23 import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
     24 import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
     25 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
     26 import static android.app.StatusBarManager.DISABLE_MASK;
     27 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
     28 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
     29 import static android.os.Process.SYSTEM_UID;
     30 import static android.os.Process.myPid;
     31 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
     32 import static android.view.Display.DEFAULT_DISPLAY;
     33 import static android.view.Display.INVALID_DISPLAY;
     34 import static android.view.WindowManager.DOCKED_INVALID;
     35 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
     36 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
     37 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
     38 import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
     39 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
     40 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
     41 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
     42 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
     43 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
     44 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
     45 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
     46 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
     47 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
     48 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
     49 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
     50 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
     51 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
     52 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
     53 import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
     54 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
     55 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
     56 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
     57 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
     58 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
     59 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
     60 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
     61 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
     62 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
     63 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
     64 import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
     65 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
     66 
     67 import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
     68 import static com.android.server.LockGuard.INDEX_WINDOW;
     69 import static com.android.server.LockGuard.installLock;
     70 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
     71 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
     72 import static com.android.server.wm.KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED;
     73 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
     74 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
     75 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
     76 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
     77 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
     78 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
     79 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
     80 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
     81 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
     82 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
     83 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
     84 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
     85 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
     86 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
     87 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
     88 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
     89 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
     90 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
     91 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
     92 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
     93 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
     94 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
     95 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
     96 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
     97 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
     98 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
     99 import static com.android.server.wm.WindowManagerServiceDumpProto.APP_TRANSITION;
    100 import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN;
    101 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
    102 import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
    103 import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
    104 import static com.android.server.wm.WindowManagerServiceDumpProto.LAST_ORIENTATION;
    105 import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY;
    106 import static com.android.server.wm.WindowManagerServiceDumpProto.ROOT_WINDOW_CONTAINER;
    107 import static com.android.server.wm.WindowManagerServiceDumpProto.ROTATION;
    108 
    109 import android.Manifest;
    110 import android.Manifest.permission;
    111 import android.animation.AnimationHandler;
    112 import android.animation.ValueAnimator;
    113 import android.annotation.IntDef;
    114 import android.annotation.NonNull;
    115 import android.annotation.Nullable;
    116 import android.app.ActivityManager;
    117 import android.app.ActivityManager.TaskSnapshot;
    118 import android.app.ActivityManagerInternal;
    119 import android.app.ActivityThread;
    120 import android.app.AppOpsManager;
    121 import android.app.IActivityManager;
    122 import android.app.IAssistDataReceiver;
    123 import android.app.admin.DevicePolicyCache;
    124 import android.content.BroadcastReceiver;
    125 import android.content.ContentResolver;
    126 import android.content.Context;
    127 import android.content.Intent;
    128 import android.content.IntentFilter;
    129 import android.content.pm.ApplicationInfo;
    130 import android.content.pm.PackageManager;
    131 import android.content.pm.PackageManagerInternal;
    132 import android.content.res.Configuration;
    133 import android.database.ContentObserver;
    134 import android.graphics.Bitmap;
    135 import android.graphics.GraphicBuffer;
    136 import android.graphics.Matrix;
    137 import android.graphics.Point;
    138 import android.graphics.Rect;
    139 import android.graphics.RectF;
    140 import android.graphics.Region;
    141 import android.hardware.configstore.V1_0.ISurfaceFlingerConfigs;
    142 import android.hardware.configstore.V1_0.OptionalBool;
    143 import android.hardware.display.DisplayManager;
    144 import android.hardware.display.DisplayManagerInternal;
    145 import android.hardware.input.InputManager;
    146 import android.net.Uri;
    147 import android.os.Binder;
    148 import android.os.Build;
    149 import android.os.Bundle;
    150 import android.os.Debug;
    151 import android.os.Handler;
    152 import android.os.IBinder;
    153 import android.os.IRemoteCallback;
    154 import android.os.Looper;
    155 import android.os.Message;
    156 import android.os.Parcel;
    157 import android.os.ParcelFileDescriptor;
    158 import android.os.PowerManager;
    159 import android.os.PowerManager.ServiceType;
    160 import android.os.PowerManagerInternal;
    161 import android.os.PowerSaveState;
    162 import android.os.RemoteException;
    163 import android.os.ResultReceiver;
    164 import android.os.ServiceManager;
    165 import android.os.ShellCallback;
    166 import android.os.StrictMode;
    167 import android.os.SystemClock;
    168 import android.os.SystemProperties;
    169 import android.os.SystemService;
    170 import android.os.Trace;
    171 import android.os.UserHandle;
    172 import android.os.WorkSource;
    173 import android.provider.Settings;
    174 import android.text.format.DateUtils;
    175 import android.util.ArrayMap;
    176 import android.util.ArraySet;
    177 import android.util.DisplayMetrics;
    178 import android.util.EventLog;
    179 import android.util.Log;
    180 import android.util.MergedConfiguration;
    181 import android.util.Pair;
    182 import android.util.Slog;
    183 import android.util.SparseBooleanArray;
    184 import android.util.SparseIntArray;
    185 import android.util.TimeUtils;
    186 import android.util.TypedValue;
    187 import android.util.proto.ProtoOutputStream;
    188 import android.view.AppTransitionAnimationSpec;
    189 import android.view.Display;
    190 import android.view.DisplayCutout;
    191 import android.view.DisplayInfo;
    192 import android.view.Gravity;
    193 import android.view.IAppTransitionAnimationSpecsFuture;
    194 import android.view.IDockedStackListener;
    195 import android.view.IInputFilter;
    196 import android.view.IOnKeyguardExitResult;
    197 import android.view.IPinnedStackListener;
    198 import android.view.IRecentsAnimationRunner;
    199 import android.view.IRotationWatcher;
    200 import android.view.IWallpaperVisibilityListener;
    201 import android.view.IWindow;
    202 import android.view.IWindowId;
    203 import android.view.IWindowManager;
    204 import android.view.IWindowSession;
    205 import android.view.IWindowSessionCallback;
    206 import android.view.InputChannel;
    207 import android.view.InputDevice;
    208 import android.view.InputEventReceiver;
    209 import android.view.KeyEvent;
    210 import android.view.MagnificationSpec;
    211 import android.view.MotionEvent;
    212 import android.view.PointerIcon;
    213 import android.view.RemoteAnimationAdapter;
    214 import android.view.Surface;
    215 import android.view.SurfaceControl;
    216 import android.view.SurfaceSession;
    217 import android.view.View;
    218 import android.view.WindowContentFrameStats;
    219 import android.view.WindowManager;
    220 import android.view.WindowManager.LayoutParams;
    221 import android.view.WindowManager.TransitionFlags;
    222 import android.view.WindowManager.TransitionType;
    223 import android.view.WindowManagerGlobal;
    224 import android.view.WindowManagerPolicyConstants.PointerEventListener;
    225 import android.view.inputmethod.InputMethodManagerInternal;
    226 
    227 import com.android.internal.R;
    228 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
    229 import com.android.internal.os.IResultReceiver;
    230 import com.android.internal.policy.IKeyguardDismissCallback;
    231 import com.android.internal.policy.IShortcutService;
    232 import com.android.internal.util.DumpUtils;
    233 import com.android.internal.util.FastPrintWriter;
    234 import com.android.internal.util.LatencyTracker;
    235 import com.android.internal.view.IInputContext;
    236 import com.android.internal.view.IInputMethodClient;
    237 import com.android.internal.view.IInputMethodManager;
    238 import com.android.internal.view.WindowManagerPolicyThread;
    239 import com.android.server.AnimationThread;
    240 import com.android.server.DisplayThread;
    241 import com.android.server.EventLogTags;
    242 import com.android.server.FgThread;
    243 import com.android.server.LocalServices;
    244 import com.android.server.UiThread;
    245 import com.android.server.Watchdog;
    246 import com.android.server.input.InputManagerService;
    247 import com.android.server.policy.WindowManagerPolicy;
    248 import com.android.server.policy.WindowManagerPolicy.ScreenOffListener;
    249 import com.android.server.power.ShutdownThread;
    250 import com.android.server.utils.PriorityDump;
    251 
    252 import java.io.BufferedWriter;
    253 import java.io.DataInputStream;
    254 import java.io.File;
    255 import java.io.FileDescriptor;
    256 import java.io.FileInputStream;
    257 import java.io.FileNotFoundException;
    258 import java.io.IOException;
    259 import java.io.OutputStream;
    260 import java.io.OutputStreamWriter;
    261 import java.io.PrintWriter;
    262 import java.io.StringWriter;
    263 import java.lang.annotation.Retention;
    264 import java.lang.annotation.RetentionPolicy;
    265 import java.net.Socket;
    266 import java.text.DateFormat;
    267 import java.util.ArrayList;
    268 import java.util.Arrays;
    269 import java.util.Date;
    270 import java.util.List;
    271 /** {@hide} */
    272 public class WindowManagerService extends IWindowManager.Stub
    273         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    274     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowManagerService" : TAG_WM;
    275 
    276     static final int LAYOUT_REPEAT_THRESHOLD = 4;
    277 
    278     static final boolean PROFILE_ORIENTATION = false;
    279     static final boolean localLOGV = DEBUG;
    280 
    281     /** How much to multiply the policy's type layer, to reserve room
    282      * for multiple windows of the same type and Z-ordering adjustment
    283      * with TYPE_LAYER_OFFSET. */
    284     static final int TYPE_LAYER_MULTIPLIER = 10000;
    285 
    286     /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
    287      * or below others in the same layer. */
    288     static final int TYPE_LAYER_OFFSET = 1000;
    289 
    290     /** How much to increment the layer for each window, to reserve room
    291      * for effect surfaces between them.
    292      */
    293     static final int WINDOW_LAYER_MULTIPLIER = 5;
    294 
    295     /**
    296      * Dim surface layer is immediately below target window.
    297      */
    298     static final int LAYER_OFFSET_DIM = 1;
    299 
    300     /**
    301      * Animation thumbnail is as far as possible below the window above
    302      * the thumbnail (or in other words as far as possible above the window
    303      * below it).
    304      */
    305     static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1;
    306 
    307     /** The maximum length we will accept for a loaded animation duration:
    308      * this is 10 seconds.
    309      */
    310     static final int MAX_ANIMATION_DURATION = 10 * 1000;
    311 
    312     /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
    313     static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
    314 
    315     /** Amount of time (in milliseconds) to delay before declaring a seamless rotation timeout. */
    316     static final int SEAMLESS_ROTATION_TIMEOUT_DURATION = 2000;
    317 
    318     /** Amount of time (in milliseconds) to delay before declaring a window replacement timeout. */
    319     static final int WINDOW_REPLACEMENT_TIMEOUT_DURATION = 2000;
    320 
    321     /** Amount of time to allow a last ANR message to exist before freeing the memory. */
    322     static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
    323     /**
    324      * If true, the window manager will do its own custom freezing and general
    325      * management of the screen during rotation.
    326      */
    327     static final boolean CUSTOM_SCREEN_ROTATION = true;
    328 
    329     // Maximum number of milliseconds to wait for input devices to be enumerated before
    330     // proceding with safe mode detection.
    331     private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
    332 
    333     // Default input dispatching timeout in nanoseconds.
    334     static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
    335 
    336     // Poll interval in milliseconds for watching boot animation finished.
    337     private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
    338 
    339     // The name of the boot animation service in init.rc.
    340     private static final String BOOT_ANIMATION_SERVICE = "bootanim";
    341 
    342     static final int UPDATE_FOCUS_NORMAL = 0;
    343     static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
    344     static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
    345     static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
    346 
    347     private static final String SYSTEM_SECURE = "ro.secure";
    348     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    349 
    350     private static final String DENSITY_OVERRIDE = "ro.config.density_override";
    351     private static final String SIZE_OVERRIDE = "ro.config.size_override";
    352 
    353     private static final int MAX_SCREENSHOT_RETRIES = 3;
    354 
    355     private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
    356 
    357     // Used to indicate that if there is already a transition set, it should be preserved when
    358     // trying to apply a new one.
    359     private static final boolean ALWAYS_KEEP_CURRENT = true;
    360 
    361     // Enums for animation scale update types.
    362     @Retention(RetentionPolicy.SOURCE)
    363     @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
    364     private @interface UpdateAnimationScaleMode {};
    365     private static final int WINDOW_ANIMATION_SCALE = 0;
    366     private static final int TRANSITION_ANIMATION_SCALE = 1;
    367     private static final int ANIMATION_DURATION_SCALE = 2;
    368 
    369     final WindowTracing mWindowTracing;
    370 
    371     final private KeyguardDisableHandler mKeyguardDisableHandler;
    372     // TODO: eventually unify all keyguard state in a common place instead of having it spread over
    373     // AM's KeyguardController and the policy's KeyguardServiceDelegate.
    374     boolean mKeyguardGoingAway;
    375     boolean mKeyguardOrAodShowingOnDefaultDisplay;
    376     // VR Vr2d Display Id.
    377     int mVr2dDisplayId = INVALID_DISPLAY;
    378 
    379     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    380         @Override
    381         public void onReceive(Context context, Intent intent) {
    382             switch (intent.getAction()) {
    383                 case ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED:
    384                     mKeyguardDisableHandler.sendEmptyMessage(KEYGUARD_POLICY_CHANGED);
    385                     break;
    386             }
    387         }
    388     };
    389     final WindowSurfacePlacer mWindowPlacerLocked;
    390 
    391     private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
    392         @Override
    393         public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
    394                 boolean asProto) {
    395             doDump(fd, pw, new String[] {"-a"}, asProto);
    396         }
    397 
    398         @Override
    399         public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
    400             doDump(fd, pw, args, asProto);
    401         }
    402     };
    403 
    404     /**
    405      * Current user when multi-user is enabled. Don't show windows of
    406      * non-current user. Also see mCurrentProfileIds.
    407      */
    408     int mCurrentUserId;
    409     /**
    410      * Users that are profiles of the current user. These are also allowed to show windows
    411      * on the current user.
    412      */
    413     int[] mCurrentProfileIds = new int[] {};
    414 
    415     final Context mContext;
    416 
    417     final boolean mHaveInputMethods;
    418 
    419     final boolean mHasPermanentDpad;
    420     final long mDrawLockTimeoutMillis;
    421     final boolean mAllowAnimationsInLowPowerMode;
    422 
    423     final boolean mAllowBootMessages;
    424 
    425     final boolean mLimitedAlphaCompositing;
    426     final int mMaxUiWidth;
    427 
    428     final WindowManagerPolicy mPolicy;
    429 
    430     final IActivityManager mActivityManager;
    431     final ActivityManagerInternal mAmInternal;
    432 
    433     final AppOpsManager mAppOps;
    434     final PackageManagerInternal mPmInternal;
    435 
    436     final DisplaySettings mDisplaySettings;
    437 
    438     /** If the system should display notifications for apps displaying an alert window. */
    439     boolean mShowAlertWindowNotifications = true;
    440 
    441     /**
    442      * All currently active sessions with clients.
    443      */
    444     final ArraySet<Session> mSessions = new ArraySet<>();
    445 
    446     /**
    447      * Mapping from an IWindow IBinder to the server's Window object.
    448      * This is also used as the lock for all of our state.
    449      * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
    450      */
    451     final WindowHashMap mWindowMap = new WindowHashMap();
    452 
    453     /**
    454      * List of window tokens that have finished starting their application,
    455      * and now need to have the policy remove their windows.
    456      */
    457     final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>();
    458 
    459     /**
    460      * List of app window tokens that are waiting for replacing windows. If the
    461      * replacement doesn't come in time the stale windows needs to be disposed of.
    462      */
    463     final ArrayList<AppWindowToken> mWindowReplacementTimeouts = new ArrayList<>();
    464 
    465     /**
    466      * Windows that are being resized.  Used so we can tell the client about
    467      * the resize after closing the transaction in which we resized the
    468      * underlying surface.
    469      */
    470     final ArrayList<WindowState> mResizingWindows = new ArrayList<>();
    471 
    472     /**
    473      * Windows whose animations have ended and now must be removed.
    474      */
    475     final ArrayList<WindowState> mPendingRemove = new ArrayList<>();
    476 
    477     /**
    478      * Used when processing mPendingRemove to avoid working on the original array.
    479      */
    480     WindowState[] mPendingRemoveTmp = new WindowState[20];
    481 
    482     /**
    483      * Windows whose surface should be destroyed.
    484      */
    485     final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
    486 
    487     /**
    488      * Windows with a preserved surface waiting to be destroyed. These windows
    489      * are going through a surface change. We keep the old surface around until
    490      * the first frame on the new surface finishes drawing.
    491      */
    492     final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();
    493 
    494     /**
    495      * Windows that have lost input focus and are waiting for the new
    496      * focus window to be displayed before they are told about this.
    497      */
    498     ArrayList<WindowState> mLosingFocus = new ArrayList<>();
    499 
    500     /**
    501      * This is set when we have run out of memory, and will either be an empty
    502      * list or contain windows that need to be force removed.
    503      */
    504     final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
    505 
    506     /**
    507      * Windows that clients are waiting to have drawn.
    508      */
    509     ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
    510     /**
    511      * And the callback to make when they've all been drawn.
    512      */
    513     Runnable mWaitingForDrawnCallback;
    514 
    515     /** List of window currently causing non-system overlay windows to be hidden. */
    516     private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
    517 
    518     IInputMethodManager mInputMethodManager;
    519 
    520     AccessibilityController mAccessibilityController;
    521     private RecentsAnimationController mRecentsAnimationController;
    522 
    523     Watermark mWatermark;
    524     StrictModeFlash mStrictModeFlash;
    525     CircularDisplayMask mCircularDisplayMask;
    526     EmulatorDisplayOverlay mEmulatorDisplayOverlay;
    527 
    528     final float[] mTmpFloats = new float[9];
    529     final Rect mTmpRect = new Rect();
    530     final Rect mTmpRect2 = new Rect();
    531     final Rect mTmpRect3 = new Rect();
    532     final RectF mTmpRectF = new RectF();
    533 
    534     final Matrix mTmpTransform = new Matrix();
    535 
    536     boolean mDisplayReady;
    537     boolean mSafeMode;
    538     boolean mDisplayEnabled = false;
    539     boolean mSystemBooted = false;
    540     boolean mForceDisplayEnabled = false;
    541     boolean mShowingBootMessages = false;
    542     boolean mBootAnimationStopped = false;
    543 
    544     // Following variables are for debugging screen wakelock only.
    545     WindowState mLastWakeLockHoldingWindow = null;
    546     WindowState mLastWakeLockObscuringWindow = null;
    547 
    548     /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
    549      * LAST_ANR_LIFETIME_DURATION_MSECS */
    550     String mLastANRState;
    551 
    552     // The root of the device window hierarchy.
    553     RootWindowContainer mRoot;
    554 
    555     int mDockedStackCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
    556     Rect mDockedStackCreateBounds;
    557 
    558     boolean mForceResizableTasks = false;
    559     boolean mSupportsPictureInPicture = false;
    560 
    561     boolean mDisableTransitionAnimation = false;
    562 
    563     int getDragLayerLocked() {
    564         return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
    565     }
    566 
    567     class RotationWatcher {
    568         final IRotationWatcher mWatcher;
    569         final IBinder.DeathRecipient mDeathRecipient;
    570         final int mDisplayId;
    571         RotationWatcher(IRotationWatcher watcher, IBinder.DeathRecipient deathRecipient,
    572                 int displayId) {
    573             mWatcher = watcher;
    574             mDeathRecipient = deathRecipient;
    575             mDisplayId = displayId;
    576         }
    577     }
    578 
    579     ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
    580     int mDeferredRotationPauseCount;
    581     final WallpaperVisibilityListeners mWallpaperVisibilityListeners =
    582             new WallpaperVisibilityListeners();
    583 
    584     int mSystemDecorLayer = 0;
    585     final Rect mScreenRect = new Rect();
    586 
    587     boolean mDisplayFrozen = false;
    588     long mDisplayFreezeTime = 0;
    589     int mLastDisplayFreezeDuration = 0;
    590     Object mLastFinishedFreezeSource = null;
    591     boolean mWaitingForConfig = false;
    592     boolean mSwitchingUser = false;
    593 
    594     final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
    595     final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
    596     final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
    597     int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
    598 
    599     boolean mClientFreezingScreen = false;
    600     int mAppsFreezingScreen = 0;
    601 
    602     // Last systemUiVisibility we received from status bar.
    603     int mLastStatusBarVisibility = 0;
    604     // Last systemUiVisibility we dispatched to windows.
    605     int mLastDispatchedSystemUiVisibility = 0;
    606 
    607     // State while inside of layoutAndPlaceSurfacesLocked().
    608     boolean mFocusMayChange;
    609 
    610     // This is held as long as we have the screen frozen, to give us time to
    611     // perform a rotation animation when turning off shows the lock screen which
    612     // changes the orientation.
    613     private final PowerManager.WakeLock mScreenFrozenLock;
    614 
    615     final AppTransition mAppTransition;
    616     boolean mSkipAppTransitionAnimation = false;
    617 
    618     final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>();
    619     final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>();
    620 
    621     final UnknownAppVisibilityController mUnknownAppVisibilityController =
    622             new UnknownAppVisibilityController(this);
    623     final TaskSnapshotController mTaskSnapshotController;
    624 
    625     boolean mIsTouchDevice;
    626 
    627     final H mH = new H();
    628 
    629     /**
    630      * Handler for things to run that have direct impact on an animation, i.e. animation tick,
    631      * layout, starting window creation, whereas {@link H} runs things that are still important, but
    632      * not as critical.
    633      */
    634     final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());
    635 
    636     WindowState mCurrentFocus = null;
    637     WindowState mLastFocus = null;
    638 
    639     /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
    640     private final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
    641     /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
    642     private final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>();
    643 
    644     /** This just indicates the window the input method is on top of, not
    645      * necessarily the window its input is going to. */
    646     WindowState mInputMethodTarget = null;
    647 
    648     /** If true hold off on modifying the animation layer of mInputMethodTarget */
    649     boolean mInputMethodTargetWaitingAnim;
    650 
    651     WindowState mInputMethodWindow = null;
    652 
    653     boolean mHardKeyboardAvailable;
    654     WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
    655     SettingsObserver mSettingsObserver;
    656 
    657     /**
    658      * A count of the windows which are 'seamlessly rotated', e.g. a surface
    659      * at an old orientation is being transformed. We freeze orientation updates
    660      * while any windows are seamlessly rotated, so we need to track when this
    661      * hits zero so we can apply deferred orientation updates.
    662      */
    663     private int mSeamlessRotationCount = 0;
    664     /**
    665      * True in the interval from starting seamless rotation until the last rotated
    666      * window draws in the new orientation.
    667      */
    668     private boolean mRotatingSeamlessly = false;
    669 
    670     private final class SettingsObserver extends ContentObserver {
    671         private final Uri mDisplayInversionEnabledUri =
    672                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
    673         private final Uri mWindowAnimationScaleUri =
    674                 Settings.Global.getUriFor(Settings.Global.WINDOW_ANIMATION_SCALE);
    675         private final Uri mTransitionAnimationScaleUri =
    676                 Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE);
    677         private final Uri mAnimationDurationScaleUri =
    678                 Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE);
    679 
    680         public SettingsObserver() {
    681             super(new Handler());
    682             ContentResolver resolver = mContext.getContentResolver();
    683             resolver.registerContentObserver(mDisplayInversionEnabledUri, false, this,
    684                     UserHandle.USER_ALL);
    685             resolver.registerContentObserver(mWindowAnimationScaleUri, false, this,
    686                     UserHandle.USER_ALL);
    687             resolver.registerContentObserver(mTransitionAnimationScaleUri, false, this,
    688                     UserHandle.USER_ALL);
    689             resolver.registerContentObserver(mAnimationDurationScaleUri, false, this,
    690                     UserHandle.USER_ALL);
    691         }
    692 
    693         @Override
    694         public void onChange(boolean selfChange, Uri uri) {
    695             if (uri == null) {
    696                 return;
    697             }
    698 
    699             if (mDisplayInversionEnabledUri.equals(uri)) {
    700                 updateCircularDisplayMaskIfNeeded();
    701             } else {
    702                 @UpdateAnimationScaleMode
    703                 final int mode;
    704                 if (mWindowAnimationScaleUri.equals(uri)) {
    705                     mode = WINDOW_ANIMATION_SCALE;
    706                 } else if (mTransitionAnimationScaleUri.equals(uri)) {
    707                     mode = TRANSITION_ANIMATION_SCALE;
    708                 } else if (mAnimationDurationScaleUri.equals(uri)) {
    709                     mode = ANIMATION_DURATION_SCALE;
    710                 } else {
    711                     // Ignoring unrecognized content changes
    712                     return;
    713                 }
    714                 Message m = mH.obtainMessage(H.UPDATE_ANIMATION_SCALE, mode, 0);
    715                 mH.sendMessage(m);
    716             }
    717         }
    718     }
    719 
    720     // TODO: Move to RootWindowContainer
    721     AppWindowToken mFocusedApp = null;
    722 
    723     PowerManager mPowerManager;
    724     PowerManagerInternal mPowerManagerInternal;
    725 
    726     private float mWindowAnimationScaleSetting = 1.0f;
    727     private float mTransitionAnimationScaleSetting = 1.0f;
    728     private float mAnimatorDurationScaleSetting = 1.0f;
    729     private boolean mAnimationsDisabled = false;
    730 
    731     final InputManagerService mInputManager;
    732     final DisplayManagerInternal mDisplayManagerInternal;
    733     final DisplayManager mDisplayManager;
    734 
    735     // Indicates whether this device supports wide color gamut rendering
    736     private boolean mHasWideColorGamutSupport;
    737 
    738     // Who is holding the screen on.
    739     private Session mHoldingScreenOn;
    740     private PowerManager.WakeLock mHoldingScreenWakeLock;
    741 
    742     // Whether or not a layout can cause a wake up when theater mode is enabled.
    743     boolean mAllowTheaterModeWakeFromLayout;
    744 
    745     final TaskPositioningController mTaskPositioningController;
    746     final DragDropController mDragDropController;
    747 
    748     // For frozen screen animations.
    749     private int mExitAnimId, mEnterAnimId;
    750 
    751     // The display that the rotation animation is applying to.
    752     private int mFrozenDisplayId;
    753 
    754     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
    755      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
    756     int mTransactionSequence;
    757 
    758     final WindowAnimator mAnimator;
    759     final SurfaceAnimationRunner mSurfaceAnimationRunner;
    760 
    761     /**
    762      * Keeps track of which animations got transferred to which animators. Entries will get cleaned
    763      * up when the animation finishes.
    764      */
    765     final ArrayMap<AnimationAdapter, SurfaceAnimator> mAnimationTransferMap = new ArrayMap<>();
    766     final BoundsAnimationController mBoundsAnimationController;
    767 
    768     private final PointerEventDispatcher mPointerEventDispatcher;
    769 
    770     private WindowContentFrameStats mTempWindowRenderStats;
    771 
    772     private final LatencyTracker mLatencyTracker;
    773 
    774     /**
    775      * Whether the UI is currently running in touch mode (not showing
    776      * navigational focus because the user is directly pressing the screen).
    777      */
    778     boolean mInTouchMode;
    779 
    780     private ViewServer mViewServer;
    781     final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
    782     boolean mWindowsChanged = false;
    783 
    784     public interface WindowChangeListener {
    785         public void windowsChanged();
    786         public void focusChanged();
    787     }
    788 
    789     final Configuration mTempConfiguration = new Configuration();
    790 
    791     // If true, only the core apps and services are being launched because the device
    792     // is in a special boot mode, such as being encrypted or waiting for a decryption password.
    793     // For example, when this flag is true, there will be no wallpaper service.
    794     final boolean mOnlyCore;
    795 
    796     // List of clients without a transtiton animation that we notify once we are done transitioning
    797     // since they won't be notified through the app window animator.
    798     final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
    799 
    800     static WindowManagerThreadPriorityBooster sThreadPriorityBooster =
    801             new WindowManagerThreadPriorityBooster();
    802 
    803     SurfaceBuilderFactory mSurfaceBuilderFactory = SurfaceControl.Builder::new;
    804     TransactionFactory mTransactionFactory = SurfaceControl.Transaction::new;
    805 
    806     private final SurfaceControl.Transaction mTransaction = mTransactionFactory.make();
    807 
    808     static void boostPriorityForLockedSection() {
    809         sThreadPriorityBooster.boost();
    810     }
    811 
    812     static void resetPriorityAfterLockedSection() {
    813         sThreadPriorityBooster.reset();
    814     }
    815 
    816     void openSurfaceTransaction() {
    817         try {
    818             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "openSurfaceTransaction");
    819             synchronized (mWindowMap) {
    820                 SurfaceControl.openTransaction();
    821             }
    822         } finally {
    823             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    824         }
    825     }
    826 
    827     /**
    828      * Closes a surface transaction.
    829      * @param where debug string indicating where the transaction originated
    830      */
    831     void closeSurfaceTransaction(String where) {
    832         try {
    833             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "closeSurfaceTransaction");
    834             synchronized (mWindowMap) {
    835                 try {
    836                     traceStateLocked(where);
    837                 } finally {
    838                     SurfaceControl.closeTransaction();
    839                 }
    840             }
    841         } finally {
    842             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    843         }
    844     }
    845     /** Listener to notify activity manager about app transitions. */
    846     final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
    847             = new WindowManagerInternal.AppTransitionListener() {
    848 
    849         @Override
    850         public void onAppTransitionCancelledLocked(int transit) {
    851             mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_CANCELLED);
    852         }
    853 
    854         @Override
    855         public void onAppTransitionFinishedLocked(IBinder token) {
    856             mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_FINISHED);
    857             final AppWindowToken atoken = mRoot.getAppWindowToken(token);
    858             if (atoken == null) {
    859                 return;
    860             }
    861             if (atoken.mLaunchTaskBehind) {
    862                 try {
    863                     mActivityManager.notifyLaunchTaskBehindComplete(atoken.token);
    864                 } catch (RemoteException e) {
    865                 }
    866                 atoken.mLaunchTaskBehind = false;
    867             } else {
    868                 atoken.updateReportedVisibilityLocked();
    869                 if (atoken.mEnteringAnimation) {
    870                     if (getRecentsAnimationController() != null
    871                             && getRecentsAnimationController().isTargetApp(atoken)) {
    872                         // Currently running a recents animation, this will get called early because
    873                         // we show the recents animation target activity immediately when the
    874                         // animation starts. In this case, we should defer sending the finished
    875                         // callback until the animation successfully finishes
    876                         return;
    877                     } else {
    878                         atoken.mEnteringAnimation = false;
    879                         try {
    880                             mActivityManager.notifyEnterAnimationComplete(atoken.token);
    881                         } catch (RemoteException e) {
    882                         }
    883                     }
    884                 }
    885             }
    886         }
    887     };
    888 
    889     final ArrayList<AppFreezeListener> mAppFreezeListeners = new ArrayList<>();
    890 
    891     interface AppFreezeListener {
    892         void onAppFreezeTimeout();
    893     }
    894 
    895     private static WindowManagerService sInstance;
    896     static WindowManagerService getInstance() {
    897         return sInstance;
    898     }
    899 
    900     public static WindowManagerService main(final Context context, final InputManagerService im,
    901             final boolean haveInputMethods, final boolean showBootMsgs, final boolean onlyCore,
    902             WindowManagerPolicy policy) {
    903         DisplayThread.getHandler().runWithScissors(() ->
    904                 sInstance = new WindowManagerService(context, im, haveInputMethods, showBootMsgs,
    905                         onlyCore, policy), 0);
    906         return sInstance;
    907     }
    908 
    909     private void initPolicy() {
    910         UiThread.getHandler().runWithScissors(new Runnable() {
    911             @Override
    912             public void run() {
    913                 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
    914                 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
    915             }
    916         }, 0);
    917     }
    918 
    919     @Override
    920     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
    921             String[] args, ShellCallback callback, ResultReceiver result) {
    922         new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result);
    923     }
    924 
    925     private WindowManagerService(Context context, InputManagerService inputManager,
    926             boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
    927             WindowManagerPolicy policy) {
    928         installLock(this, INDEX_WINDOW);
    929         mContext = context;
    930         mHaveInputMethods = haveInputMethods;
    931         mAllowBootMessages = showBootMsgs;
    932         mOnlyCore = onlyCore;
    933         mLimitedAlphaCompositing = context.getResources().getBoolean(
    934                 com.android.internal.R.bool.config_sf_limitedAlpha);
    935         mHasPermanentDpad = context.getResources().getBoolean(
    936                 com.android.internal.R.bool.config_hasPermanentDpad);
    937         mInTouchMode = context.getResources().getBoolean(
    938                 com.android.internal.R.bool.config_defaultInTouchMode);
    939         mDrawLockTimeoutMillis = context.getResources().getInteger(
    940                 com.android.internal.R.integer.config_drawLockTimeoutMillis);
    941         mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
    942                 com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
    943         mMaxUiWidth = context.getResources().getInteger(
    944                 com.android.internal.R.integer.config_maxUiWidth);
    945         mDisableTransitionAnimation = context.getResources().getBoolean(
    946                 com.android.internal.R.bool.config_disableTransitionAnimation);
    947         mInputManager = inputManager; // Must be before createDisplayContentLocked.
    948         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
    949         mDisplaySettings = new DisplaySettings();
    950         mDisplaySettings.readSettingsLocked();
    951 
    952         mPolicy = policy;
    953         mAnimator = new WindowAnimator(this);
    954         mRoot = new RootWindowContainer(this);
    955 
    956         mWindowPlacerLocked = new WindowSurfacePlacer(this);
    957         mTaskSnapshotController = new TaskSnapshotController(this);
    958 
    959         mWindowTracing = WindowTracing.createDefaultAndStartLooper(context);
    960 
    961         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
    962 
    963         if(mInputManager != null) {
    964             final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM);
    965             mPointerEventDispatcher = inputChannel != null
    966                     ? new PointerEventDispatcher(inputChannel) : null;
    967         } else {
    968             mPointerEventDispatcher = null;
    969         }
    970 
    971         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
    972 
    973         mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
    974 
    975         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    976         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
    977 
    978         if (mPowerManagerInternal != null) {
    979             mPowerManagerInternal.registerLowPowerModeObserver(
    980                     new PowerManagerInternal.LowPowerModeListener() {
    981                 @Override
    982                 public int getServiceType() {
    983                     return ServiceType.ANIMATION;
    984                 }
    985 
    986                 @Override
    987                 public void onLowPowerModeChanged(PowerSaveState result) {
    988                     synchronized (mWindowMap) {
    989                         final boolean enabled = result.batterySaverEnabled;
    990                         if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
    991                             mAnimationsDisabled = enabled;
    992                             dispatchNewAnimatorScaleLocked(null);
    993                         }
    994                     }
    995                 }
    996             });
    997             mAnimationsDisabled = mPowerManagerInternal
    998                     .getLowPowerState(ServiceType.ANIMATION).batterySaverEnabled;
    999         }
   1000         mScreenFrozenLock = mPowerManager.newWakeLock(
   1001                 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
   1002         mScreenFrozenLock.setReferenceCounted(false);
   1003 
   1004         mAppTransition = new AppTransition(context, this);
   1005         mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
   1006 
   1007         final AnimationHandler animationHandler = new AnimationHandler();
   1008         animationHandler.setProvider(new SfVsyncFrameCallbackProvider());
   1009         mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
   1010                 AnimationThread.getHandler(), animationHandler);
   1011 
   1012         mActivityManager = ActivityManager.getService();
   1013         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
   1014         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
   1015         AppOpsManager.OnOpChangedInternalListener opListener =
   1016                 new AppOpsManager.OnOpChangedInternalListener() {
   1017                     @Override public void onOpChanged(int op, String packageName) {
   1018                         updateAppOpsState();
   1019                     }
   1020                 };
   1021         mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
   1022         mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
   1023 
   1024         mPmInternal = LocalServices.getService(PackageManagerInternal.class);
   1025         final IntentFilter suspendPackagesFilter = new IntentFilter();
   1026         suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
   1027         suspendPackagesFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
   1028         context.registerReceiverAsUser(new BroadcastReceiver() {
   1029             @Override
   1030             public void onReceive(Context context, Intent intent) {
   1031                 final String[] affectedPackages =
   1032                         intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
   1033                 final boolean suspended =
   1034                         Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
   1035                 updateHiddenWhileSuspendedState(new ArraySet<>(Arrays.asList(affectedPackages)),
   1036                         suspended);
   1037             }
   1038         }, UserHandle.ALL, suspendPackagesFilter, null, null);
   1039 
   1040         // Get persisted window scale setting
   1041         mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
   1042                 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
   1043         mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
   1044                 Settings.Global.TRANSITION_ANIMATION_SCALE,
   1045                 context.getResources().getFloat(
   1046                         R.dimen.config_appTransitionAnimationDurationScaleDefault));
   1047 
   1048         setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
   1049                 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
   1050 
   1051         IntentFilter filter = new IntentFilter();
   1052         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
   1053         filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
   1054         mContext.registerReceiver(mBroadcastReceiver, filter);
   1055 
   1056         mLatencyTracker = LatencyTracker.getInstance(context);
   1057 
   1058         mSettingsObserver = new SettingsObserver();
   1059 
   1060         mHoldingScreenWakeLock = mPowerManager.newWakeLock(
   1061                 PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
   1062         mHoldingScreenWakeLock.setReferenceCounted(false);
   1063 
   1064         mSurfaceAnimationRunner = new SurfaceAnimationRunner();
   1065 
   1066         mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
   1067                 com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
   1068 
   1069         mTaskPositioningController = new TaskPositioningController(
   1070                 this, mInputManager, mInputMonitor, mActivityManager, mH.getLooper());
   1071         mDragDropController = new DragDropController(this, mH.getLooper());
   1072 
   1073         LocalServices.addService(WindowManagerInternal.class, new LocalService());
   1074     }
   1075 
   1076     /**
   1077      * Called after all entities (such as the {@link ActivityManagerService}) have been set up and
   1078      * associated with the {@link WindowManagerService}.
   1079      */
   1080     public void onInitReady() {
   1081         initPolicy();
   1082 
   1083         // Add ourself to the Watchdog monitors.
   1084         Watchdog.getInstance().addMonitor(this);
   1085 
   1086         openSurfaceTransaction();
   1087         try {
   1088             createWatermarkInTransaction();
   1089         } finally {
   1090             closeSurfaceTransaction("createWatermarkInTransaction");
   1091         }
   1092 
   1093         showEmulatorDisplayOverlayIfNeeded();
   1094     }
   1095 
   1096 
   1097     public InputMonitor getInputMonitor() {
   1098         return mInputMonitor;
   1099     }
   1100 
   1101     @Override
   1102     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1103             throws RemoteException {
   1104         try {
   1105             return super.onTransact(code, data, reply, flags);
   1106         } catch (RuntimeException e) {
   1107             // The window manager only throws security exceptions, so let's
   1108             // log all others.
   1109             if (!(e instanceof SecurityException)) {
   1110                 Slog.wtf(TAG_WM, "Window Manager Crash", e);
   1111             }
   1112             throw e;
   1113         }
   1114     }
   1115 
   1116     static boolean excludeWindowTypeFromTapOutTask(int windowType) {
   1117         switch (windowType) {
   1118             case TYPE_STATUS_BAR:
   1119             case TYPE_NAVIGATION_BAR:
   1120             case TYPE_INPUT_METHOD_DIALOG:
   1121                 return true;
   1122         }
   1123         return false;
   1124     }
   1125 
   1126     public int addWindow(Session session, IWindow client, int seq,
   1127             LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,
   1128             Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
   1129             DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel) {
   1130         int[] appOp = new int[1];
   1131         int res = mPolicy.checkAddPermission(attrs, appOp);
   1132         if (res != WindowManagerGlobal.ADD_OKAY) {
   1133             return res;
   1134         }
   1135 
   1136         boolean reportNewConfig = false;
   1137         WindowState parentWindow = null;
   1138         long origId;
   1139         final int callingUid = Binder.getCallingUid();
   1140         final int type = attrs.type;
   1141 
   1142         synchronized(mWindowMap) {
   1143             if (!mDisplayReady) {
   1144                 throw new IllegalStateException("Display has not been initialialized");
   1145             }
   1146 
   1147             final DisplayContent displayContent = getDisplayContentOrCreate(displayId);
   1148 
   1149             if (displayContent == null) {
   1150                 Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
   1151                         + displayId + ".  Aborting.");
   1152                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
   1153             }
   1154             if (!displayContent.hasAccess(session.mUid)
   1155                     && !mDisplayManagerInternal.isUidPresentOnDisplay(session.mUid, displayId)) {
   1156                 Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
   1157                         + "does not have access: " + displayId + ".  Aborting.");
   1158                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
   1159             }
   1160 
   1161             if (mWindowMap.containsKey(client.asBinder())) {
   1162                 Slog.w(TAG_WM, "Window " + client + " is already added");
   1163                 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
   1164             }
   1165 
   1166             if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
   1167                 parentWindow = windowForClientLocked(null, attrs.token, false);
   1168                 if (parentWindow == null) {
   1169                     Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
   1170                           + attrs.token + ".  Aborting.");
   1171                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
   1172                 }
   1173                 if (parentWindow.mAttrs.type >= FIRST_SUB_WINDOW
   1174                         && parentWindow.mAttrs.type <= LAST_SUB_WINDOW) {
   1175                     Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
   1176                             + attrs.token + ".  Aborting.");
   1177                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
   1178                 }
   1179             }
   1180 
   1181             if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
   1182                 Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display.  Aborting.");
   1183                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
   1184             }
   1185 
   1186             AppWindowToken atoken = null;
   1187             final boolean hasParent = parentWindow != null;
   1188             // Use existing parent window token for child windows since they go in the same token
   1189             // as there parent window so we can apply the same policy on them.
   1190             WindowToken token = displayContent.getWindowToken(
   1191                     hasParent ? parentWindow.mAttrs.token : attrs.token);
   1192             // If this is a child window, we want to apply the same type checking rules as the
   1193             // parent window type.
   1194             final int rootType = hasParent ? parentWindow.mAttrs.type : type;
   1195 
   1196             boolean addToastWindowRequiresToken = false;
   1197 
   1198             if (token == null) {
   1199                 if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
   1200                     Slog.w(TAG_WM, "Attempted to add application window with unknown token "
   1201                           + attrs.token + ".  Aborting.");
   1202                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1203                 }
   1204                 if (rootType == TYPE_INPUT_METHOD) {
   1205                     Slog.w(TAG_WM, "Attempted to add input method window with unknown token "
   1206                           + attrs.token + ".  Aborting.");
   1207                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1208                 }
   1209                 if (rootType == TYPE_VOICE_INTERACTION) {
   1210                     Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token "
   1211                           + attrs.token + ".  Aborting.");
   1212                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1213                 }
   1214                 if (rootType == TYPE_WALLPAPER) {
   1215                     Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token "
   1216                           + attrs.token + ".  Aborting.");
   1217                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1218                 }
   1219                 if (rootType == TYPE_DREAM) {
   1220                     Slog.w(TAG_WM, "Attempted to add Dream window with unknown token "
   1221                           + attrs.token + ".  Aborting.");
   1222                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1223                 }
   1224                 if (rootType == TYPE_QS_DIALOG) {
   1225                     Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token "
   1226                           + attrs.token + ".  Aborting.");
   1227                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1228                 }
   1229                 if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
   1230                     Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token "
   1231                             + attrs.token + ".  Aborting.");
   1232                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1233                 }
   1234                 if (type == TYPE_TOAST) {
   1235                     // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
   1236                     if (doesAddToastWindowRequireToken(attrs.packageName, callingUid,
   1237                             parentWindow)) {
   1238                         Slog.w(TAG_WM, "Attempted to add a toast window with unknown token "
   1239                                 + attrs.token + ".  Aborting.");
   1240                         return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1241                     }
   1242                 }
   1243                 final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
   1244                 final boolean isRoundedCornerOverlay =
   1245                         (attrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
   1246                 token = new WindowToken(this, binder, type, false, displayContent,
   1247                         session.mCanAddInternalSystemWindow, isRoundedCornerOverlay);
   1248             } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
   1249                 atoken = token.asAppWindowToken();
   1250                 if (atoken == null) {
   1251                     Slog.w(TAG_WM, "Attempted to add window with non-application token "
   1252                           + token + ".  Aborting.");
   1253                     return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
   1254                 } else if (atoken.removed) {
   1255                     Slog.w(TAG_WM, "Attempted to add window with exiting application token "
   1256                           + token + ".  Aborting.");
   1257                     return WindowManagerGlobal.ADD_APP_EXITING;
   1258                 } else if (type == TYPE_APPLICATION_STARTING && atoken.startingWindow != null) {
   1259                     Slog.w(TAG_WM, "Attempted to add starting window to token with already existing"
   1260                             + " starting window");
   1261                     return WindowManagerGlobal.ADD_DUPLICATE_ADD;
   1262                 }
   1263             } else if (rootType == TYPE_INPUT_METHOD) {
   1264                 if (token.windowType != TYPE_INPUT_METHOD) {
   1265                     Slog.w(TAG_WM, "Attempted to add input method window with bad token "
   1266                             + attrs.token + ".  Aborting.");
   1267                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1268                 }
   1269             } else if (rootType == TYPE_VOICE_INTERACTION) {
   1270                 if (token.windowType != TYPE_VOICE_INTERACTION) {
   1271                     Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token "
   1272                             + attrs.token + ".  Aborting.");
   1273                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1274                 }
   1275             } else if (rootType == TYPE_WALLPAPER) {
   1276                 if (token.windowType != TYPE_WALLPAPER) {
   1277                     Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token "
   1278                             + attrs.token + ".  Aborting.");
   1279                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1280                 }
   1281             } else if (rootType == TYPE_DREAM) {
   1282                 if (token.windowType != TYPE_DREAM) {
   1283                     Slog.w(TAG_WM, "Attempted to add Dream window with bad token "
   1284                             + attrs.token + ".  Aborting.");
   1285                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1286                 }
   1287             } else if (rootType == TYPE_ACCESSIBILITY_OVERLAY) {
   1288                 if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
   1289                     Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token "
   1290                             + attrs.token + ".  Aborting.");
   1291                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1292                 }
   1293             } else if (type == TYPE_TOAST) {
   1294                 // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
   1295                 addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName,
   1296                         callingUid, parentWindow);
   1297                 if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) {
   1298                     Slog.w(TAG_WM, "Attempted to add a toast window with bad token "
   1299                             + attrs.token + ".  Aborting.");
   1300                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1301                 }
   1302             } else if (type == TYPE_QS_DIALOG) {
   1303                 if (token.windowType != TYPE_QS_DIALOG) {
   1304                     Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token "
   1305                             + attrs.token + ".  Aborting.");
   1306                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1307                 }
   1308             } else if (token.asAppWindowToken() != null) {
   1309                 Slog.w(TAG_WM, "Non-null appWindowToken for system window of rootType=" + rootType);
   1310                 // It is not valid to use an app token with other system types; we will
   1311                 // instead make a new token for it (as if null had been passed in for the token).
   1312                 attrs.token = null;
   1313                 token = new WindowToken(this, client.asBinder(), type, false, displayContent,
   1314                         session.mCanAddInternalSystemWindow);
   1315             }
   1316 
   1317             final WindowState win = new WindowState(this, session, client, token, parentWindow,
   1318                     appOp[0], seq, attrs, viewVisibility, session.mUid,
   1319                     session.mCanAddInternalSystemWindow);
   1320             if (win.mDeathRecipient == null) {
   1321                 // Client has apparently died, so there is no reason to
   1322                 // continue.
   1323                 Slog.w(TAG_WM, "Adding window client " + client.asBinder()
   1324                         + " that is dead, aborting.");
   1325                 return WindowManagerGlobal.ADD_APP_EXITING;
   1326             }
   1327 
   1328             if (win.getDisplayContent() == null) {
   1329                 Slog.w(TAG_WM, "Adding window to Display that has been removed.");
   1330                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
   1331             }
   1332 
   1333             final boolean hasStatusBarServicePermission =
   1334                     mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
   1335                             == PackageManager.PERMISSION_GRANTED;
   1336             mPolicy.adjustWindowParamsLw(win, win.mAttrs, hasStatusBarServicePermission);
   1337             win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
   1338 
   1339             res = mPolicy.prepareAddWindowLw(win, attrs);
   1340             if (res != WindowManagerGlobal.ADD_OKAY) {
   1341                 return res;
   1342             }
   1343 
   1344             final boolean openInputChannels = (outInputChannel != null
   1345                     && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
   1346             if  (openInputChannels) {
   1347                 win.openInputChannel(outInputChannel);
   1348             }
   1349 
   1350             // If adding a toast requires a token for this app we always schedule hiding
   1351             // toast windows to make sure they don't stick around longer then necessary.
   1352             // We hide instead of remove such windows as apps aren't prepared to handle
   1353             // windows being removed under them.
   1354             //
   1355             // If the app is older it can add toasts without a token and hence overlay
   1356             // other apps. To be maximally compatible with these apps we will hide the
   1357             // window after the toast timeout only if the focused window is from another
   1358             // UID, otherwise we allow unlimited duration. When a UID looses focus we
   1359             // schedule hiding all of its toast windows.
   1360             if (type == TYPE_TOAST) {
   1361                 if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) {
   1362                     Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
   1363                     return WindowManagerGlobal.ADD_DUPLICATE_ADD;
   1364                 }
   1365                 // Make sure this happens before we moved focus as one can make the
   1366                 // toast focusable to force it not being hidden after the timeout.
   1367                 // Focusable toasts are always timed out to prevent a focused app to
   1368                 // show a focusable toasts while it has focus which will be kept on
   1369                 // the screen after the activity goes away.
   1370                 if (addToastWindowRequiresToken
   1371                         || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0
   1372                         || mCurrentFocus == null
   1373                         || mCurrentFocus.mOwnerUid != callingUid) {
   1374                     mH.sendMessageDelayed(
   1375                             mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win),
   1376                             win.mAttrs.hideTimeoutMilliseconds);
   1377                 }
   1378             }
   1379 
   1380             // From now on, no exceptions or errors allowed!
   1381 
   1382             res = WindowManagerGlobal.ADD_OKAY;
   1383             if (mCurrentFocus == null) {
   1384                 mWinAddedSinceNullFocus.add(win);
   1385             }
   1386 
   1387             if (excludeWindowTypeFromTapOutTask(type)) {
   1388                 displayContent.mTapExcludedWindows.add(win);
   1389             }
   1390 
   1391             origId = Binder.clearCallingIdentity();
   1392 
   1393             win.attach();
   1394             mWindowMap.put(client.asBinder(), win);
   1395 
   1396             win.initAppOpsState();
   1397 
   1398             final boolean suspended = mPmInternal.isPackageSuspended(win.getOwningPackage(),
   1399                     UserHandle.getUserId(win.getOwningUid()));
   1400             win.setHiddenWhileSuspended(suspended);
   1401 
   1402             final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
   1403             win.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
   1404 
   1405             final AppWindowToken aToken = token.asAppWindowToken();
   1406             if (type == TYPE_APPLICATION_STARTING && aToken != null) {
   1407                 aToken.startingWindow = win;
   1408                 if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + aToken
   1409                         + " startingWindow=" + win);
   1410             }
   1411 
   1412             boolean imMayMove = true;
   1413 
   1414             win.mToken.addWindow(win);
   1415             if (type == TYPE_INPUT_METHOD) {
   1416                 win.mGivenInsetsPending = true;
   1417                 setInputMethodWindowLocked(win);
   1418                 imMayMove = false;
   1419             } else if (type == TYPE_INPUT_METHOD_DIALOG) {
   1420                 displayContent.computeImeTarget(true /* updateImeTarget */);
   1421                 imMayMove = false;
   1422             } else {
   1423                 if (type == TYPE_WALLPAPER) {
   1424                     displayContent.mWallpaperController.clearLastWallpaperTimeoutTime();
   1425                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   1426                 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
   1427                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   1428                 } else if (displayContent.mWallpaperController.isBelowWallpaperTarget(win)) {
   1429                     // If there is currently a wallpaper being shown, and
   1430                     // the base layer of the new window is below the current
   1431                     // layer of the target window, then adjust the wallpaper.
   1432                     // This is to avoid a new window being placed between the
   1433                     // wallpaper and its target.
   1434                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   1435                 }
   1436             }
   1437 
   1438             // If the window is being added to a stack that's currently adjusted for IME,
   1439             // make sure to apply the same adjust to this new window.
   1440             win.applyAdjustForImeIfNeeded();
   1441 
   1442             if (type == TYPE_DOCK_DIVIDER) {
   1443                 mRoot.getDisplayContent(displayId).getDockedDividerController().setWindow(win);
   1444             }
   1445 
   1446             final WindowStateAnimator winAnimator = win.mWinAnimator;
   1447             winAnimator.mEnterAnimationPending = true;
   1448             winAnimator.mEnteringAnimation = true;
   1449             // Check if we need to prepare a transition for replacing window first.
   1450             if (atoken != null && atoken.isVisible()
   1451                     && !prepareWindowReplacementTransition(atoken)) {
   1452                 // If not, check if need to set up a dummy transition during display freeze
   1453                 // so that the unfreeze wait for the apps to draw. This might be needed if
   1454                 // the app is relaunching.
   1455                 prepareNoneTransitionForRelaunching(atoken);
   1456             }
   1457 
   1458             final DisplayFrames displayFrames = displayContent.mDisplayFrames;
   1459             // TODO: Not sure if onDisplayInfoUpdated() call is needed.
   1460             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
   1461             displayFrames.onDisplayInfoUpdated(displayInfo,
   1462                     displayContent.calculateDisplayCutoutForRotation(displayInfo.rotation));
   1463             final Rect taskBounds;
   1464             if (atoken != null && atoken.getTask() != null) {
   1465                 taskBounds = mTmpRect;
   1466                 atoken.getTask().getBounds(mTmpRect);
   1467             } else {
   1468                 taskBounds = null;
   1469             }
   1470             if (mPolicy.getLayoutHintLw(win.mAttrs, taskBounds, displayFrames, outFrame,
   1471                     outContentInsets, outStableInsets, outOutsets, outDisplayCutout)) {
   1472                 res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR;
   1473             }
   1474 
   1475             if (mInTouchMode) {
   1476                 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
   1477             }
   1478             if (win.mAppToken == null || !win.mAppToken.isClientHidden()) {
   1479                 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
   1480             }
   1481 
   1482             mInputMonitor.setUpdateInputWindowsNeededLw();
   1483 
   1484             boolean focusChanged = false;
   1485             if (win.canReceiveKeys()) {
   1486                 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
   1487                         false /*updateInputWindows*/);
   1488                 if (focusChanged) {
   1489                     imMayMove = false;
   1490                 }
   1491             }
   1492 
   1493             if (imMayMove) {
   1494                 displayContent.computeImeTarget(true /* updateImeTarget */);
   1495             }
   1496 
   1497             // Don't do layout here, the window must call
   1498             // relayout to be displayed, so we'll do it there.
   1499             win.getParent().assignChildLayers();
   1500 
   1501             if (focusChanged) {
   1502                 mInputMonitor.setInputFocusLw(mCurrentFocus, false /*updateInputWindows*/);
   1503             }
   1504             mInputMonitor.updateInputWindowsLw(false /*force*/);
   1505 
   1506             if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client "
   1507                     + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
   1508 
   1509             if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(displayId)) {
   1510                 reportNewConfig = true;
   1511             }
   1512         }
   1513 
   1514         if (reportNewConfig) {
   1515             sendNewConfiguration(displayId);
   1516         }
   1517 
   1518         Binder.restoreCallingIdentity(origId);
   1519 
   1520         return res;
   1521     }
   1522 
   1523     /**
   1524      * Get existing {@link DisplayContent} or create a new one if the display is registered in
   1525      * DisplayManager.
   1526      *
   1527      * NOTE: This should only be used in cases when there is a chance that a {@link DisplayContent}
   1528      * that corresponds to a display just added to DisplayManager has not yet been created. This
   1529      * usually means that the call of this method was initiated from outside of Activity or Window
   1530      * Manager. In most cases the regular getter should be used.
   1531      * @see RootWindowContainer#getDisplayContent(int)
   1532      */
   1533     private DisplayContent getDisplayContentOrCreate(int displayId) {
   1534         DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   1535 
   1536         // Create an instance if possible instead of waiting for the ActivityManagerService to drive
   1537         // the creation.
   1538         if (displayContent == null) {
   1539             final Display display = mDisplayManager.getDisplay(displayId);
   1540 
   1541             if (display != null) {
   1542                 displayContent = mRoot.createDisplayContent(display, null /* controller */);
   1543             }
   1544         }
   1545 
   1546         return displayContent;
   1547     }
   1548 
   1549     private boolean doesAddToastWindowRequireToken(String packageName, int callingUid,
   1550             WindowState attachedWindow) {
   1551         // Try using the target SDK of the root window
   1552         if (attachedWindow != null) {
   1553             return attachedWindow.mAppToken != null
   1554                     && attachedWindow.mAppToken.mTargetSdk >= Build.VERSION_CODES.O;
   1555         } else {
   1556             // Otherwise, look at the package
   1557             try {
   1558                 ApplicationInfo appInfo = mContext.getPackageManager()
   1559                         .getApplicationInfoAsUser(packageName, 0,
   1560                                 UserHandle.getUserId(callingUid));
   1561                 if (appInfo.uid != callingUid) {
   1562                     throw new SecurityException("Package " + packageName + " not in UID "
   1563                             + callingUid);
   1564                 }
   1565                 if (appInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
   1566                     return true;
   1567                 }
   1568             } catch (PackageManager.NameNotFoundException e) {
   1569                 /* ignore */
   1570             }
   1571         }
   1572         return false;
   1573     }
   1574 
   1575     /**
   1576      * Returns true if we're done setting up any transitions.
   1577      */
   1578     private boolean prepareWindowReplacementTransition(AppWindowToken atoken) {
   1579         atoken.clearAllDrawn();
   1580         final WindowState replacedWindow = atoken.getReplacingWindow();
   1581         if (replacedWindow == null) {
   1582             // We expect to already receive a request to remove the old window. If it did not
   1583             // happen, let's just simply add a window.
   1584             return false;
   1585         }
   1586         // We use the visible frame, because we want the animation to morph the window from what
   1587         // was visible to the user to the final destination of the new window.
   1588         Rect frame = replacedWindow.mVisibleFrame;
   1589         // We treat this as if this activity was opening, so we can trigger the app transition
   1590         // animation and piggy-back on existing transition animation infrastructure.
   1591         mOpeningApps.add(atoken);
   1592         prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_RELAUNCH, ALWAYS_KEEP_CURRENT);
   1593         mAppTransition.overridePendingAppTransitionClipReveal(frame.left, frame.top,
   1594                 frame.width(), frame.height());
   1595         executeAppTransition();
   1596         return true;
   1597     }
   1598 
   1599     private void prepareNoneTransitionForRelaunching(AppWindowToken atoken) {
   1600         // Set up a none-transition and add the app to opening apps, so that the display
   1601         // unfreeze wait for the apps to be drawn.
   1602         // Note that if the display unfroze already because app unfreeze timed out,
   1603         // we don't set up the transition anymore and just let it go.
   1604         if (mDisplayFrozen && !mOpeningApps.contains(atoken) && atoken.isRelaunching()) {
   1605             mOpeningApps.add(atoken);
   1606             prepareAppTransition(WindowManager.TRANSIT_NONE, !ALWAYS_KEEP_CURRENT);
   1607             executeAppTransition();
   1608         }
   1609     }
   1610 
   1611     boolean isSecureLocked(WindowState w) {
   1612         if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
   1613             return true;
   1614         }
   1615         if (DevicePolicyCache.getInstance().getScreenCaptureDisabled(
   1616                 UserHandle.getUserId(w.mOwnerUid))) {
   1617             return true;
   1618         }
   1619         return false;
   1620     }
   1621 
   1622     /**
   1623      * Set whether screen capture is disabled for all windows of a specific user from
   1624      * the device policy cache.
   1625      */
   1626     @Override
   1627     public void refreshScreenCaptureDisabled(int userId) {
   1628         int callingUid = Binder.getCallingUid();
   1629         if (callingUid != SYSTEM_UID) {
   1630             throw new SecurityException("Only system can call refreshScreenCaptureDisabled.");
   1631         }
   1632 
   1633         synchronized(mWindowMap) {
   1634             // Update secure surface for all windows belonging to this user.
   1635             mRoot.setSecureSurfaceState(userId,
   1636                     DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId));
   1637         }
   1638     }
   1639 
   1640     void removeWindow(Session session, IWindow client) {
   1641         synchronized(mWindowMap) {
   1642             WindowState win = windowForClientLocked(session, client, false);
   1643             if (win == null) {
   1644                 return;
   1645             }
   1646             win.removeIfPossible();
   1647         }
   1648     }
   1649 
   1650     /**
   1651      * Performs some centralized bookkeeping clean-up on the window that is being removed.
   1652      * NOTE: Should only be called from {@link WindowState#removeImmediately()}
   1653      * TODO: Maybe better handled with a method {@link WindowContainer#removeChild} if we can
   1654      * figure-out a good way to have all parents of a WindowState doing the same thing without
   1655      * forgetting to add the wiring when a new parent of WindowState is added.
   1656      */
   1657     void postWindowRemoveCleanupLocked(WindowState win) {
   1658         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "postWindowRemoveCleanupLocked: " + win);
   1659         mWindowMap.remove(win.mClient.asBinder());
   1660 
   1661         markForSeamlessRotation(win, false);
   1662 
   1663         win.resetAppOpsState();
   1664 
   1665         if (mCurrentFocus == null) {
   1666             mWinRemovedSinceNullFocus.add(win);
   1667         }
   1668         mPendingRemove.remove(win);
   1669         mResizingWindows.remove(win);
   1670         updateNonSystemOverlayWindowsVisibilityIfNeeded(win, false /* surfaceShown */);
   1671         mWindowsChanged = true;
   1672         if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win);
   1673 
   1674         if (mInputMethodWindow == win) {
   1675             setInputMethodWindowLocked(null);
   1676         }
   1677 
   1678         final WindowToken token = win.mToken;
   1679         final AppWindowToken atoken = win.mAppToken;
   1680         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token);
   1681         // Window will already be removed from token before this post clean-up method is called.
   1682         if (token.isEmpty()) {
   1683             if (!token.mPersistOnEmpty) {
   1684                 token.removeImmediately();
   1685             } else if (atoken != null) {
   1686                 // TODO: Should this be moved into AppWindowToken.removeWindow? Might go away after
   1687                 // re-factor.
   1688                 atoken.firstWindowDrawn = false;
   1689                 atoken.clearAllDrawn();
   1690                 final TaskStack stack = atoken.getStack();
   1691                 if (stack != null) {
   1692                     stack.mExitingAppTokens.remove(atoken);
   1693                 }
   1694             }
   1695         }
   1696 
   1697         if (atoken != null) {
   1698             atoken.postWindowRemoveStartingWindowCleanup(win);
   1699         }
   1700 
   1701         final DisplayContent dc = win.getDisplayContent();
   1702         if (win.mAttrs.type == TYPE_WALLPAPER) {
   1703             dc.mWallpaperController.clearLastWallpaperTimeoutTime();
   1704             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   1705         } else if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
   1706             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   1707         }
   1708 
   1709         if (dc != null && !mWindowPlacerLocked.isInLayout()) {
   1710             dc.assignWindowLayers(true /* setLayoutNeeded */);
   1711             mWindowPlacerLocked.performSurfacePlacement();
   1712             if (win.mAppToken != null) {
   1713                 win.mAppToken.updateReportedVisibilityLocked();
   1714             }
   1715         }
   1716 
   1717         mInputMonitor.updateInputWindowsLw(true /*force*/);
   1718     }
   1719 
   1720     void setInputMethodWindowLocked(WindowState win) {
   1721         mInputMethodWindow = win;
   1722         final DisplayContent dc = win != null
   1723                 ? win.getDisplayContent() : getDefaultDisplayContentLocked();
   1724         dc.computeImeTarget(true /* updateImeTarget */);
   1725     }
   1726 
   1727     private void updateHiddenWhileSuspendedState(ArraySet<String> packages, boolean suspended) {
   1728         synchronized (mWindowMap) {
   1729             mRoot.updateHiddenWhileSuspendedState(packages, suspended);
   1730         }
   1731     }
   1732 
   1733     private void updateAppOpsState() {
   1734         synchronized(mWindowMap) {
   1735             mRoot.updateAppOpsState();
   1736         }
   1737     }
   1738 
   1739     static void logSurface(WindowState w, String msg, boolean withStackTrace) {
   1740         String str = "  SURFACE " + msg + ": " + w;
   1741         if (withStackTrace) {
   1742             logWithStack(TAG, str);
   1743         } else {
   1744             Slog.i(TAG_WM, str);
   1745         }
   1746     }
   1747 
   1748     static void logSurface(SurfaceControl s, String title, String msg) {
   1749         String str = "  SURFACE " + s + ": " + msg + " / " + title;
   1750         Slog.i(TAG_WM, str);
   1751     }
   1752 
   1753     static void logWithStack(String tag, String s) {
   1754         RuntimeException e = null;
   1755         if (SHOW_STACK_CRAWLS) {
   1756             e = new RuntimeException();
   1757             e.fillInStackTrace();
   1758         }
   1759         Slog.i(tag, s, e);
   1760     }
   1761 
   1762     void setTransparentRegionWindow(Session session, IWindow client, Region region) {
   1763         long origId = Binder.clearCallingIdentity();
   1764         try {
   1765             synchronized (mWindowMap) {
   1766                 WindowState w = windowForClientLocked(session, client, false);
   1767                 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   1768                         "transparentRegionHint=" + region, false);
   1769 
   1770                 if ((w != null) && w.mHasSurface) {
   1771                     w.mWinAnimator.setTransparentRegionHintLocked(region);
   1772                 }
   1773             }
   1774         } finally {
   1775             Binder.restoreCallingIdentity(origId);
   1776         }
   1777     }
   1778 
   1779     void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets,
   1780             Rect visibleInsets, Region touchableRegion) {
   1781         long origId = Binder.clearCallingIdentity();
   1782         try {
   1783             synchronized (mWindowMap) {
   1784                 WindowState w = windowForClientLocked(session, client, false);
   1785                 if (DEBUG_LAYOUT) Slog.d(TAG, "setInsetsWindow " + w
   1786                         + ", contentInsets=" + w.mGivenContentInsets + " -> " + contentInsets
   1787                         + ", visibleInsets=" + w.mGivenVisibleInsets + " -> " + visibleInsets
   1788                         + ", touchableRegion=" + w.mGivenTouchableRegion + " -> " + touchableRegion
   1789                         + ", touchableInsets " + w.mTouchableInsets + " -> " + touchableInsets);
   1790                 if (w != null) {
   1791                     w.mGivenInsetsPending = false;
   1792                     w.mGivenContentInsets.set(contentInsets);
   1793                     w.mGivenVisibleInsets.set(visibleInsets);
   1794                     w.mGivenTouchableRegion.set(touchableRegion);
   1795                     w.mTouchableInsets = touchableInsets;
   1796                     if (w.mGlobalScale != 1) {
   1797                         w.mGivenContentInsets.scale(w.mGlobalScale);
   1798                         w.mGivenVisibleInsets.scale(w.mGlobalScale);
   1799                         w.mGivenTouchableRegion.scale(w.mGlobalScale);
   1800                     }
   1801                     w.setDisplayLayoutNeeded();
   1802                     mWindowPlacerLocked.performSurfacePlacement();
   1803 
   1804                     // We need to report touchable region changes to accessibility.
   1805                     if (mAccessibilityController != null
   1806                             && w.getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
   1807                         mAccessibilityController.onSomeWindowResizedOrMovedLocked();
   1808                     }
   1809                 }
   1810             }
   1811         } finally {
   1812             Binder.restoreCallingIdentity(origId);
   1813         }
   1814     }
   1815 
   1816     public void getWindowDisplayFrame(Session session, IWindow client,
   1817             Rect outDisplayFrame) {
   1818         synchronized(mWindowMap) {
   1819             WindowState win = windowForClientLocked(session, client, false);
   1820             if (win == null) {
   1821                 outDisplayFrame.setEmpty();
   1822                 return;
   1823             }
   1824             outDisplayFrame.set(win.mDisplayFrame);
   1825         }
   1826     }
   1827 
   1828     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
   1829         synchronized (mWindowMap) {
   1830             if (mAccessibilityController != null) {
   1831                 WindowState window = mWindowMap.get(token);
   1832                 //TODO (multidisplay): Magnification is supported only for the default display.
   1833                 if (window != null && window.getDisplayId() == DEFAULT_DISPLAY) {
   1834                     mAccessibilityController.onRectangleOnScreenRequestedLocked(rectangle);
   1835                 }
   1836             }
   1837         }
   1838     }
   1839 
   1840     public IWindowId getWindowId(IBinder token) {
   1841         synchronized (mWindowMap) {
   1842             WindowState window = mWindowMap.get(token);
   1843             return window != null ? window.mWindowId : null;
   1844         }
   1845     }
   1846 
   1847     public void pokeDrawLock(Session session, IBinder token) {
   1848         synchronized (mWindowMap) {
   1849             WindowState window = windowForClientLocked(session, token, false);
   1850             if (window != null) {
   1851                 window.pokeDrawLockLw(mDrawLockTimeoutMillis);
   1852             }
   1853         }
   1854     }
   1855 
   1856     public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
   1857             int requestedWidth, int requestedHeight, int viewVisibility, int flags,
   1858             long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
   1859             Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
   1860             DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration,
   1861             Surface outSurface) {
   1862         int result = 0;
   1863         boolean configChanged;
   1864         final boolean hasStatusBarPermission =
   1865                 mContext.checkCallingOrSelfPermission(permission.STATUS_BAR)
   1866                         == PackageManager.PERMISSION_GRANTED;
   1867         final boolean hasStatusBarServicePermission =
   1868                 mContext.checkCallingOrSelfPermission(permission.STATUS_BAR_SERVICE)
   1869                         == PackageManager.PERMISSION_GRANTED;
   1870 
   1871         long origId = Binder.clearCallingIdentity();
   1872         final int displayId;
   1873         synchronized(mWindowMap) {
   1874             WindowState win = windowForClientLocked(session, client, false);
   1875             if (win == null) {
   1876                 return 0;
   1877             }
   1878             displayId = win.getDisplayId();
   1879 
   1880             WindowStateAnimator winAnimator = win.mWinAnimator;
   1881             if (viewVisibility != View.GONE) {
   1882                 win.setRequestedSize(requestedWidth, requestedHeight);
   1883             }
   1884 
   1885             win.setFrameNumber(frameNumber);
   1886             int attrChanges = 0;
   1887             int flagChanges = 0;
   1888             if (attrs != null) {
   1889                 mPolicy.adjustWindowParamsLw(win, attrs, hasStatusBarServicePermission);
   1890                 // if they don't have the permission, mask out the status bar bits
   1891                 if (seq == win.mSeq) {
   1892                     int systemUiVisibility = attrs.systemUiVisibility
   1893                             | attrs.subtreeSystemUiVisibility;
   1894                     if ((systemUiVisibility & DISABLE_MASK) != 0) {
   1895                         if (!hasStatusBarPermission) {
   1896                             systemUiVisibility &= ~DISABLE_MASK;
   1897                         }
   1898                     }
   1899                     win.mSystemUiVisibility = systemUiVisibility;
   1900                 }
   1901                 if (win.mAttrs.type != attrs.type) {
   1902                     throw new IllegalArgumentException(
   1903                             "Window type can not be changed after the window is added.");
   1904                 }
   1905 
   1906                 // Odd choice but less odd than embedding in copyFrom()
   1907                 if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY)
   1908                         != 0) {
   1909                     attrs.x = win.mAttrs.x;
   1910                     attrs.y = win.mAttrs.y;
   1911                     attrs.width = win.mAttrs.width;
   1912                     attrs.height = win.mAttrs.height;
   1913                 }
   1914 
   1915                 flagChanges = win.mAttrs.flags ^= attrs.flags;
   1916                 attrChanges = win.mAttrs.copyFrom(attrs);
   1917                 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
   1918                         | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
   1919                     win.mLayoutNeeded = true;
   1920                 }
   1921                 if (win.mAppToken != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0
   1922                         || (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {
   1923                     win.mAppToken.checkKeyguardFlagsChanged();
   1924                 }
   1925                 if (((attrChanges & LayoutParams.ACCESSIBILITY_TITLE_CHANGED) != 0)
   1926                         && (mAccessibilityController != null)
   1927                         && (win.getDisplayId() == DEFAULT_DISPLAY)) {
   1928                     // No move or resize, but the controller checks for title changes as well
   1929                     mAccessibilityController.onSomeWindowResizedOrMovedLocked();
   1930                 }
   1931 
   1932                 if ((flagChanges & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
   1933                     updateNonSystemOverlayWindowsVisibilityIfNeeded(
   1934                             win, win.mWinAnimator.getShown());
   1935                 }
   1936             }
   1937 
   1938             if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
   1939                     + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
   1940             winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
   1941             win.mEnforceSizeCompat =
   1942                     (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
   1943             if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
   1944                 winAnimator.mAlpha = attrs.alpha;
   1945             }
   1946             win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
   1947 
   1948             if (win.mAttrs.surfaceInsets.left != 0
   1949                     || win.mAttrs.surfaceInsets.top != 0
   1950                     || win.mAttrs.surfaceInsets.right != 0
   1951                     || win.mAttrs.surfaceInsets.bottom != 0) {
   1952                 winAnimator.setOpaqueLocked(false);
   1953             }
   1954 
   1955             final int oldVisibility = win.mViewVisibility;
   1956 
   1957             // If the window is becoming visible, visibleOrAdding may change which may in turn
   1958             // change the IME target.
   1959             final boolean becameVisible =
   1960                     (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)
   1961                             && viewVisibility == View.VISIBLE;
   1962             boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
   1963                     || becameVisible;
   1964             final boolean isDefaultDisplay = win.isDefaultDisplay();
   1965             boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
   1966                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
   1967                     || (!win.mRelayoutCalled));
   1968 
   1969             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
   1970                     && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
   1971             wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
   1972             if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
   1973                 winAnimator.mSurfaceController.setSecure(isSecureLocked(win));
   1974             }
   1975 
   1976             win.mRelayoutCalled = true;
   1977             win.mInRelayout = true;
   1978 
   1979             win.mViewVisibility = viewVisibility;
   1980             if (DEBUG_SCREEN_ON) {
   1981                 RuntimeException stack = new RuntimeException();
   1982                 stack.fillInStackTrace();
   1983                 Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility
   1984                         + " newVis=" + viewVisibility, stack);
   1985             }
   1986 
   1987             win.setDisplayLayoutNeeded();
   1988             win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
   1989 
   1990             // We should only relayout if the view is visible, it is a starting window, or the
   1991             // associated appToken is not hidden.
   1992             final boolean shouldRelayout = viewVisibility == View.VISIBLE &&
   1993                     (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING
   1994                             || !win.mAppToken.isClientHidden());
   1995 
   1996             // If we are not currently running the exit animation, we need to see about starting
   1997             // one.
   1998             // We don't want to animate visibility of windows which are pending replacement.
   1999             // In the case of activity relaunch child windows could request visibility changes as
   2000             // they are detached from the main application window during the tear down process.
   2001             // If we satisfied these visibility changes though, we would cause a visual glitch
   2002             // hiding the window before it's replacement was available. So we just do nothing on
   2003             // our side.
   2004             // This must be called before the call to performSurfacePlacement.
   2005             if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
   2006                 if (DEBUG_VISIBILITY) {
   2007                     Slog.i(TAG_WM,
   2008                             "Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
   2009                 }
   2010                 result |= RELAYOUT_RES_SURFACE_CHANGED;
   2011                 if (!win.mWillReplaceWindow) {
   2012                     focusMayChange = tryStartExitingAnimation(win, winAnimator, isDefaultDisplay,
   2013                             focusMayChange);
   2014                 }
   2015             }
   2016 
   2017             // We may be deferring layout passes at the moment, but since the client is interested
   2018             // in the new out values right now we need to force a layout.
   2019             mWindowPlacerLocked.performSurfacePlacement(true /* force */);
   2020 
   2021             if (shouldRelayout) {
   2022                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_1");
   2023 
   2024                 result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
   2025 
   2026                 try {
   2027                     result = createSurfaceControl(outSurface, result, win, winAnimator);
   2028                 } catch (Exception e) {
   2029                     mInputMonitor.updateInputWindowsLw(true /*force*/);
   2030 
   2031                     Slog.w(TAG_WM, "Exception thrown when creating surface for client "
   2032                              + client + " (" + win.mAttrs.getTitle() + ")",
   2033                              e);
   2034                     Binder.restoreCallingIdentity(origId);
   2035                     return 0;
   2036                 }
   2037                 if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
   2038                     focusMayChange = isDefaultDisplay;
   2039                 }
   2040                 if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) {
   2041                     setInputMethodWindowLocked(win);
   2042                     imMayMove = true;
   2043                 }
   2044                 win.adjustStartingWindowFlags();
   2045                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2046             } else {
   2047                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: viewVisibility_2");
   2048 
   2049                 winAnimator.mEnterAnimationPending = false;
   2050                 winAnimator.mEnteringAnimation = false;
   2051 
   2052                 if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
   2053                     // We already told the client to go invisible, but the message may not be
   2054                     // handled yet, or it might want to draw a last frame. If we already have a
   2055                     // surface, let the client use that, but don't create new surface at this point.
   2056                     Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: getSurface");
   2057                     winAnimator.mSurfaceController.getSurface(outSurface);
   2058                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2059                 } else {
   2060                     if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
   2061 
   2062                     try {
   2063                         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
   2064                                 + win.mAttrs.getTitle());
   2065                         outSurface.release();
   2066                     } finally {
   2067                         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2068                     }
   2069                 }
   2070 
   2071                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2072             }
   2073 
   2074             if (focusMayChange) {
   2075                 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
   2076                 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
   2077                         false /*updateInputWindows*/)) {
   2078                     imMayMove = false;
   2079                 }
   2080                 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
   2081             }
   2082 
   2083             // updateFocusedWindowLocked() already assigned layers so we only need to
   2084             // reassign them at this point if the IM window state gets shuffled
   2085             boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
   2086             final DisplayContent dc = win.getDisplayContent();
   2087             if (imMayMove) {
   2088                 dc.computeImeTarget(true /* updateImeTarget */);
   2089                 if (toBeDisplayed) {
   2090                     // Little hack here -- we -should- be able to rely on the function to return
   2091                     // true if the IME has moved and needs its layer recomputed. However, if the IME
   2092                     // was hidden and isn't actually moved in the list, its layer may be out of data
   2093                     // so we make sure to recompute it.
   2094                     dc.assignWindowLayers(false /* setLayoutNeeded */);
   2095                 }
   2096             }
   2097 
   2098             if (wallpaperMayMove) {
   2099                 win.getDisplayContent().pendingLayoutChanges |=
   2100                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
   2101             }
   2102 
   2103             if (win.mAppToken != null) {
   2104                 mUnknownAppVisibilityController.notifyRelayouted(win.mAppToken);
   2105             }
   2106 
   2107             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
   2108                     "relayoutWindow: updateOrientationFromAppTokens");
   2109             configChanged = updateOrientationFromAppTokensLocked(displayId);
   2110             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2111 
   2112             if (toBeDisplayed && win.mIsWallpaper) {
   2113                 DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo();
   2114                 dc.mWallpaperController.updateWallpaperOffset(
   2115                         win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
   2116             }
   2117             if (win.mAppToken != null) {
   2118                 win.mAppToken.updateReportedVisibilityLocked();
   2119             }
   2120             if (winAnimator.mReportSurfaceResized) {
   2121                 winAnimator.mReportSurfaceResized = false;
   2122                 result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED;
   2123             }
   2124             if (mPolicy.isNavBarForcedShownLw(win)) {
   2125                 result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR;
   2126             }
   2127             if (!win.isGoneForLayoutLw()) {
   2128                 win.mResizedWhileGone = false;
   2129             }
   2130 
   2131             // We must always send the latest {@link MergedConfiguration}, regardless of whether we
   2132             // have already reported it. The client might not have processed the previous value yet
   2133             // and needs process it before handling the corresponding window frame. the variable
   2134             // {@code mergedConfiguration} is an out parameter that will be passed back to the
   2135             // client over IPC and checked there.
   2136             // Note: in the cases where the window is tied to an activity, we should not send a
   2137             // configuration update when the window has requested to be hidden. Doing so can lead
   2138             // to the client erroneously accepting a configuration that would have otherwise caused
   2139             // an activity restart. We instead hand back the last reported
   2140             // {@link MergedConfiguration}.
   2141             if (shouldRelayout) {
   2142                 win.getMergedConfiguration(mergedConfiguration);
   2143             } else {
   2144                 win.getLastReportedMergedConfiguration(mergedConfiguration);
   2145             }
   2146 
   2147             win.setLastReportedMergedConfiguration(mergedConfiguration);
   2148 
   2149             // Update the last inset values here because the values are sent back to the client.
   2150             // The last inset values represent the last client state.
   2151             win.updateLastInsetValues();
   2152 
   2153             outFrame.set(win.mCompatFrame);
   2154             outOverscanInsets.set(win.mOverscanInsets);
   2155             outContentInsets.set(win.mContentInsets);
   2156             win.mLastRelayoutContentInsets.set(win.mContentInsets);
   2157             outVisibleInsets.set(win.mVisibleInsets);
   2158             outStableInsets.set(win.mStableInsets);
   2159             outCutout.set(win.mDisplayCutout.getDisplayCutout());
   2160             outOutsets.set(win.mOutsets);
   2161             outBackdropFrame.set(win.getBackdropFrame(win.mFrame));
   2162             if (localLOGV) Slog.v(
   2163                 TAG_WM, "Relayout given client " + client.asBinder()
   2164                 + ", requestedWidth=" + requestedWidth
   2165                 + ", requestedHeight=" + requestedHeight
   2166                 + ", viewVisibility=" + viewVisibility
   2167                 + "\nRelayout returning frame=" + outFrame
   2168                 + ", surface=" + outSurface);
   2169 
   2170             if (localLOGV || DEBUG_FOCUS) Slog.v(
   2171                 TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
   2172 
   2173             result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
   2174 
   2175             mInputMonitor.updateInputWindowsLw(true /*force*/);
   2176 
   2177             if (DEBUG_LAYOUT) {
   2178                 Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
   2179             }
   2180             win.mInRelayout = false;
   2181         }
   2182 
   2183         if (configChanged) {
   2184             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "relayoutWindow: sendNewConfiguration");
   2185             sendNewConfiguration(displayId);
   2186             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2187         }
   2188         Binder.restoreCallingIdentity(origId);
   2189         return result;
   2190     }
   2191 
   2192     private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator,
   2193             boolean isDefaultDisplay, boolean focusMayChange) {
   2194         // Try starting an animation; if there isn't one, we
   2195         // can destroy the surface right away.
   2196         int transit = WindowManagerPolicy.TRANSIT_EXIT;
   2197         if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
   2198             transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
   2199         }
   2200         if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
   2201             focusMayChange = isDefaultDisplay;
   2202             win.mAnimatingExit = true;
   2203         } else if (win.mWinAnimator.isAnimationSet()) {
   2204             // Currently in a hide animation... turn this into
   2205             // an exit.
   2206             win.mAnimatingExit = true;
   2207         } else if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
   2208             // If the wallpaper is currently behind this
   2209             // window, we need to change both of them inside
   2210             // of a transaction to avoid artifacts.
   2211             win.mAnimatingExit = true;
   2212         } else {
   2213             if (mInputMethodWindow == win) {
   2214                 setInputMethodWindowLocked(null);
   2215             }
   2216             boolean stopped = win.mAppToken != null ? win.mAppToken.mAppStopped : true;
   2217             // We set mDestroying=true so AppWindowToken#notifyAppStopped in-to destroy surfaces
   2218             // will later actually destroy the surface if we do not do so here. Normally we leave
   2219             // this to the exit animation.
   2220             win.mDestroying = true;
   2221             win.destroySurface(false, stopped);
   2222         }
   2223         // TODO(multidisplay): Magnification is supported only for the default display.
   2224         if (mAccessibilityController != null && win.getDisplayId() == DEFAULT_DISPLAY) {
   2225             mAccessibilityController.onWindowTransitionLocked(win, transit);
   2226         }
   2227 
   2228         // When we start the exit animation we take the Surface from the client
   2229         // so it will stop perturbing it. We need to likewise takeaway the SurfaceFlinger
   2230         // side child surfaces, so they will remain preserved in their current state
   2231         // (rather than be cleaned up immediately by the app code).
   2232         SurfaceControl.openTransaction();
   2233         winAnimator.detachChildren();
   2234         SurfaceControl.closeTransaction();
   2235 
   2236         return focusMayChange;
   2237     }
   2238 
   2239     private int createSurfaceControl(Surface outSurface, int result, WindowState win,
   2240             WindowStateAnimator winAnimator) {
   2241         if (!win.mHasSurface) {
   2242             result |= RELAYOUT_RES_SURFACE_CHANGED;
   2243         }
   2244 
   2245         WindowSurfaceController surfaceController;
   2246         try {
   2247             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
   2248             surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
   2249         } finally {
   2250             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   2251         }
   2252         if (surfaceController != null) {
   2253             surfaceController.getSurface(outSurface);
   2254             if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, "  OUT SURFACE " + outSurface + ": copied");
   2255         } else {
   2256             // For some reason there isn't a surface.  Clear the
   2257             // caller's object so they see the same state.
   2258             Slog.w(TAG_WM, "Failed to create surface control for " + win);
   2259             outSurface.release();
   2260         }
   2261 
   2262         return result;
   2263     }
   2264 
   2265     public boolean outOfMemoryWindow(Session session, IWindow client) {
   2266         final long origId = Binder.clearCallingIdentity();
   2267 
   2268         try {
   2269             synchronized (mWindowMap) {
   2270                 WindowState win = windowForClientLocked(session, client, false);
   2271                 if (win == null) {
   2272                     return false;
   2273                 }
   2274                 return mRoot.reclaimSomeSurfaceMemory(win.mWinAnimator, "from-client", false);
   2275             }
   2276         } finally {
   2277             Binder.restoreCallingIdentity(origId);
   2278         }
   2279     }
   2280 
   2281     void finishDrawingWindow(Session session, IWindow client) {
   2282         final long origId = Binder.clearCallingIdentity();
   2283         try {
   2284             synchronized (mWindowMap) {
   2285                 WindowState win = windowForClientLocked(session, client, false);
   2286                 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
   2287                         + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
   2288                 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
   2289                     if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
   2290                         win.getDisplayContent().pendingLayoutChanges |=
   2291                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
   2292                     }
   2293                     win.setDisplayLayoutNeeded();
   2294                     mWindowPlacerLocked.requestTraversal();
   2295                 }
   2296             }
   2297         } finally {
   2298             Binder.restoreCallingIdentity(origId);
   2299         }
   2300     }
   2301 
   2302     boolean checkCallingPermission(String permission, String func) {
   2303         // Quick check: if the calling permission is me, it's all okay.
   2304         if (Binder.getCallingPid() == myPid()) {
   2305             return true;
   2306         }
   2307 
   2308         if (mContext.checkCallingPermission(permission)
   2309                 == PackageManager.PERMISSION_GRANTED) {
   2310             return true;
   2311         }
   2312         final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid()
   2313                 + ", uid=" + Binder.getCallingUid() + " requires " + permission;
   2314         Slog.w(TAG_WM, msg);
   2315         return false;
   2316     }
   2317 
   2318     @Override
   2319     public void addWindowToken(IBinder binder, int type, int displayId) {
   2320         if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) {
   2321             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2322         }
   2323 
   2324         synchronized(mWindowMap) {
   2325             final DisplayContent dc = mRoot.getDisplayContent(displayId);
   2326             WindowToken token = dc.getWindowToken(binder);
   2327             if (token != null) {
   2328                 Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
   2329                         + " for already created window token: " + token
   2330                         + " displayId=" + displayId);
   2331                 return;
   2332             }
   2333             if (type == TYPE_WALLPAPER) {
   2334                 new WallpaperWindowToken(this, binder, true, dc,
   2335                         true /* ownerCanManageAppTokens */);
   2336             } else {
   2337                 new WindowToken(this, binder, type, true, dc, true /* ownerCanManageAppTokens */);
   2338             }
   2339         }
   2340     }
   2341 
   2342     @Override
   2343     public void removeWindowToken(IBinder binder, int displayId) {
   2344         if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()")) {
   2345             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2346         }
   2347 
   2348         final long origId = Binder.clearCallingIdentity();
   2349         try {
   2350             synchronized (mWindowMap) {
   2351                 final DisplayContent dc = mRoot.getDisplayContent(displayId);
   2352                 if (dc == null) {
   2353                     Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder
   2354                             + " for non-exiting displayId=" + displayId);
   2355                     return;
   2356                 }
   2357 
   2358                 final WindowToken token = dc.removeWindowToken(binder);
   2359                 if (token == null) {
   2360                     Slog.w(TAG_WM,
   2361                             "removeWindowToken: Attempted to remove non-existing token: " + binder);
   2362                     return;
   2363                 }
   2364 
   2365                 mInputMonitor.updateInputWindowsLw(true /*force*/);
   2366             }
   2367         } finally {
   2368             Binder.restoreCallingIdentity(origId);
   2369         }
   2370     }
   2371 
   2372     @Override
   2373     public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
   2374             IBinder freezeThisOneIfNeeded, int displayId) {
   2375         return updateOrientationFromAppTokens(currentConfig, freezeThisOneIfNeeded, displayId,
   2376                 false /* forceUpdate */);
   2377     }
   2378 
   2379     public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
   2380             IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) {
   2381         if (!checkCallingPermission(MANAGE_APP_TOKENS, "updateOrientationFromAppTokens()")) {
   2382             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2383         }
   2384 
   2385         final Configuration config;
   2386         final long ident = Binder.clearCallingIdentity();
   2387         try {
   2388             synchronized(mWindowMap) {
   2389                 config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded,
   2390                         displayId, forceUpdate);
   2391             }
   2392         } finally {
   2393             Binder.restoreCallingIdentity(ident);
   2394         }
   2395 
   2396         return config;
   2397     }
   2398 
   2399     private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig,
   2400             IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) {
   2401         if (!mDisplayReady) {
   2402             return null;
   2403         }
   2404         Configuration config = null;
   2405 
   2406         if (updateOrientationFromAppTokensLocked(displayId, forceUpdate)) {
   2407             // If we changed the orientation but mOrientationChangeComplete is already true,
   2408             // we used seamless rotation, and we don't need to freeze the screen.
   2409             if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) {
   2410                 final AppWindowToken atoken = mRoot.getAppWindowToken(freezeThisOneIfNeeded);
   2411                 if (atoken != null) {
   2412                     atoken.startFreezingScreen();
   2413                 }
   2414             }
   2415             config = computeNewConfigurationLocked(displayId);
   2416 
   2417         } else if (currentConfig != null) {
   2418             // No obvious action we need to take, but if our current state mismatches the activity
   2419             // manager's, update it, disregarding font scale, which should remain set to the value
   2420             // of the previous configuration.
   2421             // Here we're calling Configuration#unset() instead of setToDefaults() because we need
   2422             // to keep override configs clear of non-empty values (e.g. fontSize).
   2423             mTempConfiguration.unset();
   2424             mTempConfiguration.updateFrom(currentConfig);
   2425             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   2426             displayContent.computeScreenConfiguration(mTempConfiguration);
   2427             if (currentConfig.diff(mTempConfiguration) != 0) {
   2428                 mWaitingForConfig = true;
   2429                 displayContent.setLayoutNeeded();
   2430                 int anim[] = new int[2];
   2431                 mPolicy.selectRotationAnimationLw(anim);
   2432 
   2433                 startFreezingDisplayLocked(anim[0], anim[1], displayContent);
   2434                 config = new Configuration(mTempConfiguration);
   2435             }
   2436         }
   2437 
   2438         return config;
   2439     }
   2440 
   2441     /**
   2442      * Determine the new desired orientation of the display, returning a non-null new Configuration
   2443      * if it has changed from the current orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL
   2444      * {@link #setNewDisplayOverrideConfiguration(Configuration, int)} TO TELL THE WINDOW MANAGER IT
   2445      * CAN UNFREEZE THE SCREEN.  This will typically be done for you if you call
   2446      * {@link #sendNewConfiguration(int)}.
   2447      *
   2448      * The orientation is computed from non-application windows first. If none of the
   2449      * non-application windows specify orientation, the orientation is computed from application
   2450      * tokens.
   2451      * @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int)
   2452      */
   2453     boolean updateOrientationFromAppTokensLocked(int displayId) {
   2454         return updateOrientationFromAppTokensLocked(displayId, false /* forceUpdate */);
   2455     }
   2456 
   2457     boolean updateOrientationFromAppTokensLocked(int displayId, boolean forceUpdate) {
   2458         long ident = Binder.clearCallingIdentity();
   2459         try {
   2460             final DisplayContent dc = mRoot.getDisplayContent(displayId);
   2461             final int req = dc.getOrientation();
   2462             if (req != dc.getLastOrientation() || forceUpdate) {
   2463                 dc.setLastOrientation(req);
   2464                 //send a message to Policy indicating orientation change to take
   2465                 //action like disabling/enabling sensors etc.,
   2466                 // TODO(multi-display): Implement policy for secondary displays.
   2467                 if (dc.isDefaultDisplay) {
   2468                     mPolicy.setCurrentOrientationLw(req);
   2469                 }
   2470                 return dc.updateRotationUnchecked(forceUpdate);
   2471             }
   2472             return false;
   2473         } finally {
   2474             Binder.restoreCallingIdentity(ident);
   2475         }
   2476     }
   2477 
   2478     // If this is true we have updated our desired orientation, but not yet
   2479     // changed the real orientation our applied our screen rotation animation.
   2480     // For example, because a previous screen rotation was in progress.
   2481     boolean rotationNeedsUpdateLocked() {
   2482         // TODO(multi-display): Check for updates on all displays. Need to have per-display policy
   2483         // to implement WindowManagerPolicy#rotationForOrientationLw() correctly.
   2484         final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
   2485         final int lastOrientation = defaultDisplayContent.getLastOrientation();
   2486         final int oldRotation = defaultDisplayContent.getRotation();
   2487         final boolean oldAltOrientation = defaultDisplayContent.getAltOrientation();
   2488 
   2489         final int rotation = mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
   2490                 true /* defaultDisplay */);
   2491         boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
   2492                 lastOrientation, rotation);
   2493         if (oldRotation == rotation && oldAltOrientation == altOrientation) {
   2494             return false;
   2495         }
   2496         return true;
   2497     }
   2498 
   2499     @Override
   2500     public int[] setNewDisplayOverrideConfiguration(Configuration overrideConfig, int displayId) {
   2501         if (!checkCallingPermission(MANAGE_APP_TOKENS, "setNewDisplayOverrideConfiguration()")) {
   2502             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2503         }
   2504 
   2505         synchronized(mWindowMap) {
   2506             if (mWaitingForConfig) {
   2507                 mWaitingForConfig = false;
   2508                 mLastFinishedFreezeSource = "new-config";
   2509             }
   2510 
   2511             return mRoot.setDisplayOverrideConfigurationIfNeeded(overrideConfig, displayId);
   2512         }
   2513     }
   2514 
   2515     void setFocusTaskRegionLocked(AppWindowToken previousFocus) {
   2516         final Task focusedTask = mFocusedApp != null ? mFocusedApp.getTask() : null;
   2517         final Task previousTask = previousFocus != null ? previousFocus.getTask() : null;
   2518         final DisplayContent focusedDisplayContent =
   2519                 focusedTask != null ? focusedTask.getDisplayContent() : null;
   2520         final DisplayContent previousDisplayContent =
   2521                 previousTask != null ? previousTask.getDisplayContent() : null;
   2522         if (previousDisplayContent != null && previousDisplayContent != focusedDisplayContent) {
   2523             previousDisplayContent.setTouchExcludeRegion(null);
   2524         }
   2525         if (focusedDisplayContent != null) {
   2526             focusedDisplayContent.setTouchExcludeRegion(focusedTask);
   2527         }
   2528     }
   2529 
   2530     @Override
   2531     public void setFocusedApp(IBinder token, boolean moveFocusNow) {
   2532         if (!checkCallingPermission(MANAGE_APP_TOKENS, "setFocusedApp()")) {
   2533             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2534         }
   2535 
   2536         synchronized(mWindowMap) {
   2537             final AppWindowToken newFocus;
   2538             if (token == null) {
   2539                 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Clearing focused app, was " + mFocusedApp);
   2540                 newFocus = null;
   2541             } else {
   2542                 newFocus = mRoot.getAppWindowToken(token);
   2543                 if (newFocus == null) {
   2544                     Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token);
   2545                 }
   2546                 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Set focused app to: " + newFocus
   2547                         + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
   2548             }
   2549 
   2550             final boolean changed = mFocusedApp != newFocus;
   2551             if (changed) {
   2552                 AppWindowToken prev = mFocusedApp;
   2553                 mFocusedApp = newFocus;
   2554                 mInputMonitor.setFocusedAppLw(newFocus);
   2555                 setFocusTaskRegionLocked(prev);
   2556             }
   2557 
   2558             if (moveFocusNow && changed) {
   2559                 final long origId = Binder.clearCallingIdentity();
   2560                 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
   2561                 Binder.restoreCallingIdentity(origId);
   2562             }
   2563         }
   2564     }
   2565 
   2566     @Override
   2567     public void prepareAppTransition(@TransitionType int transit, boolean alwaysKeepCurrent) {
   2568         prepareAppTransition(transit, alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
   2569     }
   2570 
   2571     /**
   2572      * @param transit What kind of transition is happening. Use one of the constants
   2573      *                AppTransition.TRANSIT_*.
   2574      * @param alwaysKeepCurrent If true and a transition is already set, new transition will NOT
   2575      *                          be set.
   2576      * @param flags Additional flags for the app transition, Use a combination of the constants
   2577      *              AppTransition.TRANSIT_FLAG_*.
   2578      * @param forceOverride Always override the transit, not matter what was set previously.
   2579      */
   2580     public void prepareAppTransition(@TransitionType int transit, boolean alwaysKeepCurrent,
   2581             @TransitionFlags int flags, boolean forceOverride) {
   2582         if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
   2583             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2584         }
   2585         synchronized(mWindowMap) {
   2586             boolean prepared = mAppTransition.prepareAppTransitionLocked(transit, alwaysKeepCurrent,
   2587                     flags, forceOverride);
   2588             // TODO (multidisplay): associate app transitions with displays
   2589             final DisplayContent dc = mRoot.getDisplayContent(DEFAULT_DISPLAY);
   2590             if (prepared && dc != null && dc.okToAnimate()) {
   2591                 mSkipAppTransitionAnimation = false;
   2592             }
   2593         }
   2594     }
   2595 
   2596     @Override
   2597     public @TransitionType int getPendingAppTransition() {
   2598         return mAppTransition.getAppTransition();
   2599     }
   2600 
   2601     @Override
   2602     public void overridePendingAppTransition(String packageName,
   2603             int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
   2604         synchronized(mWindowMap) {
   2605             mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim,
   2606                     startedCallback);
   2607         }
   2608     }
   2609 
   2610     @Override
   2611     public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
   2612             int startHeight) {
   2613         synchronized(mWindowMap) {
   2614             mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth,
   2615                     startHeight);
   2616         }
   2617     }
   2618 
   2619     @Override
   2620     public void overridePendingAppTransitionClipReveal(int startX, int startY,
   2621             int startWidth, int startHeight) {
   2622         synchronized(mWindowMap) {
   2623             mAppTransition.overridePendingAppTransitionClipReveal(startX, startY, startWidth,
   2624                     startHeight);
   2625         }
   2626     }
   2627 
   2628     @Override
   2629     public void overridePendingAppTransitionThumb(GraphicBuffer srcThumb, int startX,
   2630             int startY, IRemoteCallback startedCallback, boolean scaleUp) {
   2631         synchronized(mWindowMap) {
   2632             mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
   2633                     startedCallback, scaleUp);
   2634         }
   2635     }
   2636 
   2637     @Override
   2638     public void overridePendingAppTransitionAspectScaledThumb(GraphicBuffer srcThumb, int startX,
   2639             int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
   2640             boolean scaleUp) {
   2641         synchronized(mWindowMap) {
   2642             mAppTransition.overridePendingAppTransitionAspectScaledThumb(srcThumb, startX, startY,
   2643                     targetWidth, targetHeight, startedCallback, scaleUp);
   2644         }
   2645     }
   2646 
   2647     @Override
   2648     public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
   2649             IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback,
   2650             boolean scaleUp) {
   2651         synchronized (mWindowMap) {
   2652             mAppTransition.overridePendingAppTransitionMultiThumb(specs, onAnimationStartedCallback,
   2653                     onAnimationFinishedCallback, scaleUp);
   2654 
   2655         }
   2656     }
   2657 
   2658     public void overridePendingAppTransitionStartCrossProfileApps() {
   2659         synchronized (mWindowMap) {
   2660             mAppTransition.overridePendingAppTransitionStartCrossProfileApps();
   2661         }
   2662     }
   2663 
   2664     @Override
   2665     public void overridePendingAppTransitionInPlace(String packageName, int anim) {
   2666         synchronized(mWindowMap) {
   2667             mAppTransition.overrideInPlaceAppTransition(packageName, anim);
   2668         }
   2669     }
   2670 
   2671     @Override
   2672     public void overridePendingAppTransitionMultiThumbFuture(
   2673             IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
   2674             boolean scaleUp) {
   2675         synchronized(mWindowMap) {
   2676             mAppTransition.overridePendingAppTransitionMultiThumbFuture(specsFuture, callback,
   2677                     scaleUp);
   2678         }
   2679     }
   2680 
   2681     @Override
   2682     public void overridePendingAppTransitionRemote(RemoteAnimationAdapter remoteAnimationAdapter) {
   2683         if (!checkCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
   2684                 "overridePendingAppTransitionRemote()")) {
   2685             throw new SecurityException(
   2686                     "Requires CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS permission");
   2687         }
   2688         synchronized (mWindowMap) {
   2689             mAppTransition.overridePendingAppTransitionRemote(remoteAnimationAdapter);
   2690         }
   2691     }
   2692 
   2693     @Override
   2694     public void endProlongedAnimations() {
   2695         // TODO: Remove once clients are updated.
   2696     }
   2697 
   2698     @Override
   2699     public void executeAppTransition() {
   2700         if (!checkCallingPermission(MANAGE_APP_TOKENS, "executeAppTransition()")) {
   2701             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   2702         }
   2703 
   2704         synchronized(mWindowMap) {
   2705             if (DEBUG_APP_TRANSITIONS) Slog.w(TAG_WM, "Execute app transition: " + mAppTransition
   2706                     + " Callers=" + Debug.getCallers(5));
   2707             if (mAppTransition.isTransitionSet()) {
   2708                 mAppTransition.setReady();
   2709                 mWindowPlacerLocked.requestTraversal();
   2710             }
   2711         }
   2712     }
   2713 
   2714     public void initializeRecentsAnimation(int targetActivityType,
   2715             IRecentsAnimationRunner recentsAnimationRunner,
   2716             RecentsAnimationController.RecentsAnimationCallbacks callbacks, int displayId,
   2717             SparseBooleanArray recentTaskIds) {
   2718         synchronized (mWindowMap) {
   2719             mRecentsAnimationController = new RecentsAnimationController(this,
   2720                     recentsAnimationRunner, callbacks, displayId);
   2721             mAppTransition.updateBooster();
   2722             mRecentsAnimationController.initialize(targetActivityType, recentTaskIds);
   2723         }
   2724     }
   2725 
   2726     public RecentsAnimationController getRecentsAnimationController() {
   2727         return mRecentsAnimationController;
   2728     }
   2729 
   2730     /**
   2731      * @return Whether the next recents animation can continue to start. Called from
   2732      *         {@link RecentsAnimation#startRecentsActivity}.
   2733      */
   2734     public boolean canStartRecentsAnimation() {
   2735         synchronized (mWindowMap) {
   2736             if (mAppTransition.isTransitionSet()) {
   2737                 return false;
   2738             }
   2739             return true;
   2740         }
   2741     }
   2742 
   2743     /**
   2744      * Cancels any running recents animation. The caller should NOT hold the WM lock while calling
   2745      * this method, as it will call back into AM and may cause a deadlock. Any locking will be done
   2746      * in the animation controller itself.
   2747      */
   2748     public void cancelRecentsAnimationSynchronously(
   2749             @RecentsAnimationController.ReorderMode int reorderMode, String reason) {
   2750         if (mRecentsAnimationController != null) {
   2751             // This call will call through to cleanupAnimation() below after the animation is
   2752             // canceled
   2753             mRecentsAnimationController.cancelAnimationSynchronously(reorderMode, reason);
   2754         }
   2755     }
   2756 
   2757     public void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
   2758         synchronized (mWindowMap) {
   2759             if (mRecentsAnimationController != null) {
   2760                 mRecentsAnimationController.cleanupAnimation(reorderMode);
   2761                 mRecentsAnimationController = null;
   2762                 mAppTransition.updateBooster();
   2763             }
   2764         }
   2765     }
   2766 
   2767     public void setAppFullscreen(IBinder token, boolean toOpaque) {
   2768         synchronized (mWindowMap) {
   2769             final AppWindowToken atoken = mRoot.getAppWindowToken(token);
   2770             if (atoken != null) {
   2771                 atoken.setFillsParent(toOpaque);
   2772                 setWindowOpaqueLocked(token, toOpaque);
   2773                 mWindowPlacerLocked.requestTraversal();
   2774             }
   2775         }
   2776     }
   2777 
   2778     public void setWindowOpaque(IBinder token, boolean isOpaque) {
   2779         synchronized (mWindowMap) {
   2780             setWindowOpaqueLocked(token, isOpaque);
   2781         }
   2782     }
   2783 
   2784     private void setWindowOpaqueLocked(IBinder token, boolean isOpaque) {
   2785         final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
   2786         if (wtoken != null) {
   2787             final WindowState win = wtoken.findMainWindow();
   2788             if (win != null) {
   2789                 win.mWinAnimator.setOpaqueLocked(isOpaque);
   2790             }
   2791         }
   2792     }
   2793 
   2794     public void setDockedStackCreateState(int mode, Rect bounds) {
   2795         synchronized (mWindowMap) {
   2796             setDockedStackCreateStateLocked(mode, bounds);
   2797         }
   2798     }
   2799 
   2800     void setDockedStackCreateStateLocked(int mode, Rect bounds) {
   2801         mDockedStackCreateMode = mode;
   2802         mDockedStackCreateBounds = bounds;
   2803     }
   2804 
   2805     public void checkSplitScreenMinimizedChanged(boolean animate) {
   2806         synchronized (mWindowMap) {
   2807             final DisplayContent displayContent = getDefaultDisplayContentLocked();
   2808             displayContent.getDockedDividerController().checkMinimizeChanged(animate);
   2809         }
   2810     }
   2811 
   2812     public boolean isValidPictureInPictureAspectRatio(int displayId, float aspectRatio) {
   2813         final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   2814         return displayContent.getPinnedStackController().isValidPictureInPictureAspectRatio(
   2815                 aspectRatio);
   2816     }
   2817 
   2818     @Override
   2819     public void getStackBounds(int windowingMode, int activityType, Rect bounds) {
   2820         synchronized (mWindowMap) {
   2821             final TaskStack stack = mRoot.getStack(windowingMode, activityType);
   2822             if (stack != null) {
   2823                 stack.getBounds(bounds);
   2824                 return;
   2825             }
   2826             bounds.setEmpty();
   2827         }
   2828     }
   2829 
   2830     @Override
   2831     public void notifyShowingDreamChanged() {
   2832         notifyKeyguardFlagsChanged(null /* callback */);
   2833     }
   2834 
   2835     @Override
   2836     public WindowManagerPolicy.WindowState getInputMethodWindowLw() {
   2837         return mInputMethodWindow;
   2838     }
   2839 
   2840     @Override
   2841     public void notifyKeyguardTrustedChanged() {
   2842         mH.sendEmptyMessage(H.NOTIFY_KEYGUARD_TRUSTED_CHANGED);
   2843     }
   2844 
   2845     @Override
   2846     public void screenTurningOff(ScreenOffListener listener) {
   2847         mTaskSnapshotController.screenTurningOff(listener);
   2848     }
   2849 
   2850     @Override
   2851     public void triggerAnimationFailsafe() {
   2852         mH.sendEmptyMessage(H.ANIMATION_FAILSAFE);
   2853     }
   2854 
   2855     @Override
   2856     public void onKeyguardShowingAndNotOccludedChanged() {
   2857         mH.sendEmptyMessage(H.RECOMPUTE_FOCUS);
   2858     }
   2859 
   2860     /**
   2861      * Starts deferring layout passes. Useful when doing multiple changes but to optimize
   2862      * performance, only one layout pass should be done. This can be called multiple times, and
   2863      * layouting will be resumed once the last caller has called {@link #continueSurfaceLayout}
   2864      */
   2865     public void deferSurfaceLayout() {
   2866         synchronized (mWindowMap) {
   2867             mWindowPlacerLocked.deferLayout();
   2868         }
   2869     }
   2870 
   2871     /**
   2872      * Resumes layout passes after deferring them. See {@link #deferSurfaceLayout()}
   2873      */
   2874     public void continueSurfaceLayout() {
   2875         synchronized (mWindowMap) {
   2876             mWindowPlacerLocked.continueLayout();
   2877         }
   2878     }
   2879 
   2880     /**
   2881      * @return true if the activity contains windows that have
   2882      *         {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set
   2883      */
   2884     public boolean containsShowWhenLockedWindow(IBinder token) {
   2885         synchronized (mWindowMap) {
   2886             final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
   2887             return wtoken != null && wtoken.containsShowWhenLockedWindow();
   2888         }
   2889     }
   2890 
   2891     /**
   2892      * @return true if the activity contains windows that have
   2893      *         {@link LayoutParams#FLAG_DISMISS_KEYGUARD} set
   2894      */
   2895     public boolean containsDismissKeyguardWindow(IBinder token) {
   2896         synchronized (mWindowMap) {
   2897             final AppWindowToken wtoken = mRoot.getAppWindowToken(token);
   2898             return wtoken != null && wtoken.containsDismissKeyguardWindow();
   2899         }
   2900     }
   2901 
   2902     /**
   2903      * Notifies activity manager that some Keyguard flags have changed and that it needs to
   2904      * reevaluate the visibilities of the activities.
   2905      * @param callback Runnable to be called when activity manager is done reevaluating visibilities
   2906      */
   2907     void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
   2908         final Runnable wrappedCallback = callback != null
   2909                 ? () -> { synchronized (mWindowMap) { callback.run(); } }
   2910                 : null;
   2911         mH.obtainMessage(H.NOTIFY_KEYGUARD_FLAGS_CHANGED, wrappedCallback).sendToTarget();
   2912     }
   2913 
   2914     public boolean isKeyguardTrusted() {
   2915         synchronized (mWindowMap) {
   2916             return mPolicy.isKeyguardTrustedLw();
   2917         }
   2918     }
   2919 
   2920     public void setKeyguardGoingAway(boolean keyguardGoingAway) {
   2921         synchronized (mWindowMap) {
   2922             mKeyguardGoingAway = keyguardGoingAway;
   2923         }
   2924     }
   2925 
   2926     public void setKeyguardOrAodShowingOnDefaultDisplay(boolean showing) {
   2927         synchronized (mWindowMap) {
   2928             mKeyguardOrAodShowingOnDefaultDisplay = showing;
   2929         }
   2930     }
   2931 
   2932     // -------------------------------------------------------------
   2933     // Misc IWindowSession methods
   2934     // -------------------------------------------------------------
   2935 
   2936     @Override
   2937     public void startFreezingScreen(int exitAnim, int enterAnim) {
   2938         if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
   2939                 "startFreezingScreen()")) {
   2940             throw new SecurityException("Requires FREEZE_SCREEN permission");
   2941         }
   2942 
   2943         synchronized(mWindowMap) {
   2944             if (!mClientFreezingScreen) {
   2945                 mClientFreezingScreen = true;
   2946                 final long origId = Binder.clearCallingIdentity();
   2947                 try {
   2948                     startFreezingDisplayLocked(exitAnim, enterAnim);
   2949                     mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
   2950                     mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
   2951                 } finally {
   2952                     Binder.restoreCallingIdentity(origId);
   2953                 }
   2954             }
   2955         }
   2956     }
   2957 
   2958     @Override
   2959     public void stopFreezingScreen() {
   2960         if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
   2961                 "stopFreezingScreen()")) {
   2962             throw new SecurityException("Requires FREEZE_SCREEN permission");
   2963         }
   2964 
   2965         synchronized(mWindowMap) {
   2966             if (mClientFreezingScreen) {
   2967                 mClientFreezingScreen = false;
   2968                 mLastFinishedFreezeSource = "client";
   2969                 final long origId = Binder.clearCallingIdentity();
   2970                 try {
   2971                     stopFreezingDisplayLocked();
   2972                 } finally {
   2973                     Binder.restoreCallingIdentity(origId);
   2974                 }
   2975             }
   2976         }
   2977     }
   2978 
   2979     @Override
   2980     public void disableKeyguard(IBinder token, String tag) {
   2981         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
   2982             != PackageManager.PERMISSION_GRANTED) {
   2983             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
   2984         }
   2985         // If this isn't coming from the system then don't allow disabling the lockscreen
   2986         // to bypass security.
   2987         if (Binder.getCallingUid() != SYSTEM_UID && isKeyguardSecure()) {
   2988             Log.d(TAG_WM, "current mode is SecurityMode, ignore disableKeyguard");
   2989             return;
   2990         }
   2991 
   2992         // If this isn't coming from the current profiles, ignore it.
   2993         if (!isCurrentProfileLocked(UserHandle.getCallingUserId())) {
   2994             Log.d(TAG_WM, "non-current profiles, ignore disableKeyguard");
   2995             return;
   2996         }
   2997 
   2998         if (token == null) {
   2999             throw new IllegalArgumentException("token == null");
   3000         }
   3001 
   3002         mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
   3003                 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
   3004     }
   3005 
   3006     @Override
   3007     public void reenableKeyguard(IBinder token) {
   3008         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
   3009             != PackageManager.PERMISSION_GRANTED) {
   3010             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
   3011         }
   3012 
   3013         if (token == null) {
   3014             throw new IllegalArgumentException("token == null");
   3015         }
   3016 
   3017         mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
   3018                 KeyguardDisableHandler.KEYGUARD_REENABLE, token));
   3019     }
   3020 
   3021     /**
   3022      * @see android.app.KeyguardManager#exitKeyguardSecurely
   3023      */
   3024     @Override
   3025     public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
   3026         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
   3027             != PackageManager.PERMISSION_GRANTED) {
   3028             throw new SecurityException("Requires DISABLE_KEYGUARD permission");
   3029         }
   3030 
   3031         if (callback == null) {
   3032             throw new IllegalArgumentException("callback == null");
   3033         }
   3034 
   3035         mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
   3036             @Override
   3037             public void onKeyguardExitResult(boolean success) {
   3038                 try {
   3039                     callback.onKeyguardExitResult(success);
   3040                 } catch (RemoteException e) {
   3041                     // Client has died, we don't care.
   3042                 }
   3043             }
   3044         });
   3045     }
   3046 
   3047     @Override
   3048     public boolean isKeyguardLocked() {
   3049         return mPolicy.isKeyguardLocked();
   3050     }
   3051 
   3052     public boolean isKeyguardShowingAndNotOccluded() {
   3053         return mPolicy.isKeyguardShowingAndNotOccluded();
   3054     }
   3055 
   3056     @Override
   3057     public boolean isKeyguardSecure() {
   3058         int userId = UserHandle.getCallingUserId();
   3059         long origId = Binder.clearCallingIdentity();
   3060         try {
   3061             return mPolicy.isKeyguardSecure(userId);
   3062         } finally {
   3063             Binder.restoreCallingIdentity(origId);
   3064         }
   3065     }
   3066 
   3067     public boolean isShowingDream() {
   3068         synchronized (mWindowMap) {
   3069             return mPolicy.isShowingDreamLw();
   3070         }
   3071     }
   3072 
   3073     @Override
   3074     public void dismissKeyguard(IKeyguardDismissCallback callback, CharSequence message) {
   3075         if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
   3076             throw new SecurityException("Requires CONTROL_KEYGUARD permission");
   3077         }
   3078         synchronized(mWindowMap) {
   3079             mPolicy.dismissKeyguardLw(callback, message);
   3080         }
   3081     }
   3082 
   3083     public void onKeyguardOccludedChanged(boolean occluded) {
   3084         synchronized (mWindowMap) {
   3085             mPolicy.onKeyguardOccludedChangedLw(occluded);
   3086         }
   3087     }
   3088 
   3089     @Override
   3090     public void setSwitchingUser(boolean switching) {
   3091         if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
   3092                 "setSwitchingUser()")) {
   3093             throw new SecurityException("Requires INTERACT_ACROSS_USERS_FULL permission");
   3094         }
   3095         mPolicy.setSwitchingUser(switching);
   3096         synchronized (mWindowMap) {
   3097             mSwitchingUser = switching;
   3098         }
   3099     }
   3100 
   3101     void showGlobalActions() {
   3102         mPolicy.showGlobalActions();
   3103     }
   3104 
   3105     @Override
   3106     public void closeSystemDialogs(String reason) {
   3107         synchronized(mWindowMap) {
   3108             mRoot.closeSystemDialogs(reason);
   3109         }
   3110     }
   3111 
   3112     static float fixScale(float scale) {
   3113         if (scale < 0) scale = 0;
   3114         else if (scale > 20) scale = 20;
   3115         return Math.abs(scale);
   3116     }
   3117 
   3118     @Override
   3119     public void setAnimationScale(int which, float scale) {
   3120         if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
   3121                 "setAnimationScale()")) {
   3122             throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
   3123         }
   3124 
   3125         scale = fixScale(scale);
   3126         switch (which) {
   3127             case 0: mWindowAnimationScaleSetting = scale; break;
   3128             case 1: mTransitionAnimationScaleSetting = scale; break;
   3129             case 2: mAnimatorDurationScaleSetting = scale; break;
   3130         }
   3131 
   3132         // Persist setting
   3133         mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
   3134     }
   3135 
   3136     @Override
   3137     public void setAnimationScales(float[] scales) {
   3138         if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
   3139                 "setAnimationScale()")) {
   3140             throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
   3141         }
   3142 
   3143         if (scales != null) {
   3144             if (scales.length >= 1) {
   3145                 mWindowAnimationScaleSetting = fixScale(scales[0]);
   3146             }
   3147             if (scales.length >= 2) {
   3148                 mTransitionAnimationScaleSetting = fixScale(scales[1]);
   3149             }
   3150             if (scales.length >= 3) {
   3151                 mAnimatorDurationScaleSetting = fixScale(scales[2]);
   3152                 dispatchNewAnimatorScaleLocked(null);
   3153             }
   3154         }
   3155 
   3156         // Persist setting
   3157         mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
   3158     }
   3159 
   3160     private void setAnimatorDurationScale(float scale) {
   3161         mAnimatorDurationScaleSetting = scale;
   3162         ValueAnimator.setDurationScale(scale);
   3163     }
   3164 
   3165     public float getWindowAnimationScaleLocked() {
   3166         return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting;
   3167     }
   3168 
   3169     public float getTransitionAnimationScaleLocked() {
   3170         return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting;
   3171     }
   3172 
   3173     @Override
   3174     public float getAnimationScale(int which) {
   3175         switch (which) {
   3176             case 0: return mWindowAnimationScaleSetting;
   3177             case 1: return mTransitionAnimationScaleSetting;
   3178             case 2: return mAnimatorDurationScaleSetting;
   3179         }
   3180         return 0;
   3181     }
   3182 
   3183     @Override
   3184     public float[] getAnimationScales() {
   3185         return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting,
   3186                 mAnimatorDurationScaleSetting };
   3187     }
   3188 
   3189     @Override
   3190     public float getCurrentAnimatorScale() {
   3191         synchronized(mWindowMap) {
   3192             return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting;
   3193         }
   3194     }
   3195 
   3196     void dispatchNewAnimatorScaleLocked(Session session) {
   3197         mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget();
   3198     }
   3199 
   3200     @Override
   3201     public void registerPointerEventListener(PointerEventListener listener) {
   3202         mPointerEventDispatcher.registerInputEventListener(listener);
   3203     }
   3204 
   3205     @Override
   3206     public void unregisterPointerEventListener(PointerEventListener listener) {
   3207         mPointerEventDispatcher.unregisterInputEventListener(listener);
   3208     }
   3209 
   3210     /** Check if the service is set to dispatch pointer events. */
   3211     boolean canDispatchPointerEvents() {
   3212         return mPointerEventDispatcher != null;
   3213     }
   3214 
   3215     // Called by window manager policy. Not exposed externally.
   3216     @Override
   3217     public int getLidState() {
   3218         int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
   3219                 InputManagerService.SW_LID);
   3220         if (sw > 0) {
   3221             // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
   3222             return LID_CLOSED;
   3223         } else if (sw == 0) {
   3224             // Switch state: AKEY_STATE_UP.
   3225             return LID_OPEN;
   3226         } else {
   3227             // Switch state: AKEY_STATE_UNKNOWN.
   3228             return LID_ABSENT;
   3229         }
   3230     }
   3231 
   3232     // Called by window manager policy. Not exposed externally.
   3233     @Override
   3234     public void lockDeviceNow() {
   3235         lockNow(null);
   3236     }
   3237 
   3238     // Called by window manager policy. Not exposed externally.
   3239     @Override
   3240     public int getCameraLensCoverState() {
   3241         int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
   3242                 InputManagerService.SW_CAMERA_LENS_COVER);
   3243         if (sw > 0) {
   3244             // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
   3245             return CAMERA_LENS_COVERED;
   3246         } else if (sw == 0) {
   3247             // Switch state: AKEY_STATE_UP.
   3248             return CAMERA_LENS_UNCOVERED;
   3249         } else {
   3250             // Switch state: AKEY_STATE_UNKNOWN.
   3251             return CAMERA_LENS_COVER_ABSENT;
   3252         }
   3253     }
   3254 
   3255     // Called by window manager policy.  Not exposed externally.
   3256     @Override
   3257     public void switchKeyboardLayout(int deviceId, int direction) {
   3258         mInputManager.switchKeyboardLayout(deviceId, direction);
   3259     }
   3260 
   3261     // Called by window manager policy.  Not exposed externally.
   3262     @Override
   3263     public void switchInputMethod(boolean forwardDirection) {
   3264         final InputMethodManagerInternal inputMethodManagerInternal =
   3265                 LocalServices.getService(InputMethodManagerInternal.class);
   3266         if (inputMethodManagerInternal != null) {
   3267             inputMethodManagerInternal.switchInputMethod(forwardDirection);
   3268         }
   3269     }
   3270 
   3271     // Called by window manager policy.  Not exposed externally.
   3272     @Override
   3273     public void shutdown(boolean confirm) {
   3274         // Pass in the UI context, since ShutdownThread requires it (to show UI).
   3275         ShutdownThread.shutdown(ActivityThread.currentActivityThread().getSystemUiContext(),
   3276                 PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
   3277     }
   3278 
   3279     // Called by window manager policy.  Not exposed externally.
   3280     @Override
   3281     public void reboot(boolean confirm) {
   3282         // Pass in the UI context, since ShutdownThread requires it (to show UI).
   3283         ShutdownThread.reboot(ActivityThread.currentActivityThread().getSystemUiContext(),
   3284                 PowerManager.SHUTDOWN_USER_REQUESTED, confirm);
   3285     }
   3286 
   3287     // Called by window manager policy.  Not exposed externally.
   3288     @Override
   3289     public void rebootSafeMode(boolean confirm) {
   3290         // Pass in the UI context, since ShutdownThread requires it (to show UI).
   3291         ShutdownThread.rebootSafeMode(ActivityThread.currentActivityThread().getSystemUiContext(),
   3292                 confirm);
   3293     }
   3294 
   3295     public void setCurrentProfileIds(final int[] currentProfileIds) {
   3296         synchronized (mWindowMap) {
   3297             mCurrentProfileIds = currentProfileIds;
   3298         }
   3299     }
   3300 
   3301     public void setCurrentUser(final int newUserId, final int[] currentProfileIds) {
   3302         synchronized (mWindowMap) {
   3303             mCurrentUserId = newUserId;
   3304             mCurrentProfileIds = currentProfileIds;
   3305             mAppTransition.setCurrentUser(newUserId);
   3306             mPolicy.setCurrentUserLw(newUserId);
   3307 
   3308             // If keyguard was disabled, re-enable it
   3309             // TODO: Keep track of keyguardEnabled state per user and use here...
   3310             // e.g. enabled = mKeyguardDisableHandler.getEnabledStateForUser(newUserId);
   3311             mPolicy.enableKeyguard(true);
   3312 
   3313             // Hide windows that should not be seen by the new user.
   3314             mRoot.switchUser();
   3315             mWindowPlacerLocked.performSurfacePlacement();
   3316 
   3317             // Notify whether the docked stack exists for the current user
   3318             final DisplayContent displayContent = getDefaultDisplayContentLocked();
   3319             final TaskStack stack =
   3320                     displayContent.getSplitScreenPrimaryStackIgnoringVisibility();
   3321             displayContent.mDividerControllerLocked.notifyDockedStackExistsChanged(
   3322                     stack != null && stack.hasTaskForUser(newUserId));
   3323 
   3324             // If the display is already prepared, update the density.
   3325             // Otherwise, we'll update it when it's prepared.
   3326             if (mDisplayReady) {
   3327                 final int forcedDensity = getForcedDisplayDensityForUserLocked(newUserId);
   3328                 final int targetDensity = forcedDensity != 0 ? forcedDensity
   3329                         : displayContent.mInitialDisplayDensity;
   3330                 setForcedDisplayDensityLocked(displayContent, targetDensity);
   3331             }
   3332         }
   3333     }
   3334 
   3335     /* Called by WindowState */
   3336     boolean isCurrentProfileLocked(int userId) {
   3337         if (userId == mCurrentUserId) return true;
   3338         for (int i = 0; i < mCurrentProfileIds.length; i++) {
   3339             if (mCurrentProfileIds[i] == userId) return true;
   3340         }
   3341         return false;
   3342     }
   3343 
   3344     public void enableScreenAfterBoot() {
   3345         synchronized(mWindowMap) {
   3346             if (DEBUG_BOOT) {
   3347                 RuntimeException here = new RuntimeException("here");
   3348                 here.fillInStackTrace();
   3349                 Slog.i(TAG_WM, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
   3350                         + " mForceDisplayEnabled=" + mForceDisplayEnabled
   3351                         + " mShowingBootMessages=" + mShowingBootMessages
   3352                         + " mSystemBooted=" + mSystemBooted, here);
   3353             }
   3354             if (mSystemBooted) {
   3355                 return;
   3356             }
   3357             mSystemBooted = true;
   3358             hideBootMessagesLocked();
   3359             // If the screen still doesn't come up after 30 seconds, give
   3360             // up and turn it on.
   3361             mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30 * 1000);
   3362         }
   3363 
   3364         mPolicy.systemBooted();
   3365 
   3366         performEnableScreen();
   3367     }
   3368 
   3369     @Override
   3370     public void enableScreenIfNeeded() {
   3371         synchronized (mWindowMap) {
   3372             enableScreenIfNeededLocked();
   3373         }
   3374     }
   3375 
   3376     void enableScreenIfNeededLocked() {
   3377         if (DEBUG_BOOT) {
   3378             RuntimeException here = new RuntimeException("here");
   3379             here.fillInStackTrace();
   3380             Slog.i(TAG_WM, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
   3381                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
   3382                     + " mShowingBootMessages=" + mShowingBootMessages
   3383                     + " mSystemBooted=" + mSystemBooted, here);
   3384         }
   3385         if (mDisplayEnabled) {
   3386             return;
   3387         }
   3388         if (!mSystemBooted && !mShowingBootMessages) {
   3389             return;
   3390         }
   3391         mH.sendEmptyMessage(H.ENABLE_SCREEN);
   3392     }
   3393 
   3394     public void performBootTimeout() {
   3395         synchronized(mWindowMap) {
   3396             if (mDisplayEnabled) {
   3397                 return;
   3398             }
   3399             Slog.w(TAG_WM, "***** BOOT TIMEOUT: forcing display enabled");
   3400             mForceDisplayEnabled = true;
   3401         }
   3402         performEnableScreen();
   3403     }
   3404 
   3405     /**
   3406      * Called when System UI has been started.
   3407      */
   3408     public void onSystemUiStarted() {
   3409         mPolicy.onSystemUiStarted();
   3410     }
   3411 
   3412     private void performEnableScreen() {
   3413         synchronized(mWindowMap) {
   3414             if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
   3415                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
   3416                     + " mShowingBootMessages=" + mShowingBootMessages
   3417                     + " mSystemBooted=" + mSystemBooted
   3418                     + " mOnlyCore=" + mOnlyCore,
   3419                     new RuntimeException("here").fillInStackTrace());
   3420             if (mDisplayEnabled) {
   3421                 return;
   3422             }
   3423             if (!mSystemBooted && !mShowingBootMessages) {
   3424                 return;
   3425             }
   3426 
   3427             if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) {
   3428                 return;
   3429             }
   3430 
   3431             // Don't enable the screen until all existing windows have been drawn.
   3432             if (!mForceDisplayEnabled
   3433                     // TODO(multidisplay): Expand to all displays?
   3434                     && getDefaultDisplayContentLocked().checkWaitingForWindows()) {
   3435                 return;
   3436             }
   3437 
   3438             if (!mBootAnimationStopped) {
   3439                 Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
   3440                 // stop boot animation
   3441                 // formerly we would just kill the process, but we now ask it to exit so it
   3442                 // can choose where to stop the animation.
   3443                 SystemProperties.set("service.bootanim.exit", "1");
   3444                 mBootAnimationStopped = true;
   3445             }
   3446 
   3447             if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
   3448                 if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: Waiting for anim complete");
   3449                 return;
   3450             }
   3451 
   3452             try {
   3453                 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
   3454                 if (surfaceFlinger != null) {
   3455                     Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
   3456                     Parcel data = Parcel.obtain();
   3457                     data.writeInterfaceToken("android.ui.ISurfaceComposer");
   3458                     surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
   3459                             data, null, 0);
   3460                     data.recycle();
   3461                 }
   3462             } catch (RemoteException ex) {
   3463                 Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
   3464             }
   3465 
   3466             EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
   3467             Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
   3468             mDisplayEnabled = true;
   3469             if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG_WM, "******************** ENABLING SCREEN!");
   3470 
   3471             // Enable input dispatch.
   3472             mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
   3473         }
   3474 
   3475         try {
   3476             mActivityManager.bootAnimationComplete();
   3477         } catch (RemoteException e) {
   3478         }
   3479 
   3480         mPolicy.enableScreenAfterBoot();
   3481 
   3482         // Make sure the last requested orientation has been applied.
   3483         updateRotationUnchecked(false, false);
   3484     }
   3485 
   3486     private boolean checkBootAnimationCompleteLocked() {
   3487         if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
   3488             mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
   3489             mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
   3490                     BOOT_ANIMATION_POLL_INTERVAL);
   3491             if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Waiting for anim complete");
   3492             return false;
   3493         }
   3494         if (DEBUG_BOOT) Slog.i(TAG_WM, "checkBootAnimationComplete: Animation complete!");
   3495         return true;
   3496     }
   3497 
   3498     public void showBootMessage(final CharSequence msg, final boolean always) {
   3499         boolean first = false;
   3500         synchronized(mWindowMap) {
   3501             if (DEBUG_BOOT) {
   3502                 RuntimeException here = new RuntimeException("here");
   3503                 here.fillInStackTrace();
   3504                 Slog.i(TAG_WM, "showBootMessage: msg=" + msg + " always=" + always
   3505                         + " mAllowBootMessages=" + mAllowBootMessages
   3506                         + " mShowingBootMessages=" + mShowingBootMessages
   3507                         + " mSystemBooted=" + mSystemBooted, here);
   3508             }
   3509             if (!mAllowBootMessages) {
   3510                 return;
   3511             }
   3512             if (!mShowingBootMessages) {
   3513                 if (!always) {
   3514                     return;
   3515                 }
   3516                 first = true;
   3517             }
   3518             if (mSystemBooted) {
   3519                 return;
   3520             }
   3521             mShowingBootMessages = true;
   3522             mPolicy.showBootMessage(msg, always);
   3523         }
   3524         if (first) {
   3525             performEnableScreen();
   3526         }
   3527     }
   3528 
   3529     public void hideBootMessagesLocked() {
   3530         if (DEBUG_BOOT) {
   3531             RuntimeException here = new RuntimeException("here");
   3532             here.fillInStackTrace();
   3533             Slog.i(TAG_WM, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
   3534                     + " mForceDisplayEnabled=" + mForceDisplayEnabled
   3535                     + " mShowingBootMessages=" + mShowingBootMessages
   3536                     + " mSystemBooted=" + mSystemBooted, here);
   3537         }
   3538         if (mShowingBootMessages) {
   3539             mShowingBootMessages = false;
   3540             mPolicy.hideBootMessages();
   3541         }
   3542     }
   3543 
   3544     @Override
   3545     public void setInTouchMode(boolean mode) {
   3546         synchronized(mWindowMap) {
   3547             mInTouchMode = mode;
   3548         }
   3549     }
   3550 
   3551     private void updateCircularDisplayMaskIfNeeded() {
   3552         if (mContext.getResources().getConfiguration().isScreenRound()
   3553                 && mContext.getResources().getBoolean(
   3554                 com.android.internal.R.bool.config_windowShowCircularMask)) {
   3555             final int currentUserId;
   3556             synchronized(mWindowMap) {
   3557                 currentUserId = mCurrentUserId;
   3558             }
   3559             // Device configuration calls for a circular display mask, but we only enable the mask
   3560             // if the accessibility color inversion feature is disabled, as the inverted mask
   3561             // causes artifacts.
   3562             int inversionState = Settings.Secure.getIntForUser(mContext.getContentResolver(),
   3563                     Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, currentUserId);
   3564             int showMask = (inversionState == 1) ? 0 : 1;
   3565             Message m = mH.obtainMessage(H.SHOW_CIRCULAR_DISPLAY_MASK);
   3566             m.arg1 = showMask;
   3567             mH.sendMessage(m);
   3568         }
   3569     }
   3570 
   3571     public void showEmulatorDisplayOverlayIfNeeded() {
   3572         if (mContext.getResources().getBoolean(
   3573                 com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay)
   3574                 && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false)
   3575                 && Build.IS_EMULATOR) {
   3576             mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY));
   3577         }
   3578     }
   3579 
   3580     public void showCircularMask(boolean visible) {
   3581         synchronized(mWindowMap) {
   3582 
   3583             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
   3584                     ">>> OPEN TRANSACTION showCircularMask(visible=" + visible + ")");
   3585             openSurfaceTransaction();
   3586             try {
   3587                 if (visible) {
   3588                     // TODO(multi-display): support multiple displays
   3589                     if (mCircularDisplayMask == null) {
   3590                         int screenOffset = mContext.getResources().getInteger(
   3591                                 com.android.internal.R.integer.config_windowOutsetBottom);
   3592                         int maskThickness = mContext.getResources().getDimensionPixelSize(
   3593                                 com.android.internal.R.dimen.circular_display_mask_thickness);
   3594 
   3595                         mCircularDisplayMask = new CircularDisplayMask(
   3596                                 getDefaultDisplayContentLocked(),
   3597                                 mPolicy.getWindowLayerFromTypeLw(
   3598                                         WindowManager.LayoutParams.TYPE_POINTER)
   3599                                         * TYPE_LAYER_MULTIPLIER + 10, screenOffset, maskThickness);
   3600                     }
   3601                     mCircularDisplayMask.setVisibility(true);
   3602                 } else if (mCircularDisplayMask != null) {
   3603                     mCircularDisplayMask.setVisibility(false);
   3604                     mCircularDisplayMask = null;
   3605                 }
   3606             } finally {
   3607                 closeSurfaceTransaction("showCircularMask");
   3608                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
   3609                         "<<< CLOSE TRANSACTION showCircularMask(visible=" + visible + ")");
   3610             }
   3611         }
   3612     }
   3613 
   3614     public void showEmulatorDisplayOverlay() {
   3615         synchronized(mWindowMap) {
   3616 
   3617             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
   3618                     ">>> OPEN TRANSACTION showEmulatorDisplayOverlay");
   3619             openSurfaceTransaction();
   3620             try {
   3621                 if (mEmulatorDisplayOverlay == null) {
   3622                     mEmulatorDisplayOverlay = new EmulatorDisplayOverlay(
   3623                             mContext,
   3624                             getDefaultDisplayContentLocked(),
   3625                             mPolicy.getWindowLayerFromTypeLw(
   3626                                     WindowManager.LayoutParams.TYPE_POINTER)
   3627                                     * TYPE_LAYER_MULTIPLIER + 10);
   3628                 }
   3629                 mEmulatorDisplayOverlay.setVisibility(true);
   3630             } finally {
   3631                 closeSurfaceTransaction("showEmulatorDisplayOverlay");
   3632                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
   3633                         "<<< CLOSE TRANSACTION showEmulatorDisplayOverlay");
   3634             }
   3635         }
   3636     }
   3637 
   3638     // TODO: more accounting of which pid(s) turned it on, keep count,
   3639     // only allow disables from pids which have count on, etc.
   3640     @Override
   3641     public void showStrictModeViolation(boolean on) {
   3642         final int pid = Binder.getCallingPid();
   3643         if (on) {
   3644             // Show the visualization, and enqueue a second message to tear it
   3645             // down if we don't hear back from the app.
   3646             mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 1, pid));
   3647             mH.sendMessageDelayed(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid),
   3648                     DateUtils.SECOND_IN_MILLIS);
   3649         } else {
   3650             mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, 0, pid));
   3651         }
   3652     }
   3653 
   3654     private void showStrictModeViolation(int arg, int pid) {
   3655         final boolean on = arg != 0;
   3656         synchronized(mWindowMap) {
   3657             // Ignoring requests to enable the red border from clients which aren't on screen.
   3658             // (e.g. Broadcast Receivers in the background..)
   3659             if (on && !mRoot.canShowStrictModeViolation(pid)) {
   3660                 return;
   3661             }
   3662 
   3663             if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM,
   3664                     ">>> OPEN TRANSACTION showStrictModeViolation");
   3665             // TODO: Modify this to use the surface trace once it is not going crazy.
   3666             // b/31532461
   3667             SurfaceControl.openTransaction();
   3668             try {
   3669                 // TODO(multi-display): support multiple displays
   3670                 if (mStrictModeFlash == null) {
   3671                     mStrictModeFlash = new StrictModeFlash(
   3672                             getDefaultDisplayContentLocked());
   3673                 }
   3674                 mStrictModeFlash.setVisibility(on);
   3675             } finally {
   3676                 SurfaceControl.closeTransaction();
   3677                 if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM,
   3678                         "<<< CLOSE TRANSACTION showStrictModeViolation");
   3679             }
   3680         }
   3681     }
   3682 
   3683     @Override
   3684     public void setStrictModeVisualIndicatorPreference(String value) {
   3685         SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
   3686     }
   3687 
   3688     @Override
   3689     public Bitmap screenshotWallpaper() {
   3690         if (!checkCallingPermission(READ_FRAME_BUFFER, "screenshotWallpaper()")) {
   3691             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
   3692         }
   3693         try {
   3694             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "screenshotWallpaper");
   3695             synchronized (mWindowMap) {
   3696                 return mRoot.mWallpaperController.screenshotWallpaperLocked();
   3697             }
   3698         } finally {
   3699             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   3700         }
   3701     }
   3702 
   3703     /**
   3704      * Takes a snapshot of the screen.  In landscape mode this grabs the whole screen.
   3705      * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
   3706      * of the target image.
   3707      */
   3708     @Override
   3709     public boolean requestAssistScreenshot(final IAssistDataReceiver receiver) {
   3710         if (!checkCallingPermission(READ_FRAME_BUFFER, "requestAssistScreenshot()")) {
   3711             throw new SecurityException("Requires READ_FRAME_BUFFER permission");
   3712         }
   3713 
   3714         final Bitmap bm;
   3715         synchronized (mWindowMap) {
   3716             final DisplayContent displayContent = mRoot.getDisplayContent(DEFAULT_DISPLAY);
   3717             if (displayContent == null) {
   3718                 if (DEBUG_SCREENSHOT) {
   3719                     Slog.i(TAG_WM, "Screenshot returning null. No Display for displayId="
   3720                             + DEFAULT_DISPLAY);
   3721                 }
   3722                 bm = null;
   3723             } else {
   3724                 bm = displayContent.screenshotDisplayLocked(Bitmap.Config.ARGB_8888);
   3725             }
   3726         }
   3727 
   3728         FgThread.getHandler().post(() -> {
   3729             try {
   3730                 receiver.onHandleAssistScreenshot(bm);
   3731             } catch (RemoteException e) {
   3732             }
   3733         });
   3734 
   3735         return true;
   3736     }
   3737 
   3738     public TaskSnapshot getTaskSnapshot(int taskId, int userId, boolean reducedResolution) {
   3739         return mTaskSnapshotController.getSnapshot(taskId, userId, true /* restoreFromDisk */,
   3740                 reducedResolution);
   3741     }
   3742 
   3743     /**
   3744      * In case a task write/delete operation was lost because the system crashed, this makes sure to
   3745      * clean up the directory to remove obsolete files.
   3746      *
   3747      * @param persistentTaskIds A set of task ids that exist in our in-memory model.
   3748      * @param runningUserIds The ids of the list of users that have tasks loaded in our in-memory
   3749      *                       model.
   3750      */
   3751     public void removeObsoleteTaskFiles(ArraySet<Integer> persistentTaskIds, int[] runningUserIds) {
   3752         synchronized (mWindowMap) {
   3753             mTaskSnapshotController.removeObsoleteTaskFiles(persistentTaskIds, runningUserIds);
   3754         }
   3755     }
   3756 
   3757     /**
   3758      * Freeze rotation changes.  (Enable "rotation lock".)
   3759      * Persists across reboots.
   3760      * @param rotation The desired rotation to freeze to, or -1 to use the
   3761      * current rotation.
   3762      */
   3763     @Override
   3764     public void freezeRotation(int rotation) {
   3765         // TODO(multi-display): Track which display is rotated.
   3766         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
   3767                 "freezeRotation()")) {
   3768             throw new SecurityException("Requires SET_ORIENTATION permission");
   3769         }
   3770         if (rotation < -1 || rotation > Surface.ROTATION_270) {
   3771             throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
   3772                     + "rotation constant.");
   3773         }
   3774 
   3775         final int defaultDisplayRotation = getDefaultDisplayRotation();
   3776         if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: mRotation="
   3777                 + defaultDisplayRotation);
   3778 
   3779         long origId = Binder.clearCallingIdentity();
   3780         try {
   3781             mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
   3782                     rotation == -1 ? defaultDisplayRotation : rotation);
   3783         } finally {
   3784             Binder.restoreCallingIdentity(origId);
   3785         }
   3786 
   3787         updateRotationUnchecked(false, false);
   3788     }
   3789 
   3790     /**
   3791      * Thaw rotation changes.  (Disable "rotation lock".)
   3792      * Persists across reboots.
   3793      */
   3794     @Override
   3795     public void thawRotation() {
   3796         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
   3797                 "thawRotation()")) {
   3798             throw new SecurityException("Requires SET_ORIENTATION permission");
   3799         }
   3800 
   3801         if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "thawRotation: mRotation="
   3802                 + getDefaultDisplayRotation());
   3803 
   3804         long origId = Binder.clearCallingIdentity();
   3805         try {
   3806             mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
   3807                     777); // rot not used
   3808         } finally {
   3809             Binder.restoreCallingIdentity(origId);
   3810         }
   3811 
   3812         updateRotationUnchecked(false, false);
   3813     }
   3814 
   3815     /**
   3816      * Recalculate the current rotation.
   3817      *
   3818      * Called by the window manager policy whenever the state of the system changes
   3819      * such that the current rotation might need to be updated, such as when the
   3820      * device is docked or rotated into a new posture.
   3821      */
   3822     @Override
   3823     public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
   3824         updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
   3825     }
   3826 
   3827     /**
   3828      * Temporarily pauses rotation changes until resumed.
   3829      *
   3830      * This can be used to prevent rotation changes from occurring while the user is
   3831      * performing certain operations, such as drag and drop.
   3832      *
   3833      * This call nests and must be matched by an equal number of calls to
   3834      * {@link #resumeRotationLocked}.
   3835      */
   3836     void pauseRotationLocked() {
   3837         mDeferredRotationPauseCount += 1;
   3838     }
   3839 
   3840     /**
   3841      * Resumes normal rotation changes after being paused.
   3842      */
   3843     void resumeRotationLocked() {
   3844         if (mDeferredRotationPauseCount > 0) {
   3845             mDeferredRotationPauseCount -= 1;
   3846             if (mDeferredRotationPauseCount == 0) {
   3847                 // TODO(multi-display): Update rotation for different displays separately.
   3848                 final DisplayContent displayContent = getDefaultDisplayContentLocked();
   3849                 final boolean changed = displayContent.updateRotationUnchecked();
   3850                 if (changed) {
   3851                     mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
   3852                             .sendToTarget();
   3853                 }
   3854             }
   3855         }
   3856     }
   3857 
   3858     private void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
   3859         if(DEBUG_ORIENTATION) Slog.v(TAG_WM, "updateRotationUnchecked:"
   3860                 + " alwaysSendConfiguration=" + alwaysSendConfiguration
   3861                 + " forceRelayout=" + forceRelayout);
   3862 
   3863         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation");
   3864 
   3865         long origId = Binder.clearCallingIdentity();
   3866 
   3867         try {
   3868             // TODO(multi-display): Update rotation for different displays separately.
   3869             final boolean rotationChanged;
   3870             final int displayId;
   3871             synchronized (mWindowMap) {
   3872                 final DisplayContent displayContent = getDefaultDisplayContentLocked();
   3873                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
   3874                 rotationChanged = displayContent.updateRotationUnchecked();
   3875                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   3876                 if (!rotationChanged || forceRelayout) {
   3877                     displayContent.setLayoutNeeded();
   3878                     Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
   3879                             "updateRotation: performSurfacePlacement");
   3880                     mWindowPlacerLocked.performSurfacePlacement();
   3881                     Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   3882                 }
   3883                 displayId = displayContent.getDisplayId();
   3884             }
   3885 
   3886             if (rotationChanged || alwaysSendConfiguration) {
   3887                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: sendNewConfiguration");
   3888                 sendNewConfiguration(displayId);
   3889                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   3890             }
   3891         } finally {
   3892             Binder.restoreCallingIdentity(origId);
   3893             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   3894         }
   3895     }
   3896 
   3897     @Override
   3898     public int getDefaultDisplayRotation() {
   3899         synchronized (mWindowMap) {
   3900             return getDefaultDisplayContentLocked().getRotation();
   3901         }
   3902     }
   3903 
   3904     @Override
   3905     public boolean isRotationFrozen() {
   3906         return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
   3907     }
   3908 
   3909     @Override
   3910     public int watchRotation(IRotationWatcher watcher, int displayId) {
   3911         final IBinder watcherBinder = watcher.asBinder();
   3912         IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
   3913             @Override
   3914             public void binderDied() {
   3915                 synchronized (mWindowMap) {
   3916                     for (int i=0; i<mRotationWatchers.size(); i++) {
   3917                         if (watcherBinder == mRotationWatchers.get(i).mWatcher.asBinder()) {
   3918                             RotationWatcher removed = mRotationWatchers.remove(i);
   3919                             IBinder binder = removed.mWatcher.asBinder();
   3920                             if (binder != null) {
   3921                                 binder.unlinkToDeath(this, 0);
   3922                             }
   3923                             i--;
   3924                         }
   3925                     }
   3926                 }
   3927             }
   3928         };
   3929 
   3930         synchronized (mWindowMap) {
   3931             try {
   3932                 watcher.asBinder().linkToDeath(dr, 0);
   3933                 mRotationWatchers.add(new RotationWatcher(watcher, dr, displayId));
   3934             } catch (RemoteException e) {
   3935                 // Client died, no cleanup needed.
   3936             }
   3937 
   3938             return getDefaultDisplayRotation();
   3939         }
   3940     }
   3941 
   3942     @Override
   3943     public void removeRotationWatcher(IRotationWatcher watcher) {
   3944         final IBinder watcherBinder = watcher.asBinder();
   3945         synchronized (mWindowMap) {
   3946             for (int i=0; i<mRotationWatchers.size(); i++) {
   3947                 RotationWatcher rotationWatcher = mRotationWatchers.get(i);
   3948                 if (watcherBinder == rotationWatcher.mWatcher.asBinder()) {
   3949                     RotationWatcher removed = mRotationWatchers.remove(i);
   3950                     IBinder binder = removed.mWatcher.asBinder();
   3951                     if (binder != null) {
   3952                         binder.unlinkToDeath(removed.mDeathRecipient, 0);
   3953                     }
   3954                     i--;
   3955                 }
   3956             }
   3957         }
   3958     }
   3959 
   3960     @Override
   3961     public boolean registerWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
   3962             int displayId) {
   3963         synchronized (mWindowMap) {
   3964             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   3965             if (displayContent == null) {
   3966                 throw new IllegalArgumentException("Trying to register visibility event "
   3967                         + "for invalid display: " + displayId);
   3968             }
   3969             mWallpaperVisibilityListeners.registerWallpaperVisibilityListener(listener, displayId);
   3970             return displayContent.mWallpaperController.isWallpaperVisible();
   3971         }
   3972     }
   3973 
   3974     @Override
   3975     public void unregisterWallpaperVisibilityListener(IWallpaperVisibilityListener listener,
   3976             int displayId) {
   3977         synchronized (mWindowMap) {
   3978             mWallpaperVisibilityListeners
   3979                     .unregisterWallpaperVisibilityListener(listener, displayId);
   3980         }
   3981     }
   3982 
   3983     /**
   3984      * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
   3985      * theme attribute) on devices that feature a physical options menu key attempt to position
   3986      * their menu panel window along the edge of the screen nearest the physical menu key.
   3987      * This lowers the travel distance between invoking the menu panel and selecting
   3988      * a menu option.
   3989      *
   3990      * This method helps control where that menu is placed. Its current implementation makes
   3991      * assumptions about the menu key and its relationship to the screen based on whether
   3992      * the device's natural orientation is portrait (width < height) or landscape.
   3993      *
   3994      * The menu key is assumed to be located along the bottom edge of natural-portrait
   3995      * devices and along the right edge of natural-landscape devices. If these assumptions
   3996      * do not hold for the target device, this method should be changed to reflect that.
   3997      *
   3998      * @return A {@link Gravity} value for placing the options menu window
   3999      */
   4000     @Override
   4001     public int getPreferredOptionsPanelGravity() {
   4002         synchronized (mWindowMap) {
   4003             // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
   4004             final DisplayContent displayContent = getDefaultDisplayContentLocked();
   4005             final int rotation = displayContent.getRotation();
   4006             if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
   4007                 // On devices with a natural orientation of portrait
   4008                 switch (rotation) {
   4009                     default:
   4010                     case Surface.ROTATION_0:
   4011                         return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
   4012                     case Surface.ROTATION_90:
   4013                         return Gravity.RIGHT | Gravity.BOTTOM;
   4014                     case Surface.ROTATION_180:
   4015                         return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
   4016                     case Surface.ROTATION_270:
   4017                         return Gravity.START | Gravity.BOTTOM;
   4018                 }
   4019             }
   4020 
   4021             // On devices with a natural orientation of landscape
   4022             switch (rotation) {
   4023                 default:
   4024                 case Surface.ROTATION_0:
   4025                     return Gravity.RIGHT | Gravity.BOTTOM;
   4026                 case Surface.ROTATION_90:
   4027                     return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
   4028                 case Surface.ROTATION_180:
   4029                     return Gravity.START | Gravity.BOTTOM;
   4030                 case Surface.ROTATION_270:
   4031                     return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
   4032             }
   4033         }
   4034     }
   4035 
   4036     /**
   4037      * Starts the view server on the specified port.
   4038      *
   4039      * @param port The port to listener to.
   4040      *
   4041      * @return True if the server was successfully started, false otherwise.
   4042      *
   4043      * @see com.android.server.wm.ViewServer
   4044      * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
   4045      */
   4046     @Override
   4047     public boolean startViewServer(int port) {
   4048         if (isSystemSecure()) {
   4049             return false;
   4050         }
   4051 
   4052         if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
   4053             return false;
   4054         }
   4055 
   4056         if (port < 1024) {
   4057             return false;
   4058         }
   4059 
   4060         if (mViewServer != null) {
   4061             if (!mViewServer.isRunning()) {
   4062                 try {
   4063                     return mViewServer.start();
   4064                 } catch (IOException e) {
   4065                     Slog.w(TAG_WM, "View server did not start");
   4066                 }
   4067             }
   4068             return false;
   4069         }
   4070 
   4071         try {
   4072             mViewServer = new ViewServer(this, port);
   4073             return mViewServer.start();
   4074         } catch (IOException e) {
   4075             Slog.w(TAG_WM, "View server did not start");
   4076         }
   4077         return false;
   4078     }
   4079 
   4080     private boolean isSystemSecure() {
   4081         return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
   4082                 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
   4083     }
   4084 
   4085     /**
   4086      * Stops the view server if it exists.
   4087      *
   4088      * @return True if the server stopped, false if it wasn't started or
   4089      *         couldn't be stopped.
   4090      *
   4091      * @see com.android.server.wm.ViewServer
   4092      */
   4093     @Override
   4094     public boolean stopViewServer() {
   4095         if (isSystemSecure()) {
   4096             return false;
   4097         }
   4098 
   4099         if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
   4100             return false;
   4101         }
   4102 
   4103         if (mViewServer != null) {
   4104             return mViewServer.stop();
   4105         }
   4106         return false;
   4107     }
   4108 
   4109     /**
   4110      * Indicates whether the view server is running.
   4111      *
   4112      * @return True if the server is running, false otherwise.
   4113      *
   4114      * @see com.android.server.wm.ViewServer
   4115      */
   4116     @Override
   4117     public boolean isViewServerRunning() {
   4118         if (isSystemSecure()) {
   4119             return false;
   4120         }
   4121 
   4122         if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
   4123             return false;
   4124         }
   4125 
   4126         return mViewServer != null && mViewServer.isRunning();
   4127     }
   4128 
   4129     /**
   4130      * Lists all available windows in the system. The listing is written in the specified Socket's
   4131      * output stream with the following syntax: windowHashCodeInHexadecimal windowName
   4132      * Each line of the output represents a different window.
   4133      *
   4134      * @param client The remote client to send the listing to.
   4135      * @return false if an error occurred, true otherwise.
   4136      */
   4137     boolean viewServerListWindows(Socket client) {
   4138         if (isSystemSecure()) {
   4139             return false;
   4140         }
   4141 
   4142         boolean result = true;
   4143 
   4144         final ArrayList<WindowState> windows = new ArrayList();
   4145         synchronized (mWindowMap) {
   4146             mRoot.forAllWindows(w -> {
   4147                 windows.add(w);
   4148             }, false /* traverseTopToBottom */);
   4149         }
   4150 
   4151         BufferedWriter out = null;
   4152 
   4153         // Any uncaught exception will crash the system process
   4154         try {
   4155             OutputStream clientStream = client.getOutputStream();
   4156             out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
   4157 
   4158             final int count = windows.size();
   4159             for (int i = 0; i < count; i++) {
   4160                 final WindowState w = windows.get(i);
   4161                 out.write(Integer.toHexString(System.identityHashCode(w)));
   4162                 out.write(' ');
   4163                 out.append(w.mAttrs.getTitle());
   4164                 out.write('\n');
   4165             }
   4166 
   4167             out.write("DONE.\n");
   4168             out.flush();
   4169         } catch (Exception e) {
   4170             result = false;
   4171         } finally {
   4172             if (out != null) {
   4173                 try {
   4174                     out.close();
   4175                 } catch (IOException e) {
   4176                     result = false;
   4177                 }
   4178             }
   4179         }
   4180 
   4181         return result;
   4182     }
   4183 
   4184     // TODO(multidisplay): Extend to multiple displays.
   4185     /**
   4186      * Returns the focused window in the following format:
   4187      * windowHashCodeInHexadecimal windowName
   4188      *
   4189      * @param client The remote client to send the listing to.
   4190      * @return False if an error occurred, true otherwise.
   4191      */
   4192     boolean viewServerGetFocusedWindow(Socket client) {
   4193         if (isSystemSecure()) {
   4194             return false;
   4195         }
   4196 
   4197         boolean result = true;
   4198 
   4199         WindowState focusedWindow = getFocusedWindow();
   4200 
   4201         BufferedWriter out = null;
   4202 
   4203         // Any uncaught exception will crash the system process
   4204         try {
   4205             OutputStream clientStream = client.getOutputStream();
   4206             out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
   4207 
   4208             if(focusedWindow != null) {
   4209                 out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
   4210                 out.write(' ');
   4211                 out.append(focusedWindow.mAttrs.getTitle());
   4212             }
   4213             out.write('\n');
   4214             out.flush();
   4215         } catch (Exception e) {
   4216             result = false;
   4217         } finally {
   4218             if (out != null) {
   4219                 try {
   4220                     out.close();
   4221                 } catch (IOException e) {
   4222                     result = false;
   4223                 }
   4224             }
   4225         }
   4226 
   4227         return result;
   4228     }
   4229 
   4230     /**
   4231      * Sends a command to a target window. The result of the command, if any, will be
   4232      * written in the output stream of the specified socket.
   4233      *
   4234      * The parameters must follow this syntax:
   4235      * windowHashcode extra
   4236      *
   4237      * Where XX is the length in characeters of the windowTitle.
   4238      *
   4239      * The first parameter is the target window. The window with the specified hashcode
   4240      * will be the target. If no target can be found, nothing happens. The extra parameters
   4241      * will be delivered to the target window and as parameters to the command itself.
   4242      *
   4243      * @param client The remote client to sent the result, if any, to.
   4244      * @param command The command to execute.
   4245      * @param parameters The command parameters.
   4246      *
   4247      * @return True if the command was successfully delivered, false otherwise. This does
   4248      *         not indicate whether the command itself was successful.
   4249      */
   4250     boolean viewServerWindowCommand(Socket client, String command, String parameters) {
   4251         if (isSystemSecure()) {
   4252             return false;
   4253         }
   4254 
   4255         boolean success = true;
   4256         Parcel data = null;
   4257         Parcel reply = null;
   4258 
   4259         BufferedWriter out = null;
   4260 
   4261         // Any uncaught exception will crash the system process
   4262         try {
   4263             // Find the hashcode of the window
   4264             int index = parameters.indexOf(' ');
   4265             if (index == -1) {
   4266                 index = parameters.length();
   4267             }
   4268             final String code = parameters.substring(0, index);
   4269             int hashCode = (int) Long.parseLong(code, 16);
   4270 
   4271             // Extract the command's parameter after the window description
   4272             if (index < parameters.length()) {
   4273                 parameters = parameters.substring(index + 1);
   4274             } else {
   4275                 parameters = "";
   4276             }
   4277 
   4278             final WindowState window = findWindow(hashCode);
   4279             if (window == null) {
   4280                 return false;
   4281             }
   4282 
   4283             data = Parcel.obtain();
   4284             data.writeInterfaceToken("android.view.IWindow");
   4285             data.writeString(command);
   4286             data.writeString(parameters);
   4287             data.writeInt(1);
   4288             ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
   4289 
   4290             reply = Parcel.obtain();
   4291 
   4292             final IBinder binder = window.mClient.asBinder();
   4293             // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
   4294             binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
   4295 
   4296             reply.readException();
   4297 
   4298             if (!client.isOutputShutdown()) {
   4299                 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
   4300                 out.write("DONE\n");
   4301                 out.flush();
   4302             }
   4303 
   4304         } catch (Exception e) {
   4305             Slog.w(TAG_WM, "Could not send command " + command + " with parameters " + parameters, e);
   4306             success = false;
   4307         } finally {
   4308             if (data != null) {
   4309                 data.recycle();
   4310             }
   4311             if (reply != null) {
   4312                 reply.recycle();
   4313             }
   4314             if (out != null) {
   4315                 try {
   4316                     out.close();
   4317                 } catch (IOException e) {
   4318 
   4319                 }
   4320             }
   4321         }
   4322 
   4323         return success;
   4324     }
   4325 
   4326     public void addWindowChangeListener(WindowChangeListener listener) {
   4327         synchronized(mWindowMap) {
   4328             mWindowChangeListeners.add(listener);
   4329         }
   4330     }
   4331 
   4332     public void removeWindowChangeListener(WindowChangeListener listener) {
   4333         synchronized(mWindowMap) {
   4334             mWindowChangeListeners.remove(listener);
   4335         }
   4336     }
   4337 
   4338     private void notifyWindowsChanged() {
   4339         WindowChangeListener[] windowChangeListeners;
   4340         synchronized(mWindowMap) {
   4341             if(mWindowChangeListeners.isEmpty()) {
   4342                 return;
   4343             }
   4344             windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
   4345             windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
   4346         }
   4347         int N = windowChangeListeners.length;
   4348         for(int i = 0; i < N; i++) {
   4349             windowChangeListeners[i].windowsChanged();
   4350         }
   4351     }
   4352 
   4353     private void notifyFocusChanged() {
   4354         WindowChangeListener[] windowChangeListeners;
   4355         synchronized(mWindowMap) {
   4356             if(mWindowChangeListeners.isEmpty()) {
   4357                 return;
   4358             }
   4359             windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
   4360             windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
   4361         }
   4362         int N = windowChangeListeners.length;
   4363         for(int i = 0; i < N; i++) {
   4364             windowChangeListeners[i].focusChanged();
   4365         }
   4366     }
   4367 
   4368     private WindowState findWindow(int hashCode) {
   4369         if (hashCode == -1) {
   4370             // TODO(multidisplay): Extend to multiple displays.
   4371             return getFocusedWindow();
   4372         }
   4373 
   4374         synchronized (mWindowMap) {
   4375             return mRoot.getWindow((w) -> System.identityHashCode(w) == hashCode);
   4376         }
   4377     }
   4378 
   4379     /**
   4380      * Instruct the Activity Manager to fetch and update the current display's configuration and
   4381      * broadcast them to config-changed listeners if appropriate.
   4382      * NOTE: Can't be called with the window manager lock held since it call into activity manager.
   4383      */
   4384     void sendNewConfiguration(int displayId) {
   4385         try {
   4386             final boolean configUpdated = mActivityManager.updateDisplayOverrideConfiguration(
   4387                     null /* values */, displayId);
   4388             if (!configUpdated) {
   4389                 // Something changed (E.g. device rotation), but no configuration update is needed.
   4390                 // E.g. changing device rotation by 180 degrees. Go ahead and perform surface
   4391                 // placement to unfreeze the display since we froze it when the rotation was updated
   4392                 // in DisplayContent#updateRotationUnchecked.
   4393                 synchronized (mWindowMap) {
   4394                     if (mWaitingForConfig) {
   4395                         mWaitingForConfig = false;
   4396                         mLastFinishedFreezeSource = "config-unchanged";
   4397                         final DisplayContent dc = mRoot.getDisplayContent(displayId);
   4398                         if (dc != null) {
   4399                             dc.setLayoutNeeded();
   4400                         }
   4401                         mWindowPlacerLocked.performSurfacePlacement();
   4402                     }
   4403                 }
   4404             }
   4405         } catch (RemoteException e) {
   4406         }
   4407     }
   4408 
   4409     public Configuration computeNewConfiguration(int displayId) {
   4410         synchronized (mWindowMap) {
   4411             return computeNewConfigurationLocked(displayId);
   4412         }
   4413     }
   4414 
   4415     private Configuration computeNewConfigurationLocked(int displayId) {
   4416         if (!mDisplayReady) {
   4417             return null;
   4418         }
   4419         final Configuration config = new Configuration();
   4420         final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   4421         displayContent.computeScreenConfiguration(config);
   4422         return config;
   4423     }
   4424 
   4425     void notifyHardKeyboardStatusChange() {
   4426         final boolean available;
   4427         final WindowManagerInternal.OnHardKeyboardStatusChangeListener listener;
   4428         synchronized (mWindowMap) {
   4429             listener = mHardKeyboardStatusChangeListener;
   4430             available = mHardKeyboardAvailable;
   4431         }
   4432         if (listener != null) {
   4433             listener.onHardKeyboardStatusChange(available);
   4434         }
   4435     }
   4436 
   4437     // -------------------------------------------------------------
   4438     // Input Events and Focus Management
   4439     // -------------------------------------------------------------
   4440 
   4441     final InputMonitor mInputMonitor = new InputMonitor(this);
   4442     private boolean mEventDispatchingEnabled;
   4443 
   4444     @Override
   4445     public void setEventDispatching(boolean enabled) {
   4446         if (!checkCallingPermission(MANAGE_APP_TOKENS, "setEventDispatching()")) {
   4447             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
   4448         }
   4449 
   4450         synchronized (mWindowMap) {
   4451             mEventDispatchingEnabled = enabled;
   4452             if (mDisplayEnabled) {
   4453                 mInputMonitor.setEventDispatchingLw(enabled);
   4454             }
   4455         }
   4456     }
   4457 
   4458     private WindowState getFocusedWindow() {
   4459         synchronized (mWindowMap) {
   4460             return getFocusedWindowLocked();
   4461         }
   4462     }
   4463 
   4464     private WindowState getFocusedWindowLocked() {
   4465         return mCurrentFocus;
   4466     }
   4467 
   4468     TaskStack getImeFocusStackLocked() {
   4469         // Don't use mCurrentFocus.getStack() because it returns home stack for system windows.
   4470         // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE
   4471         // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved
   4472         // to make room for IME, but the window is not the focused window that's taking input.
   4473         return (mFocusedApp != null && mFocusedApp.getTask() != null) ?
   4474                 mFocusedApp.getTask().mStack : null;
   4475     }
   4476 
   4477     public boolean detectSafeMode() {
   4478         if (!mInputMonitor.waitForInputDevicesReady(
   4479                 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
   4480             Slog.w(TAG_WM, "Devices still not ready after waiting "
   4481                    + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
   4482                    + " milliseconds before attempting to detect safe mode.");
   4483         }
   4484 
   4485         if (Settings.Global.getInt(
   4486                 mContext.getContentResolver(), Settings.Global.SAFE_BOOT_DISALLOWED, 0) != 0) {
   4487             return false;
   4488         }
   4489 
   4490         int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
   4491                 KeyEvent.KEYCODE_MENU);
   4492         int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
   4493         int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
   4494                 KeyEvent.KEYCODE_DPAD_CENTER);
   4495         int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
   4496                 InputManagerService.BTN_MOUSE);
   4497         int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
   4498                 KeyEvent.KEYCODE_VOLUME_DOWN);
   4499         mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
   4500                 || volumeDownState > 0;
   4501         try {
   4502             if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0
   4503                     || SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) != 0) {
   4504                 mSafeMode = true;
   4505                 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
   4506             }
   4507         } catch (IllegalArgumentException e) {
   4508         }
   4509         if (mSafeMode) {
   4510             Log.i(TAG_WM, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
   4511                     + " dpad=" + dpadState + " trackball=" + trackballState + ")");
   4512             // May already be set if (for instance) this process has crashed
   4513             if (SystemProperties.getInt(ShutdownThread.RO_SAFEMODE_PROPERTY, 0) == 0) {
   4514                 SystemProperties.set(ShutdownThread.RO_SAFEMODE_PROPERTY, "1");
   4515             }
   4516         } else {
   4517             Log.i(TAG_WM, "SAFE MODE not enabled");
   4518         }
   4519         mPolicy.setSafeMode(mSafeMode);
   4520         return mSafeMode;
   4521     }
   4522 
   4523     public void displayReady() {
   4524         final int displayCount = mRoot.mChildren.size();
   4525         for (int i = 0; i < displayCount; ++i) {
   4526             final DisplayContent display = mRoot.mChildren.get(i);
   4527             displayReady(display.getDisplayId());
   4528         }
   4529 
   4530 
   4531         synchronized(mWindowMap) {
   4532             final DisplayContent displayContent = getDefaultDisplayContentLocked();
   4533             if (mMaxUiWidth > 0) {
   4534                 displayContent.setMaxUiWidth(mMaxUiWidth);
   4535             }
   4536             readForcedDisplayPropertiesLocked(displayContent);
   4537             mDisplayReady = true;
   4538         }
   4539 
   4540         try {
   4541             mActivityManager.updateConfiguration(null);
   4542         } catch (RemoteException e) {
   4543         }
   4544 
   4545         synchronized(mWindowMap) {
   4546             mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
   4547                     PackageManager.FEATURE_TOUCHSCREEN);
   4548             getDefaultDisplayContentLocked().configureDisplayPolicy();
   4549         }
   4550 
   4551         try {
   4552             mActivityManager.updateConfiguration(null);
   4553         } catch (RemoteException e) {
   4554         }
   4555 
   4556         updateCircularDisplayMaskIfNeeded();
   4557     }
   4558 
   4559     private void displayReady(int displayId) {
   4560         synchronized(mWindowMap) {
   4561             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   4562             if (displayContent != null) {
   4563                 mAnimator.addDisplayLocked(displayId);
   4564                 displayContent.initializeDisplayBaseInfo();
   4565                 reconfigureDisplayLocked(displayContent);
   4566             }
   4567         }
   4568     }
   4569 
   4570     public void systemReady() {
   4571         mPolicy.systemReady();
   4572         mTaskSnapshotController.systemReady();
   4573         mHasWideColorGamutSupport = queryWideColorGamutSupport();
   4574     }
   4575 
   4576     private static boolean queryWideColorGamutSupport() {
   4577         try {
   4578             ISurfaceFlingerConfigs surfaceFlinger = ISurfaceFlingerConfigs.getService();
   4579             OptionalBool hasWideColor = surfaceFlinger.hasWideColorDisplay();
   4580             if (hasWideColor != null) {
   4581                 return hasWideColor.value;
   4582             }
   4583         } catch (RemoteException e) {
   4584             // Ignore, we're in big trouble if we can't talk to SurfaceFlinger's config store
   4585         }
   4586         return false;
   4587     }
   4588 
   4589     // -------------------------------------------------------------
   4590     // Async Handler
   4591     // -------------------------------------------------------------
   4592 
   4593     final class H extends android.os.Handler {
   4594         public static final int REPORT_FOCUS_CHANGE = 2;
   4595         public static final int REPORT_LOSING_FOCUS = 3;
   4596         public static final int WINDOW_FREEZE_TIMEOUT = 11;
   4597 
   4598         public static final int APP_TRANSITION_TIMEOUT = 13;
   4599         public static final int PERSIST_ANIMATION_SCALE = 14;
   4600         public static final int FORCE_GC = 15;
   4601         public static final int ENABLE_SCREEN = 16;
   4602         public static final int APP_FREEZE_TIMEOUT = 17;
   4603         public static final int SEND_NEW_CONFIGURATION = 18;
   4604         public static final int REPORT_WINDOWS_CHANGE = 19;
   4605 
   4606         public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
   4607         public static final int BOOT_TIMEOUT = 23;
   4608         public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
   4609         public static final int SHOW_STRICT_MODE_VIOLATION = 25;
   4610         public static final int DO_ANIMATION_CALLBACK = 26;
   4611 
   4612         public static final int CLIENT_FREEZE_TIMEOUT = 30;
   4613         public static final int NOTIFY_ACTIVITY_DRAWN = 32;
   4614 
   4615         public static final int ALL_WINDOWS_DRAWN = 33;
   4616 
   4617         public static final int NEW_ANIMATOR_SCALE = 34;
   4618 
   4619         public static final int SHOW_CIRCULAR_DISPLAY_MASK = 35;
   4620         public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36;
   4621 
   4622         public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37;
   4623         public static final int RESET_ANR_MESSAGE = 38;
   4624         public static final int WALLPAPER_DRAW_PENDING_TIMEOUT = 39;
   4625 
   4626         public static final int UPDATE_DOCKED_STACK_DIVIDER = 41;
   4627 
   4628         public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;
   4629 
   4630         public static final int NOTIFY_APP_TRANSITION_STARTING = 47;
   4631         public static final int NOTIFY_APP_TRANSITION_CANCELLED = 48;
   4632         public static final int NOTIFY_APP_TRANSITION_FINISHED = 49;
   4633         public static final int UPDATE_ANIMATION_SCALE = 51;
   4634         public static final int WINDOW_HIDE_TIMEOUT = 52;
   4635         public static final int NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED = 53;
   4636         public static final int SEAMLESS_ROTATION_TIMEOUT = 54;
   4637         public static final int RESTORE_POINTER_ICON = 55;
   4638         public static final int NOTIFY_KEYGUARD_FLAGS_CHANGED = 56;
   4639         public static final int NOTIFY_KEYGUARD_TRUSTED_CHANGED = 57;
   4640         public static final int SET_HAS_OVERLAY_UI = 58;
   4641         public static final int SET_RUNNING_REMOTE_ANIMATION = 59;
   4642         public static final int ANIMATION_FAILSAFE = 60;
   4643         public static final int RECOMPUTE_FOCUS = 61;
   4644 
   4645         /**
   4646          * Used to denote that an integer field in a message will not be used.
   4647          */
   4648         public static final int UNUSED = 0;
   4649 
   4650         @Override
   4651         public void handleMessage(Message msg) {
   4652             if (DEBUG_WINDOW_TRACE) {
   4653                 Slog.v(TAG_WM, "handleMessage: entry what=" + msg.what);
   4654             }
   4655             switch (msg.what) {
   4656                 case REPORT_FOCUS_CHANGE: {
   4657                     WindowState lastFocus;
   4658                     WindowState newFocus;
   4659 
   4660                     AccessibilityController accessibilityController = null;
   4661 
   4662                     synchronized(mWindowMap) {
   4663                         // TODO(multidisplay): Accessibility supported only of default desiplay.
   4664                         if (mAccessibilityController != null && getDefaultDisplayContentLocked()
   4665                                 .getDisplayId() == DEFAULT_DISPLAY) {
   4666                             accessibilityController = mAccessibilityController;
   4667                         }
   4668 
   4669                         lastFocus = mLastFocus;
   4670                         newFocus = mCurrentFocus;
   4671                         if (lastFocus == newFocus) {
   4672                             // Focus is not changing, so nothing to do.
   4673                             return;
   4674                         }
   4675                         mLastFocus = newFocus;
   4676                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus +
   4677                                 " to " + newFocus);
   4678                         if (newFocus != null && lastFocus != null
   4679                                 && !newFocus.isDisplayedLw()) {
   4680                             //Slog.i(TAG_WM, "Delaying loss of focus...");
   4681                             mLosingFocus.add(lastFocus);
   4682                             lastFocus = null;
   4683                         }
   4684                     }
   4685 
   4686                     // First notify the accessibility manager for the change so it has
   4687                     // the windows before the newly focused one starts firing eventgs.
   4688                     if (accessibilityController != null) {
   4689                         accessibilityController.onWindowFocusChangedNotLocked();
   4690                     }
   4691 
   4692                     //System.out.println("Changing focus from " + lastFocus
   4693                     //                   + " to " + newFocus);
   4694                     if (newFocus != null) {
   4695                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Gaining focus: " + newFocus);
   4696                         newFocus.reportFocusChangedSerialized(true, mInTouchMode);
   4697                         notifyFocusChanged();
   4698                     }
   4699 
   4700                     if (lastFocus != null) {
   4701                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing focus: " + lastFocus);
   4702                         lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
   4703                     }
   4704                 } break;
   4705 
   4706                 case REPORT_LOSING_FOCUS: {
   4707                     ArrayList<WindowState> losers;
   4708 
   4709                     synchronized(mWindowMap) {
   4710                         losers = mLosingFocus;
   4711                         mLosingFocus = new ArrayList<WindowState>();
   4712                     }
   4713 
   4714                     final int N = losers.size();
   4715                     for (int i=0; i<N; i++) {
   4716                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing delayed focus: " +
   4717                                 losers.get(i));
   4718                         losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
   4719                     }
   4720                 } break;
   4721 
   4722                 case WINDOW_FREEZE_TIMEOUT: {
   4723                     // TODO(multidisplay): Can non-default displays rotate?
   4724                     synchronized (mWindowMap) {
   4725                         getDefaultDisplayContentLocked().onWindowFreezeTimeout();
   4726                     }
   4727                     break;
   4728                 }
   4729 
   4730                 case APP_TRANSITION_TIMEOUT: {
   4731                     synchronized (mWindowMap) {
   4732                         if (mAppTransition.isTransitionSet() || !mOpeningApps.isEmpty()
   4733                                     || !mClosingApps.isEmpty()) {
   4734                             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
   4735                                     + " isTransitionSet()=" + mAppTransition.isTransitionSet()
   4736                                     + " mOpeningApps.size()=" + mOpeningApps.size()
   4737                                     + " mClosingApps.size()=" + mClosingApps.size());
   4738                             mAppTransition.setTimeout();
   4739                             mWindowPlacerLocked.performSurfacePlacement();
   4740                         }
   4741                     }
   4742                     break;
   4743                 }
   4744 
   4745                 case PERSIST_ANIMATION_SCALE: {
   4746                     Settings.Global.putFloat(mContext.getContentResolver(),
   4747                             Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
   4748                     Settings.Global.putFloat(mContext.getContentResolver(),
   4749                             Settings.Global.TRANSITION_ANIMATION_SCALE,
   4750                             mTransitionAnimationScaleSetting);
   4751                     Settings.Global.putFloat(mContext.getContentResolver(),
   4752                             Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting);
   4753                     break;
   4754                 }
   4755 
   4756                 case UPDATE_ANIMATION_SCALE: {
   4757                     @UpdateAnimationScaleMode
   4758                     final int mode = msg.arg1;
   4759                     switch (mode) {
   4760                         case WINDOW_ANIMATION_SCALE: {
   4761                             mWindowAnimationScaleSetting = Settings.Global.getFloat(
   4762                                     mContext.getContentResolver(),
   4763                                     Settings.Global.WINDOW_ANIMATION_SCALE,
   4764                                     mWindowAnimationScaleSetting);
   4765                             break;
   4766                         }
   4767                         case TRANSITION_ANIMATION_SCALE: {
   4768                             mTransitionAnimationScaleSetting = Settings.Global.getFloat(
   4769                                     mContext.getContentResolver(),
   4770                                     Settings.Global.TRANSITION_ANIMATION_SCALE,
   4771                                     mTransitionAnimationScaleSetting);
   4772                             break;
   4773                         }
   4774                         case ANIMATION_DURATION_SCALE: {
   4775                             mAnimatorDurationScaleSetting = Settings.Global.getFloat(
   4776                                     mContext.getContentResolver(),
   4777                                     Settings.Global.ANIMATOR_DURATION_SCALE,
   4778                                     mAnimatorDurationScaleSetting);
   4779                             dispatchNewAnimatorScaleLocked(null);
   4780                             break;
   4781                         }
   4782                     }
   4783                     break;
   4784                 }
   4785 
   4786                 case FORCE_GC: {
   4787                     synchronized (mWindowMap) {
   4788                         // Since we're holding both mWindowMap and mAnimator we don't need to
   4789                         // hold mAnimator.mLayoutToAnim.
   4790                         if (mAnimator.isAnimating() || mAnimator.isAnimationScheduled()) {
   4791                             // If we are animating, don't do the gc now but
   4792                             // delay a bit so we don't interrupt the animation.
   4793                             sendEmptyMessageDelayed(H.FORCE_GC, 2000);
   4794                             return;
   4795                         }
   4796                         // If we are currently rotating the display, it will
   4797                         // schedule a new message when done.
   4798                         if (mDisplayFrozen) {
   4799                             return;
   4800                         }
   4801                     }
   4802                     Runtime.getRuntime().gc();
   4803                     break;
   4804                 }
   4805 
   4806                 case ENABLE_SCREEN: {
   4807                     performEnableScreen();
   4808                     break;
   4809                 }
   4810 
   4811                 case APP_FREEZE_TIMEOUT: {
   4812                     synchronized (mWindowMap) {
   4813                         Slog.w(TAG_WM, "App freeze timeout expired.");
   4814                         mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT;
   4815                         for (int i = mAppFreezeListeners.size() - 1; i >=0 ; --i) {
   4816                             mAppFreezeListeners.get(i).onAppFreezeTimeout();
   4817                         }
   4818                     }
   4819                     break;
   4820                 }
   4821 
   4822                 case CLIENT_FREEZE_TIMEOUT: {
   4823                     synchronized (mWindowMap) {
   4824                         if (mClientFreezingScreen) {
   4825                             mClientFreezingScreen = false;
   4826                             mLastFinishedFreezeSource = "client-timeout";
   4827                             stopFreezingDisplayLocked();
   4828                         }
   4829                     }
   4830                     break;
   4831                 }
   4832 
   4833                 case SEND_NEW_CONFIGURATION: {
   4834                     removeMessages(SEND_NEW_CONFIGURATION, msg.obj);
   4835                     final int displayId = (Integer) msg.obj;
   4836                     if (mRoot.getDisplayContent(displayId) != null) {
   4837                         sendNewConfiguration(displayId);
   4838                     } else {
   4839                         // Message could come after display has already been removed.
   4840                         if (DEBUG_CONFIGURATION) {
   4841                             Slog.w(TAG, "Trying to send configuration to non-existing displayId="
   4842                                     + displayId);
   4843                         }
   4844                     }
   4845                     break;
   4846                 }
   4847 
   4848                 case REPORT_WINDOWS_CHANGE: {
   4849                     if (mWindowsChanged) {
   4850                         synchronized (mWindowMap) {
   4851                             mWindowsChanged = false;
   4852                         }
   4853                         notifyWindowsChanged();
   4854                     }
   4855                     break;
   4856                 }
   4857 
   4858                 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
   4859                     notifyHardKeyboardStatusChange();
   4860                     break;
   4861                 }
   4862 
   4863                 case BOOT_TIMEOUT: {
   4864                     performBootTimeout();
   4865                     break;
   4866                 }
   4867 
   4868                 case WAITING_FOR_DRAWN_TIMEOUT: {
   4869                     Runnable callback = null;
   4870                     synchronized (mWindowMap) {
   4871                         Slog.w(TAG_WM, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn);
   4872                         mWaitingForDrawn.clear();
   4873                         callback = mWaitingForDrawnCallback;
   4874                         mWaitingForDrawnCallback = null;
   4875                     }
   4876                     if (callback != null) {
   4877                         callback.run();
   4878                     }
   4879                     break;
   4880                 }
   4881 
   4882                 case SHOW_STRICT_MODE_VIOLATION: {
   4883                     showStrictModeViolation(msg.arg1, msg.arg2);
   4884                     break;
   4885                 }
   4886 
   4887                 case SHOW_CIRCULAR_DISPLAY_MASK: {
   4888                     showCircularMask(msg.arg1 == 1);
   4889                     break;
   4890                 }
   4891 
   4892                 case SHOW_EMULATOR_DISPLAY_OVERLAY: {
   4893                     showEmulatorDisplayOverlay();
   4894                     break;
   4895                 }
   4896 
   4897                 case DO_ANIMATION_CALLBACK: {
   4898                     try {
   4899                         ((IRemoteCallback)msg.obj).sendResult(null);
   4900                     } catch (RemoteException e) {
   4901                     }
   4902                     break;
   4903                 }
   4904 
   4905                 case NOTIFY_ACTIVITY_DRAWN:
   4906                     try {
   4907                         mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
   4908                     } catch (RemoteException e) {
   4909                     }
   4910                     break;
   4911                 case ALL_WINDOWS_DRAWN: {
   4912                     Runnable callback;
   4913                     synchronized (mWindowMap) {
   4914                         callback = mWaitingForDrawnCallback;
   4915                         mWaitingForDrawnCallback = null;
   4916                     }
   4917                     if (callback != null) {
   4918                         callback.run();
   4919                     }
   4920                     break;
   4921                 }
   4922                 case NEW_ANIMATOR_SCALE: {
   4923                     float scale = getCurrentAnimatorScale();
   4924                     ValueAnimator.setDurationScale(scale);
   4925                     Session session = (Session)msg.obj;
   4926                     if (session != null) {
   4927                         try {
   4928                             session.mCallback.onAnimatorScaleChanged(scale);
   4929                         } catch (RemoteException e) {
   4930                         }
   4931                     } else {
   4932                         ArrayList<IWindowSessionCallback> callbacks
   4933                                 = new ArrayList<IWindowSessionCallback>();
   4934                         synchronized (mWindowMap) {
   4935                             for (int i=0; i<mSessions.size(); i++) {
   4936                                 callbacks.add(mSessions.valueAt(i).mCallback);
   4937                             }
   4938 
   4939                         }
   4940                         for (int i=0; i<callbacks.size(); i++) {
   4941                             try {
   4942                                 callbacks.get(i).onAnimatorScaleChanged(scale);
   4943                             } catch (RemoteException e) {
   4944                             }
   4945                         }
   4946                     }
   4947                 }
   4948                 break;
   4949                 case CHECK_IF_BOOT_ANIMATION_FINISHED: {
   4950                     final boolean bootAnimationComplete;
   4951                     synchronized (mWindowMap) {
   4952                         if (DEBUG_BOOT) Slog.i(TAG_WM, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
   4953                         bootAnimationComplete = checkBootAnimationCompleteLocked();
   4954                     }
   4955                     if (bootAnimationComplete) {
   4956                         performEnableScreen();
   4957                     }
   4958                 }
   4959                 break;
   4960                 case RESET_ANR_MESSAGE: {
   4961                     synchronized (mWindowMap) {
   4962                         mLastANRState = null;
   4963                     }
   4964                     mAmInternal.clearSavedANRState();
   4965                 }
   4966                 break;
   4967                 case WALLPAPER_DRAW_PENDING_TIMEOUT: {
   4968                     synchronized (mWindowMap) {
   4969                         if (mRoot.mWallpaperController.processWallpaperDrawPendingTimeout()) {
   4970                             mWindowPlacerLocked.performSurfacePlacement();
   4971                         }
   4972                     }
   4973                 }
   4974                 break;
   4975                 case UPDATE_DOCKED_STACK_DIVIDER: {
   4976                     synchronized (mWindowMap) {
   4977                         final DisplayContent displayContent = getDefaultDisplayContentLocked();
   4978                         displayContent.getDockedDividerController().reevaluateVisibility(false);
   4979                         displayContent.adjustForImeIfNeeded();
   4980                     }
   4981                 }
   4982                 break;
   4983                 case WINDOW_REPLACEMENT_TIMEOUT: {
   4984                     synchronized (mWindowMap) {
   4985                         for (int i = mWindowReplacementTimeouts.size() - 1; i >= 0; i--) {
   4986                             final AppWindowToken token = mWindowReplacementTimeouts.get(i);
   4987                             token.onWindowReplacementTimeout();
   4988                         }
   4989                         mWindowReplacementTimeouts.clear();
   4990                     }
   4991                 }
   4992                 break;
   4993                 case NOTIFY_APP_TRANSITION_STARTING: {
   4994                     mAmInternal.notifyAppTransitionStarting((SparseIntArray) msg.obj,
   4995                             msg.getWhen());
   4996                 }
   4997                 break;
   4998                 case NOTIFY_APP_TRANSITION_CANCELLED: {
   4999                     mAmInternal.notifyAppTransitionCancelled();
   5000                 }
   5001                 break;
   5002                 case NOTIFY_APP_TRANSITION_FINISHED: {
   5003                     mAmInternal.notifyAppTransitionFinished();
   5004                 }
   5005                 break;
   5006                 case WINDOW_HIDE_TIMEOUT: {
   5007                     final WindowState window = (WindowState) msg.obj;
   5008                     synchronized(mWindowMap) {
   5009                         // TODO: This is all about fixing b/21693547
   5010                         // where partially initialized Toasts get stuck
   5011                         // around and keep the screen on. We'd like
   5012                         // to just remove the toast...but this can cause clients
   5013                         // who miss the timeout due to normal circumstances (e.g.
   5014                         // running under debugger) to crash (b/29105388). The windows will
   5015                         // eventually be removed when the client process finishes.
   5016                         // The best we can do for now is remove the FLAG_KEEP_SCREEN_ON
   5017                         // and prevent the symptoms of b/21693547. Since apps don't
   5018                         // support windows being removed under them we hide the window
   5019                         // and it will be removed when the app dies.
   5020                         window.mAttrs.flags &= ~FLAG_KEEP_SCREEN_ON;
   5021                         window.hidePermanentlyLw();
   5022                         window.setDisplayLayoutNeeded();
   5023                         mWindowPlacerLocked.performSurfacePlacement();
   5024                     }
   5025                 }
   5026                 break;
   5027                 case NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED: {
   5028                     mAmInternal.notifyDockedStackMinimizedChanged(msg.arg1 == 1);
   5029                 }
   5030                 break;
   5031                 case RESTORE_POINTER_ICON: {
   5032                     synchronized (mWindowMap) {
   5033                         restorePointerIconLocked((DisplayContent)msg.obj, msg.arg1, msg.arg2);
   5034                     }
   5035                 }
   5036                 break;
   5037                 case SEAMLESS_ROTATION_TIMEOUT: {
   5038                     // Rotation only supported on primary display.
   5039                     // TODO(multi-display)
   5040                     synchronized(mWindowMap) {
   5041                         final DisplayContent dc = getDefaultDisplayContentLocked();
   5042                         dc.onSeamlessRotationTimeout();
   5043                     }
   5044                 }
   5045                 break;
   5046                 case NOTIFY_KEYGUARD_FLAGS_CHANGED: {
   5047                     mAmInternal.notifyKeyguardFlagsChanged((Runnable) msg.obj);
   5048                 }
   5049                 break;
   5050                 case NOTIFY_KEYGUARD_TRUSTED_CHANGED: {
   5051                     mAmInternal.notifyKeyguardTrustedChanged();
   5052                 }
   5053                 break;
   5054                 case SET_HAS_OVERLAY_UI: {
   5055                     mAmInternal.setHasOverlayUi(msg.arg1, msg.arg2 == 1);
   5056                 }
   5057                 break;
   5058                 case SET_RUNNING_REMOTE_ANIMATION: {
   5059                     mAmInternal.setRunningRemoteAnimation(msg.arg1, msg.arg2 == 1);
   5060                 }
   5061                 break;
   5062                 case ANIMATION_FAILSAFE: {
   5063                     synchronized (mWindowMap) {
   5064                         if (mRecentsAnimationController != null) {
   5065                             mRecentsAnimationController.scheduleFailsafe();
   5066                         }
   5067                     }
   5068                 }
   5069                 break;
   5070                 case RECOMPUTE_FOCUS: {
   5071                     synchronized (mWindowMap) {
   5072                         updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
   5073                                 true /* updateInputWindows */);
   5074                     }
   5075                 }
   5076                 break;
   5077             }
   5078             if (DEBUG_WINDOW_TRACE) {
   5079                 Slog.v(TAG_WM, "handleMessage: exit");
   5080             }
   5081         }
   5082     }
   5083 
   5084     void destroyPreservedSurfaceLocked() {
   5085         for (int i = mDestroyPreservedSurface.size() - 1; i >= 0 ; i--) {
   5086             final WindowState w = mDestroyPreservedSurface.get(i);
   5087             w.mWinAnimator.destroyPreservedSurfaceLocked();
   5088         }
   5089         mDestroyPreservedSurface.clear();
   5090     }
   5091 
   5092     // -------------------------------------------------------------
   5093     // IWindowManager API
   5094     // -------------------------------------------------------------
   5095 
   5096     @Override
   5097     public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,
   5098             IInputContext inputContext) {
   5099         if (client == null) throw new IllegalArgumentException("null client");
   5100         if (inputContext == null) throw new IllegalArgumentException("null inputContext");
   5101         Session session = new Session(this, callback, client, inputContext);
   5102         return session;
   5103     }
   5104 
   5105     @Override
   5106     public boolean inputMethodClientHasFocus(IInputMethodClient client) {
   5107         synchronized (mWindowMap) {
   5108             // TODO: multi-display
   5109             if (getDefaultDisplayContentLocked().inputMethodClientHasFocus(client)) {
   5110                 return true;
   5111             }
   5112 
   5113             // Okay, how about this...  what is the current focus?
   5114             // It seems in some cases we may not have moved the IM
   5115             // target window, such as when it was in a pop-up window,
   5116             // so let's also look at the current focus.  (An example:
   5117             // go to Gmail, start searching so the keyboard goes up,
   5118             // press home.  Sometimes the IME won't go down.)
   5119             // Would be nice to fix this more correctly, but it's
   5120             // way at the end of a release, and this should be good enough.
   5121             if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
   5122                     && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
   5123                 return true;
   5124             }
   5125         }
   5126         return false;
   5127     }
   5128 
   5129     @Override
   5130     public void getInitialDisplaySize(int displayId, Point size) {
   5131         synchronized (mWindowMap) {
   5132             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5133             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
   5134                 size.x = displayContent.mInitialDisplayWidth;
   5135                 size.y = displayContent.mInitialDisplayHeight;
   5136             }
   5137         }
   5138     }
   5139 
   5140     @Override
   5141     public void getBaseDisplaySize(int displayId, Point size) {
   5142         synchronized (mWindowMap) {
   5143             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5144             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
   5145                 size.x = displayContent.mBaseDisplayWidth;
   5146                 size.y = displayContent.mBaseDisplayHeight;
   5147             }
   5148         }
   5149     }
   5150 
   5151     @Override
   5152     public void setForcedDisplaySize(int displayId, int width, int height) {
   5153         if (mContext.checkCallingOrSelfPermission(
   5154                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
   5155                 PackageManager.PERMISSION_GRANTED) {
   5156             throw new SecurityException("Must hold permission " +
   5157                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
   5158         }
   5159         if (displayId != DEFAULT_DISPLAY) {
   5160             throw new IllegalArgumentException("Can only set the default display");
   5161         }
   5162         final long ident = Binder.clearCallingIdentity();
   5163         try {
   5164             synchronized(mWindowMap) {
   5165                 // Set some sort of reasonable bounds on the size of the display that we
   5166                 // will try to emulate.
   5167                 final int MIN_WIDTH = 200;
   5168                 final int MIN_HEIGHT = 200;
   5169                 final int MAX_SCALE = 2;
   5170                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5171                 if (displayContent != null) {
   5172                     width = Math.min(Math.max(width, MIN_WIDTH),
   5173                             displayContent.mInitialDisplayWidth * MAX_SCALE);
   5174                     height = Math.min(Math.max(height, MIN_HEIGHT),
   5175                             displayContent.mInitialDisplayHeight * MAX_SCALE);
   5176                     setForcedDisplaySizeLocked(displayContent, width, height);
   5177                     Settings.Global.putString(mContext.getContentResolver(),
   5178                             Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
   5179                 }
   5180             }
   5181         } finally {
   5182             Binder.restoreCallingIdentity(ident);
   5183         }
   5184     }
   5185 
   5186     @Override
   5187     public void setForcedDisplayScalingMode(int displayId, int mode) {
   5188         if (mContext.checkCallingOrSelfPermission(
   5189                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
   5190                 PackageManager.PERMISSION_GRANTED) {
   5191             throw new SecurityException("Must hold permission " +
   5192                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
   5193         }
   5194         if (displayId != DEFAULT_DISPLAY) {
   5195             throw new IllegalArgumentException("Can only set the default display");
   5196         }
   5197         final long ident = Binder.clearCallingIdentity();
   5198         try {
   5199             synchronized(mWindowMap) {
   5200                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5201                 if (displayContent != null) {
   5202                     if (mode < 0 || mode > 1) {
   5203                         mode = 0;
   5204                     }
   5205                     setForcedDisplayScalingModeLocked(displayContent, mode);
   5206                     Settings.Global.putInt(mContext.getContentResolver(),
   5207                             Settings.Global.DISPLAY_SCALING_FORCE, mode);
   5208                 }
   5209             }
   5210         } finally {
   5211             Binder.restoreCallingIdentity(ident);
   5212         }
   5213     }
   5214 
   5215     private void setForcedDisplayScalingModeLocked(DisplayContent displayContent, int mode) {
   5216         Slog.i(TAG_WM, "Using display scaling mode: " + (mode == 0 ? "auto" : "off"));
   5217         displayContent.mDisplayScalingDisabled = (mode != 0);
   5218         reconfigureDisplayLocked(displayContent);
   5219     }
   5220 
   5221     private void readForcedDisplayPropertiesLocked(final DisplayContent displayContent) {
   5222         // Display size.
   5223         String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
   5224                 Settings.Global.DISPLAY_SIZE_FORCED);
   5225         if (sizeStr == null || sizeStr.length() == 0) {
   5226             sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
   5227         }
   5228         if (sizeStr != null && sizeStr.length() > 0) {
   5229             final int pos = sizeStr.indexOf(',');
   5230             if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
   5231                 int width, height;
   5232                 try {
   5233                     width = Integer.parseInt(sizeStr.substring(0, pos));
   5234                     height = Integer.parseInt(sizeStr.substring(pos+1));
   5235                     if (displayContent.mBaseDisplayWidth != width
   5236                             || displayContent.mBaseDisplayHeight != height) {
   5237                         Slog.i(TAG_WM, "FORCED DISPLAY SIZE: " + width + "x" + height);
   5238                         displayContent.updateBaseDisplayMetrics(width, height,
   5239                                 displayContent.mBaseDisplayDensity);
   5240                     }
   5241                 } catch (NumberFormatException ex) {
   5242                 }
   5243             }
   5244         }
   5245 
   5246         // Display density.
   5247         final int density = getForcedDisplayDensityForUserLocked(mCurrentUserId);
   5248         if (density != 0) {
   5249             displayContent.mBaseDisplayDensity = density;
   5250         }
   5251 
   5252         // Display scaling mode.
   5253         int mode = Settings.Global.getInt(mContext.getContentResolver(),
   5254                 Settings.Global.DISPLAY_SCALING_FORCE, 0);
   5255         if (mode != 0) {
   5256             Slog.i(TAG_WM, "FORCED DISPLAY SCALING DISABLED");
   5257             displayContent.mDisplayScalingDisabled = true;
   5258         }
   5259     }
   5260 
   5261     // displayContent must not be null
   5262     private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
   5263         Slog.i(TAG_WM, "Using new display size: " + width + "x" + height);
   5264         displayContent.updateBaseDisplayMetrics(width, height, displayContent.mBaseDisplayDensity);
   5265         reconfigureDisplayLocked(displayContent);
   5266     }
   5267 
   5268     @Override
   5269     public void clearForcedDisplaySize(int displayId) {
   5270         if (mContext.checkCallingOrSelfPermission(
   5271                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
   5272                 PackageManager.PERMISSION_GRANTED) {
   5273             throw new SecurityException("Must hold permission " +
   5274                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
   5275         }
   5276         if (displayId != DEFAULT_DISPLAY) {
   5277             throw new IllegalArgumentException("Can only set the default display");
   5278         }
   5279         final long ident = Binder.clearCallingIdentity();
   5280         try {
   5281             synchronized(mWindowMap) {
   5282                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5283                 if (displayContent != null) {
   5284                     setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
   5285                             displayContent.mInitialDisplayHeight);
   5286                     Settings.Global.putString(mContext.getContentResolver(),
   5287                             Settings.Global.DISPLAY_SIZE_FORCED, "");
   5288                 }
   5289             }
   5290         } finally {
   5291             Binder.restoreCallingIdentity(ident);
   5292         }
   5293     }
   5294 
   5295     @Override
   5296     public int getInitialDisplayDensity(int displayId) {
   5297         synchronized (mWindowMap) {
   5298             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5299             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
   5300                 return displayContent.mInitialDisplayDensity;
   5301             }
   5302         }
   5303         return -1;
   5304     }
   5305 
   5306     @Override
   5307     public int getBaseDisplayDensity(int displayId) {
   5308         synchronized (mWindowMap) {
   5309             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5310             if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
   5311                 return displayContent.mBaseDisplayDensity;
   5312             }
   5313         }
   5314         return -1;
   5315     }
   5316 
   5317     @Override
   5318     public void setForcedDisplayDensityForUser(int displayId, int density, int userId) {
   5319         if (mContext.checkCallingOrSelfPermission(
   5320                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
   5321                 PackageManager.PERMISSION_GRANTED) {
   5322             throw new SecurityException("Must hold permission " +
   5323                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
   5324         }
   5325         if (displayId != DEFAULT_DISPLAY) {
   5326             throw new IllegalArgumentException("Can only set the default display");
   5327         }
   5328 
   5329         final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
   5330                 Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser",
   5331                 null);
   5332         final long ident = Binder.clearCallingIdentity();
   5333         try {
   5334             synchronized(mWindowMap) {
   5335                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5336                 if (displayContent != null && mCurrentUserId == targetUserId) {
   5337                     setForcedDisplayDensityLocked(displayContent, density);
   5338                 }
   5339                 Settings.Secure.putStringForUser(mContext.getContentResolver(),
   5340                         Settings.Secure.DISPLAY_DENSITY_FORCED,
   5341                         Integer.toString(density), targetUserId);
   5342             }
   5343         } finally {
   5344             Binder.restoreCallingIdentity(ident);
   5345         }
   5346     }
   5347 
   5348     @Override
   5349     public void clearForcedDisplayDensityForUser(int displayId, int userId) {
   5350         if (mContext.checkCallingOrSelfPermission(
   5351                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
   5352                 PackageManager.PERMISSION_GRANTED) {
   5353             throw new SecurityException("Must hold permission " +
   5354                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
   5355         }
   5356         if (displayId != DEFAULT_DISPLAY) {
   5357             throw new IllegalArgumentException("Can only set the default display");
   5358         }
   5359 
   5360         final int callingUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
   5361                 Binder.getCallingUid(), userId, false, true, "clearForcedDisplayDensityForUser",
   5362                 null);
   5363         final long ident = Binder.clearCallingIdentity();
   5364         try {
   5365             synchronized(mWindowMap) {
   5366                 final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5367                 if (displayContent != null && mCurrentUserId == callingUserId) {
   5368                     setForcedDisplayDensityLocked(displayContent,
   5369                             displayContent.mInitialDisplayDensity);
   5370                 }
   5371                 Settings.Secure.putStringForUser(mContext.getContentResolver(),
   5372                         Settings.Secure.DISPLAY_DENSITY_FORCED, "", callingUserId);
   5373             }
   5374         } finally {
   5375             Binder.restoreCallingIdentity(ident);
   5376         }
   5377     }
   5378 
   5379     /**
   5380      * @param userId the ID of the user
   5381      * @return the forced display density for the specified user, if set, or
   5382      *         {@code 0} if not set
   5383      */
   5384     private int getForcedDisplayDensityForUserLocked(int userId) {
   5385         String densityStr = Settings.Secure.getStringForUser(mContext.getContentResolver(),
   5386                 Settings.Secure.DISPLAY_DENSITY_FORCED, userId);
   5387         if (densityStr == null || densityStr.length() == 0) {
   5388             densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
   5389         }
   5390         if (densityStr != null && densityStr.length() > 0) {
   5391             try {
   5392                 return Integer.parseInt(densityStr);
   5393             } catch (NumberFormatException ex) {
   5394             }
   5395         }
   5396         return 0;
   5397     }
   5398 
   5399     /**
   5400      * Forces the given display to the use the specified density.
   5401      *
   5402      * @param displayContent the display to modify
   5403      * @param density the density in DPI to use
   5404      */
   5405     private void setForcedDisplayDensityLocked(@NonNull DisplayContent displayContent,
   5406             int density) {
   5407         displayContent.mBaseDisplayDensity = density;
   5408         reconfigureDisplayLocked(displayContent);
   5409     }
   5410 
   5411     void reconfigureDisplayLocked(@NonNull DisplayContent displayContent) {
   5412         if (!displayContent.isReady()) {
   5413             return;
   5414         }
   5415         displayContent.configureDisplayPolicy();
   5416         displayContent.setLayoutNeeded();
   5417 
   5418         final int displayId = displayContent.getDisplayId();
   5419         boolean configChanged = updateOrientationFromAppTokensLocked(displayId);
   5420         final Configuration currentDisplayConfig = displayContent.getConfiguration();
   5421         mTempConfiguration.setTo(currentDisplayConfig);
   5422         displayContent.computeScreenConfiguration(mTempConfiguration);
   5423         configChanged |= currentDisplayConfig.diff(mTempConfiguration) != 0;
   5424 
   5425         if (configChanged) {
   5426             mWaitingForConfig = true;
   5427             startFreezingDisplayLocked(0 /* exitAnim */,
   5428                     0 /* enterAnim */, displayContent);
   5429             mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
   5430         }
   5431 
   5432         mWindowPlacerLocked.performSurfacePlacement();
   5433     }
   5434 
   5435     /**
   5436      * Get an array with display ids ordered by focus priority - last items should be given
   5437      * focus first. Sparse array just maps position to displayId.
   5438      */
   5439     // TODO: Maintain display list in focus order in ActivityManager and remove this call.
   5440     public void getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder) {
   5441         synchronized(mWindowMap) {
   5442             mRoot.getDisplaysInFocusOrder(displaysInFocusOrder);
   5443         }
   5444     }
   5445 
   5446     @Override
   5447     public void setOverscan(int displayId, int left, int top, int right, int bottom) {
   5448         if (mContext.checkCallingOrSelfPermission(
   5449                 android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
   5450                 PackageManager.PERMISSION_GRANTED) {
   5451             throw new SecurityException("Must hold permission " +
   5452                     android.Manifest.permission.WRITE_SECURE_SETTINGS);
   5453         }
   5454         final long ident = Binder.clearCallingIdentity();
   5455         try {
   5456             synchronized(mWindowMap) {
   5457                 DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   5458                 if (displayContent != null) {
   5459                     setOverscanLocked(displayContent, left, top, right, bottom);
   5460                 }
   5461             }
   5462         } finally {
   5463             Binder.restoreCallingIdentity(ident);
   5464         }
   5465     }
   5466 
   5467     private void setOverscanLocked(DisplayContent displayContent,
   5468             int left, int top, int right, int bottom) {
   5469         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
   5470         displayInfo.overscanLeft = left;
   5471         displayInfo.overscanTop = top;
   5472         displayInfo.overscanRight = right;
   5473         displayInfo.overscanBottom = bottom;
   5474 
   5475         mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, displayInfo.name, left, top,
   5476                 right, bottom);
   5477         mDisplaySettings.writeSettingsLocked();
   5478 
   5479         reconfigureDisplayLocked(displayContent);
   5480     }
   5481 
   5482     @Override
   5483     public void startWindowTrace(){
   5484         try {
   5485             mWindowTracing.startTrace(null /* printwriter */);
   5486         } catch (IOException e) {
   5487             throw new RuntimeException(e);
   5488         }
   5489     }
   5490 
   5491     @Override
   5492     public void stopWindowTrace(){
   5493         mWindowTracing.stopTrace(null /* printwriter */);
   5494     }
   5495 
   5496     @Override
   5497     public boolean isWindowTraceEnabled() {
   5498         return mWindowTracing.isEnabled();
   5499     }
   5500 
   5501     // -------------------------------------------------------------
   5502     // Internals
   5503     // -------------------------------------------------------------
   5504 
   5505     final WindowState windowForClientLocked(Session session, IWindow client, boolean throwOnError) {
   5506         return windowForClientLocked(session, client.asBinder(), throwOnError);
   5507     }
   5508 
   5509     final WindowState windowForClientLocked(Session session, IBinder client, boolean throwOnError) {
   5510         WindowState win = mWindowMap.get(client);
   5511         if (localLOGV) Slog.v(TAG_WM, "Looking up client " + client + ": " + win);
   5512         if (win == null) {
   5513             if (throwOnError) {
   5514                 throw new IllegalArgumentException(
   5515                         "Requested window " + client + " does not exist");
   5516             }
   5517             Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3));
   5518             return null;
   5519         }
   5520         if (session != null && win.mSession != session) {
   5521             if (throwOnError) {
   5522                 throw new IllegalArgumentException("Requested window " + client + " is in session "
   5523                         + win.mSession + ", not " + session);
   5524             }
   5525             Slog.w(TAG_WM, "Failed looking up window callers=" + Debug.getCallers(3));
   5526             return null;
   5527         }
   5528 
   5529         return win;
   5530     }
   5531 
   5532     void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
   5533         // If the screen is currently frozen or off, then keep
   5534         // it frozen/off until this window draws at its new
   5535         // orientation.
   5536         if (!w.mToken.okToDisplay() && mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
   5537             if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
   5538             w.setOrientationChanging(true);
   5539             w.mLastFreezeDuration = 0;
   5540             mRoot.mOrientationChangeComplete = false;
   5541             if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
   5542                 mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
   5543                 // XXX should probably keep timeout from
   5544                 // when we first froze the display.
   5545                 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
   5546                 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
   5547                         WINDOW_FREEZE_TIMEOUT_DURATION);
   5548             }
   5549         }
   5550     }
   5551 
   5552     /**
   5553      * @return bitmap indicating if another pass through layout must be made.
   5554      */
   5555     int handleAnimatingStoppedAndTransitionLocked() {
   5556         int changes = 0;
   5557 
   5558         mAppTransition.setIdle();
   5559 
   5560         for (int i = mNoAnimationNotifyOnTransitionFinished.size() - 1; i >= 0; i--) {
   5561             final IBinder token = mNoAnimationNotifyOnTransitionFinished.get(i);
   5562             mAppTransition.notifyAppTransitionFinishedLocked(token);
   5563         }
   5564         mNoAnimationNotifyOnTransitionFinished.clear();
   5565 
   5566         // TODO: multi-display.
   5567         final DisplayContent dc = getDefaultDisplayContentLocked();
   5568 
   5569         dc.mWallpaperController.hideDeferredWallpapersIfNeeded();
   5570 
   5571         dc.onAppTransitionDone();
   5572 
   5573         changes |= FINISH_LAYOUT_REDO_LAYOUT;
   5574         if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM,
   5575                 "Wallpaper layer changed: assigning layers + relayout");
   5576         dc.computeImeTarget(true /* updateImeTarget */);
   5577         mRoot.mWallpaperMayChange = true;
   5578         // Since the window list has been rebuilt, focus might have to be recomputed since the
   5579         // actual order of windows might have changed again.
   5580         mFocusMayChange = true;
   5581 
   5582         return changes;
   5583     }
   5584 
   5585     void checkDrawnWindowsLocked() {
   5586         if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
   5587             return;
   5588         }
   5589         for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
   5590             WindowState win = mWaitingForDrawn.get(j);
   5591             if (DEBUG_SCREEN_ON) Slog.i(TAG_WM, "Waiting for drawn " + win +
   5592                     ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
   5593                     " mHasSurface=" + win.mHasSurface +
   5594                     " drawState=" + win.mWinAnimator.mDrawState);
   5595             if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) {
   5596                 // Window has been removed or hidden; no draw will now happen, so stop waiting.
   5597                 if (DEBUG_SCREEN_ON) Slog.w(TAG_WM, "Aborted waiting for drawn: " + win);
   5598                 mWaitingForDrawn.remove(win);
   5599             } else if (win.hasDrawnLw()) {
   5600                 // Window is now drawn (and shown).
   5601                 if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "Window drawn win=" + win);
   5602                 mWaitingForDrawn.remove(win);
   5603             }
   5604         }
   5605         if (mWaitingForDrawn.isEmpty()) {
   5606             if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "All windows drawn!");
   5607             mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
   5608             mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
   5609         }
   5610     }
   5611 
   5612     void setHoldScreenLocked(final Session newHoldScreen) {
   5613         final boolean hold = newHoldScreen != null;
   5614 
   5615         if (hold && mHoldingScreenOn != newHoldScreen) {
   5616             mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
   5617         }
   5618         mHoldingScreenOn = newHoldScreen;
   5619 
   5620         final boolean state = mHoldingScreenWakeLock.isHeld();
   5621         if (hold != state) {
   5622             if (hold) {
   5623                 if (DEBUG_KEEP_SCREEN_ON) {
   5624                     Slog.d(TAG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to "
   5625                             + mRoot.mHoldScreenWindow);
   5626                 }
   5627                 mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow;
   5628                 mLastWakeLockObscuringWindow = null;
   5629                 mHoldingScreenWakeLock.acquire();
   5630                 mPolicy.keepScreenOnStartedLw();
   5631             } else {
   5632                 if (DEBUG_KEEP_SCREEN_ON) {
   5633                     Slog.d(TAG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by "
   5634                             + mRoot.mObscuringWindow);
   5635                 }
   5636                 mLastWakeLockHoldingWindow = null;
   5637                 mLastWakeLockObscuringWindow = mRoot.mObscuringWindow;
   5638                 mPolicy.keepScreenOnStoppedLw();
   5639                 mHoldingScreenWakeLock.release();
   5640             }
   5641         }
   5642     }
   5643 
   5644     void requestTraversal() {
   5645         synchronized (mWindowMap) {
   5646             mWindowPlacerLocked.requestTraversal();
   5647         }
   5648     }
   5649 
   5650     /** Note that Locked in this case is on mLayoutToAnim */
   5651     void scheduleAnimationLocked() {
   5652         if (mAnimator != null) {
   5653             mAnimator.scheduleAnimation();
   5654         }
   5655     }
   5656 
   5657     // TODO: Move to DisplayContent
   5658     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
   5659         WindowState newFocus = mRoot.computeFocusedWindow();
   5660         if (mCurrentFocus != newFocus) {
   5661             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
   5662             // This check makes sure that we don't already have the focus
   5663             // change message pending.
   5664             mH.removeMessages(H.REPORT_FOCUS_CHANGE);
   5665             mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
   5666             // TODO(multidisplay): Focused windows on default display only.
   5667             final DisplayContent displayContent = getDefaultDisplayContentLocked();
   5668             boolean imWindowChanged = false;
   5669             if (mInputMethodWindow != null) {
   5670                 final WindowState prevTarget = mInputMethodTarget;
   5671                 final WindowState newTarget =
   5672                         displayContent.computeImeTarget(true /* updateImeTarget*/);
   5673 
   5674                 imWindowChanged = prevTarget != newTarget;
   5675 
   5676                 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
   5677                         && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
   5678                     final int prevImeAnimLayer = mInputMethodWindow.mWinAnimator.mAnimLayer;
   5679                     displayContent.assignWindowLayers(false /* setLayoutNeeded */);
   5680                     imWindowChanged |=
   5681                             prevImeAnimLayer != mInputMethodWindow.mWinAnimator.mAnimLayer;
   5682                 }
   5683             }
   5684 
   5685             if (imWindowChanged) {
   5686                 mWindowsChanged = true;
   5687                 displayContent.setLayoutNeeded();
   5688                 newFocus = mRoot.computeFocusedWindow();
   5689             }
   5690 
   5691             if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG_WM, "Changing focus from " +
   5692                     mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4));
   5693             final WindowState oldFocus = mCurrentFocus;
   5694             mCurrentFocus = newFocus;
   5695             mLosingFocus.remove(newFocus);
   5696 
   5697             if (mCurrentFocus != null) {
   5698                 mWinAddedSinceNullFocus.clear();
   5699                 mWinRemovedSinceNullFocus.clear();
   5700             }
   5701 
   5702             int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
   5703 
   5704             if (imWindowChanged && oldFocus != mInputMethodWindow) {
   5705                 // Focus of the input method window changed. Perform layout if needed.
   5706                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
   5707                     displayContent.performLayout(true /*initial*/,  updateInputWindows);
   5708                     focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
   5709                 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
   5710                     // Client will do the layout, but we need to assign layers
   5711                     // for handleNewWindowLocked() below.
   5712                     displayContent.assignWindowLayers(false /* setLayoutNeeded */);
   5713                 }
   5714             }
   5715 
   5716             if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
   5717                 // The change in focus caused us to need to do a layout.  Okay.
   5718                 displayContent.setLayoutNeeded();
   5719                 if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
   5720                     displayContent.performLayout(true /*initial*/, updateInputWindows);
   5721                 }
   5722             }
   5723 
   5724             if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
   5725                 // If we defer assigning layers, then the caller is responsible for
   5726                 // doing this part.
   5727                 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
   5728             }
   5729 
   5730             displayContent.adjustForImeIfNeeded();
   5731 
   5732             // We may need to schedule some toast windows to be removed. The toasts for an app that
   5733             // does not have input focus are removed within a timeout to prevent apps to redress
   5734             // other apps' UI.
   5735             displayContent.scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
   5736 
   5737             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
   5738             return true;
   5739         }
   5740         return false;
   5741     }
   5742 
   5743     void startFreezingDisplayLocked(int exitAnim, int enterAnim) {
   5744         startFreezingDisplayLocked(exitAnim, enterAnim,
   5745                 getDefaultDisplayContentLocked());
   5746     }
   5747 
   5748     void startFreezingDisplayLocked(int exitAnim, int enterAnim,
   5749             DisplayContent displayContent) {
   5750         if (mDisplayFrozen || mRotatingSeamlessly) {
   5751             return;
   5752         }
   5753 
   5754         if (!displayContent.isReady() || !mPolicy.isScreenOn() || !displayContent.okToAnimate()) {
   5755             // No need to freeze the screen before the display is ready,  if the screen is off,
   5756             // or we can't currently animate.
   5757             return;
   5758         }
   5759 
   5760         if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
   5761                 "startFreezingDisplayLocked: exitAnim="
   5762                 + exitAnim + " enterAnim=" + enterAnim
   5763                 + " called by " + Debug.getCallers(8));
   5764         mScreenFrozenLock.acquire();
   5765 
   5766         mDisplayFrozen = true;
   5767         mDisplayFreezeTime = SystemClock.elapsedRealtime();
   5768         mLastFinishedFreezeSource = null;
   5769 
   5770         // {@link mDisplayFrozen} prevents us from freezing on multiple displays at the same time.
   5771         // As a result, we only track the display that has initially froze the screen.
   5772         mFrozenDisplayId = displayContent.getDisplayId();
   5773 
   5774         mInputMonitor.freezeInputDispatchingLw();
   5775 
   5776         // Clear the last input window -- that is just used for
   5777         // clean transitions between IMEs, and if we are freezing
   5778         // the screen then the whole world is changing behind the scenes.
   5779         mPolicy.setLastInputMethodWindowLw(null, null);
   5780 
   5781         if (mAppTransition.isTransitionSet()) {
   5782             mAppTransition.freeze();
   5783         }
   5784 
   5785         if (PROFILE_ORIENTATION) {
   5786             File file = new File("/data/system/frozen");
   5787             Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
   5788         }
   5789 
   5790         mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
   5791         // TODO(multidisplay): rotation on non-default displays
   5792         if (CUSTOM_SCREEN_ROTATION && displayContent.isDefaultDisplay) {
   5793             mExitAnimId = exitAnim;
   5794             mEnterAnimId = enterAnim;
   5795             ScreenRotationAnimation screenRotationAnimation =
   5796                     mAnimator.getScreenRotationAnimationLocked(mFrozenDisplayId);
   5797             if (screenRotationAnimation != null) {
   5798                 screenRotationAnimation.kill();
   5799             }
   5800 
   5801             // Check whether the current screen contains any secure content.
   5802             boolean isSecure = displayContent.hasSecureWindowOnScreen();
   5803 
   5804             displayContent.updateDisplayInfo();
   5805             screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
   5806                     mPolicy.isDefaultOrientationForced(), isSecure,
   5807                     this);
   5808             mAnimator.setScreenRotationAnimationLocked(mFrozenDisplayId,
   5809                     screenRotationAnimation);
   5810         }
   5811     }
   5812 
   5813     void stopFreezingDisplayLocked() {
   5814         if (!mDisplayFrozen) {
   5815             return;
   5816         }
   5817 
   5818         if (mWaitingForConfig || mAppsFreezingScreen > 0
   5819                 || mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_ACTIVE
   5820                 || mClientFreezingScreen || !mOpeningApps.isEmpty()) {
   5821             if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
   5822                 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
   5823                 + ", mAppsFreezingScreen=" + mAppsFreezingScreen
   5824                 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
   5825                 + ", mClientFreezingScreen=" + mClientFreezingScreen
   5826                 + ", mOpeningApps.size()=" + mOpeningApps.size());
   5827             return;
   5828         }
   5829 
   5830         if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
   5831                 "stopFreezingDisplayLocked: Unfreezing now");
   5832 
   5833         final DisplayContent displayContent = mRoot.getDisplayContent(mFrozenDisplayId);
   5834 
   5835         // We must make a local copy of the displayId as it can be potentially overwritten later on
   5836         // in this method. For example, {@link startFreezingDisplayLocked} may be called as a result
   5837         // of update rotation, but we reference the frozen display after that call in this method.
   5838         final int displayId = mFrozenDisplayId;
   5839         mFrozenDisplayId = INVALID_DISPLAY;
   5840         mDisplayFrozen = false;
   5841         mInputMonitor.thawInputDispatchingLw();
   5842         mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
   5843         StringBuilder sb = new StringBuilder(128);
   5844         sb.append("Screen frozen for ");
   5845         TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
   5846         if (mLastFinishedFreezeSource != null) {
   5847             sb.append(" due to ");
   5848             sb.append(mLastFinishedFreezeSource);
   5849         }
   5850         Slog.i(TAG_WM, sb.toString());
   5851         mH.removeMessages(H.APP_FREEZE_TIMEOUT);
   5852         mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
   5853         if (PROFILE_ORIENTATION) {
   5854             Debug.stopMethodTracing();
   5855         }
   5856 
   5857         boolean updateRotation = false;
   5858 
   5859         ScreenRotationAnimation screenRotationAnimation =
   5860                 mAnimator.getScreenRotationAnimationLocked(displayId);
   5861         if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
   5862                 && screenRotationAnimation.hasScreenshot()) {
   5863             if (DEBUG_ORIENTATION) Slog.i(TAG_WM, "**** Dismissing screen rotation animation");
   5864             // TODO(multidisplay): rotation on main screen only.
   5865             DisplayInfo displayInfo = displayContent.getDisplayInfo();
   5866             // Get rotation animation again, with new top window
   5867             if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, false)) {
   5868                 mExitAnimId = mEnterAnimId = 0;
   5869             }
   5870             if (screenRotationAnimation.dismiss(mTransaction, MAX_ANIMATION_DURATION,
   5871                     getTransitionAnimationScaleLocked(), displayInfo.logicalWidth,
   5872                         displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
   5873                 mTransaction.apply();
   5874                 scheduleAnimationLocked();
   5875             } else {
   5876                 screenRotationAnimation.kill();
   5877                 mAnimator.setScreenRotationAnimationLocked(displayId, null);
   5878                 updateRotation = true;
   5879             }
   5880         } else {
   5881             if (screenRotationAnimation != null) {
   5882                 screenRotationAnimation.kill();
   5883                 mAnimator.setScreenRotationAnimationLocked(displayId, null);
   5884             }
   5885             updateRotation = true;
   5886         }
   5887 
   5888         boolean configChanged;
   5889 
   5890         // While the display is frozen we don't re-compute the orientation
   5891         // to avoid inconsistent states.  However, something interesting
   5892         // could have actually changed during that time so re-evaluate it
   5893         // now to catch that.
   5894         configChanged = updateOrientationFromAppTokensLocked(displayId);
   5895 
   5896         // A little kludge: a lot could have happened while the
   5897         // display was frozen, so now that we are coming back we
   5898         // do a gc so that any remote references the system
   5899         // processes holds on others can be released if they are
   5900         // no longer needed.
   5901         mH.removeMessages(H.FORCE_GC);
   5902         mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
   5903 
   5904         mScreenFrozenLock.release();
   5905 
   5906         if (updateRotation) {
   5907             if (DEBUG_ORIENTATION) Slog.d(TAG_WM, "Performing post-rotate rotation");
   5908             configChanged |= displayContent.updateRotationUnchecked();
   5909         }
   5910 
   5911         if (configChanged) {
   5912             mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayId).sendToTarget();
   5913         }
   5914         mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN);
   5915     }
   5916 
   5917     static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
   5918             DisplayMetrics dm) {
   5919         if (index < tokens.length) {
   5920             String str = tokens[index];
   5921             if (str != null && str.length() > 0) {
   5922                 try {
   5923                     int val = Integer.parseInt(str);
   5924                     return val;
   5925                 } catch (Exception e) {
   5926                 }
   5927             }
   5928         }
   5929         if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
   5930             return defDps;
   5931         }
   5932         int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
   5933         return val;
   5934     }
   5935 
   5936     void createWatermarkInTransaction() {
   5937         if (mWatermark != null) {
   5938             return;
   5939         }
   5940 
   5941         File file = new File("/system/etc/setup.conf");
   5942         FileInputStream in = null;
   5943         DataInputStream ind = null;
   5944         try {
   5945             in = new FileInputStream(file);
   5946             ind = new DataInputStream(in);
   5947             String line = ind.readLine();
   5948             if (line != null) {
   5949                 String[] toks = line.split("%");
   5950                 if (toks != null && toks.length > 0) {
   5951                     // TODO(multi-display): Show watermarks on secondary displays.
   5952                     final DisplayContent displayContent = getDefaultDisplayContentLocked();
   5953                     mWatermark = new Watermark(displayContent, displayContent.mRealDisplayMetrics,
   5954                             toks);
   5955                 }
   5956             }
   5957         } catch (FileNotFoundException e) {
   5958         } catch (IOException e) {
   5959         } finally {
   5960             if (ind != null) {
   5961                 try {
   5962                     ind.close();
   5963                 } catch (IOException e) {
   5964                 }
   5965             } else if (in != null) {
   5966                 try {
   5967                     in.close();
   5968                 } catch (IOException e) {
   5969                 }
   5970             }
   5971         }
   5972     }
   5973 
   5974     @Override
   5975     public void setRecentsVisibility(boolean visible) {
   5976         mAmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
   5977                 "setRecentsVisibility()");
   5978         synchronized (mWindowMap) {
   5979             mPolicy.setRecentsVisibilityLw(visible);
   5980         }
   5981     }
   5982 
   5983     @Override
   5984     public void setPipVisibility(boolean visible) {
   5985         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
   5986                 != PackageManager.PERMISSION_GRANTED) {
   5987             throw new SecurityException("Caller does not hold permission "
   5988                     + android.Manifest.permission.STATUS_BAR);
   5989         }
   5990 
   5991         synchronized (mWindowMap) {
   5992             mPolicy.setPipVisibilityLw(visible);
   5993         }
   5994     }
   5995 
   5996     @Override
   5997     public void setShelfHeight(boolean visible, int shelfHeight) {
   5998         mAmInternal.enforceCallerIsRecentsOrHasPermission(android.Manifest.permission.STATUS_BAR,
   5999                 "setShelfHeight()");
   6000         synchronized (mWindowMap) {
   6001             getDefaultDisplayContentLocked().getPinnedStackController().setAdjustedForShelf(visible,
   6002                     shelfHeight);
   6003         }
   6004     }
   6005 
   6006     @Override
   6007     public void statusBarVisibilityChanged(int visibility) {
   6008         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
   6009                 != PackageManager.PERMISSION_GRANTED) {
   6010             throw new SecurityException("Caller does not hold permission "
   6011                     + android.Manifest.permission.STATUS_BAR);
   6012         }
   6013 
   6014         synchronized (mWindowMap) {
   6015             mLastStatusBarVisibility = visibility;
   6016             visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
   6017             updateStatusBarVisibilityLocked(visibility);
   6018         }
   6019     }
   6020 
   6021     public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
   6022         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
   6023                 != PackageManager.PERMISSION_GRANTED) {
   6024             throw new SecurityException("Caller does not hold permission "
   6025                     + android.Manifest.permission.STATUS_BAR);
   6026         }
   6027 
   6028         synchronized (mWindowMap) {
   6029             mPolicy.setNavBarVirtualKeyHapticFeedbackEnabledLw(enabled);
   6030         }
   6031     }
   6032 
   6033     // TODO(multidisplay): StatusBar on multiple screens?
   6034     private boolean updateStatusBarVisibilityLocked(int visibility) {
   6035         if (mLastDispatchedSystemUiVisibility == visibility) {
   6036             return false;
   6037         }
   6038         final int globalDiff = (visibility ^ mLastDispatchedSystemUiVisibility)
   6039                 // We are only interested in differences of one of the
   6040                 // clearable flags...
   6041                 & View.SYSTEM_UI_CLEARABLE_FLAGS
   6042                 // ...if it has actually been cleared.
   6043                 & ~visibility;
   6044 
   6045         mLastDispatchedSystemUiVisibility = visibility;
   6046         mInputManager.setSystemUiVisibility(visibility);
   6047         getDefaultDisplayContentLocked().updateSystemUiVisibility(visibility, globalDiff);
   6048         return true;
   6049     }
   6050 
   6051     @Override
   6052     public void reevaluateStatusBarVisibility() {
   6053         synchronized (mWindowMap) {
   6054             int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
   6055             if (updateStatusBarVisibilityLocked(visibility)) {
   6056                 mWindowPlacerLocked.requestTraversal();
   6057             }
   6058         }
   6059     }
   6060 
   6061     /**
   6062      * Used by ActivityManager to determine where to position an app with aspect ratio shorter then
   6063      * the screen is.
   6064      * @see WindowManagerPolicy#getNavBarPosition()
   6065      */
   6066     @Override
   6067     @WindowManagerPolicy.NavigationBarPosition
   6068     public int getNavBarPosition() {
   6069         synchronized (mWindowMap) {
   6070             // Perform layout if it was scheduled before to make sure that we get correct nav bar
   6071             // position when doing rotations.
   6072             final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
   6073             defaultDisplayContent.performLayout(false /* initial */,
   6074                     false /* updateInputWindows */);
   6075             return mPolicy.getNavBarPosition();
   6076         }
   6077     }
   6078 
   6079     @Override
   6080     public WindowManagerPolicy.InputConsumer createInputConsumer(Looper looper, String name,
   6081             InputEventReceiver.Factory inputEventReceiverFactory) {
   6082         synchronized (mWindowMap) {
   6083             return mInputMonitor.createInputConsumer(looper, name, inputEventReceiverFactory);
   6084         }
   6085     }
   6086 
   6087     @Override
   6088     public void createInputConsumer(IBinder token, String name, InputChannel inputChannel) {
   6089         synchronized (mWindowMap) {
   6090             mInputMonitor.createInputConsumer(token, name, inputChannel, Binder.getCallingPid(),
   6091                     Binder.getCallingUserHandle());
   6092         }
   6093     }
   6094 
   6095     @Override
   6096     public boolean destroyInputConsumer(String name) {
   6097         synchronized (mWindowMap) {
   6098             return mInputMonitor.destroyInputConsumer(name);
   6099         }
   6100     }
   6101 
   6102     @Override
   6103     public Region getCurrentImeTouchRegion() {
   6104         if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
   6105             throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
   6106         }
   6107         synchronized (mWindowMap) {
   6108             final Region r = new Region();
   6109             if (mInputMethodWindow != null) {
   6110                 mInputMethodWindow.getTouchableRegion(r);
   6111             }
   6112             return r;
   6113         }
   6114     }
   6115 
   6116     @Override
   6117     public boolean hasNavigationBar() {
   6118         return mPolicy.hasNavigationBar();
   6119     }
   6120 
   6121     @Override
   6122     public void lockNow(Bundle options) {
   6123         mPolicy.lockNow(options);
   6124     }
   6125 
   6126     public void showRecentApps() {
   6127         mPolicy.showRecentApps();
   6128     }
   6129 
   6130     @Override
   6131     public boolean isSafeModeEnabled() {
   6132         return mSafeMode;
   6133     }
   6134 
   6135     @Override
   6136     public boolean clearWindowContentFrameStats(IBinder token) {
   6137         if (!checkCallingPermission(Manifest.permission.FRAME_STATS,
   6138                 "clearWindowContentFrameStats()")) {
   6139             throw new SecurityException("Requires FRAME_STATS permission");
   6140         }
   6141         synchronized (mWindowMap) {
   6142             WindowState windowState = mWindowMap.get(token);
   6143             if (windowState == null) {
   6144                 return false;
   6145             }
   6146             WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
   6147             if (surfaceController == null) {
   6148                 return false;
   6149             }
   6150             return surfaceController.clearWindowContentFrameStats();
   6151         }
   6152     }
   6153 
   6154     @Override
   6155     public WindowContentFrameStats getWindowContentFrameStats(IBinder token) {
   6156         if (!checkCallingPermission(Manifest.permission.FRAME_STATS,
   6157                 "getWindowContentFrameStats()")) {
   6158             throw new SecurityException("Requires FRAME_STATS permission");
   6159         }
   6160         synchronized (mWindowMap) {
   6161             WindowState windowState = mWindowMap.get(token);
   6162             if (windowState == null) {
   6163                 return null;
   6164             }
   6165             WindowSurfaceController surfaceController = windowState.mWinAnimator.mSurfaceController;
   6166             if (surfaceController == null) {
   6167                 return null;
   6168             }
   6169             if (mTempWindowRenderStats == null) {
   6170                 mTempWindowRenderStats = new WindowContentFrameStats();
   6171             }
   6172             WindowContentFrameStats stats = mTempWindowRenderStats;
   6173             if (!surfaceController.getWindowContentFrameStats(stats)) {
   6174                 return null;
   6175             }
   6176             return stats;
   6177         }
   6178     }
   6179 
   6180     public void notifyAppRelaunching(IBinder token) {
   6181         synchronized (mWindowMap) {
   6182             final AppWindowToken appWindow = mRoot.getAppWindowToken(token);
   6183             if (appWindow != null) {
   6184                 appWindow.startRelaunching();
   6185             }
   6186         }
   6187     }
   6188 
   6189     public void notifyAppRelaunchingFinished(IBinder token) {
   6190         synchronized (mWindowMap) {
   6191             final AppWindowToken appWindow = mRoot.getAppWindowToken(token);
   6192             if (appWindow != null) {
   6193                 appWindow.finishRelaunching();
   6194             }
   6195         }
   6196     }
   6197 
   6198     public void notifyAppRelaunchesCleared(IBinder token) {
   6199         synchronized (mWindowMap) {
   6200             final AppWindowToken appWindow = mRoot.getAppWindowToken(token);
   6201             if (appWindow != null) {
   6202                 appWindow.clearRelaunching();
   6203             }
   6204         }
   6205     }
   6206 
   6207     public void notifyAppResumedFinished(IBinder token) {
   6208         synchronized (mWindowMap) {
   6209             final AppWindowToken appWindow = mRoot.getAppWindowToken(token);
   6210             if (appWindow != null) {
   6211                 mUnknownAppVisibilityController.notifyAppResumedFinished(appWindow);
   6212             }
   6213         }
   6214     }
   6215 
   6216     /**
   6217      * Called when a task has been removed from the recent tasks list.
   6218      * <p>
   6219      * Note: This doesn't go through {@link TaskWindowContainerController} yet as the window
   6220      * container may not exist when this happens.
   6221      */
   6222     public void notifyTaskRemovedFromRecents(int taskId, int userId) {
   6223         synchronized (mWindowMap) {
   6224             mTaskSnapshotController.notifyTaskRemovedFromRecents(taskId, userId);
   6225         }
   6226     }
   6227 
   6228     @Override
   6229     public int getDockedDividerInsetsLw() {
   6230         return getDefaultDisplayContentLocked().getDockedDividerController().getContentInsets();
   6231     }
   6232 
   6233     private void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
   6234         pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
   6235         mPolicy.dump("    ", pw, args);
   6236     }
   6237 
   6238     private void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
   6239         pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
   6240         mAnimator.dumpLocked(pw, "    ", dumpAll);
   6241     }
   6242 
   6243     private void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
   6244         pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
   6245         mRoot.dumpTokens(pw, dumpAll);
   6246         if (!mOpeningApps.isEmpty() || !mClosingApps.isEmpty()) {
   6247             pw.println();
   6248             if (mOpeningApps.size() > 0) {
   6249                 pw.print("  mOpeningApps="); pw.println(mOpeningApps);
   6250             }
   6251             if (mClosingApps.size() > 0) {
   6252                 pw.print("  mClosingApps="); pw.println(mClosingApps);
   6253             }
   6254         }
   6255     }
   6256 
   6257     private void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
   6258         pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
   6259         for (int i=0; i<mSessions.size(); i++) {
   6260             Session s = mSessions.valueAt(i);
   6261             pw.print("  Session "); pw.print(s); pw.println(':');
   6262             s.dump(pw, "    ");
   6263         }
   6264     }
   6265 
   6266     /**
   6267      * Write to a protocol buffer output stream. Protocol buffer message definition is at
   6268      * {@link com.android.server.wm.WindowManagerServiceDumpProto}.
   6269      *
   6270      * @param proto     Stream to write the WindowContainer object to.
   6271      * @param trim      If true, reduce the amount of data written.
   6272      */
   6273     void writeToProtoLocked(ProtoOutputStream proto, boolean trim) {
   6274         mPolicy.writeToProto(proto, POLICY);
   6275         mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, trim);
   6276         if (mCurrentFocus != null) {
   6277             mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
   6278         }
   6279         if (mFocusedApp != null) {
   6280             mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
   6281         }
   6282         if (mInputMethodWindow != null) {
   6283             mInputMethodWindow.writeIdentifierToProto(proto, INPUT_METHOD_WINDOW);
   6284         }
   6285         proto.write(DISPLAY_FROZEN, mDisplayFrozen);
   6286         final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
   6287         proto.write(ROTATION, defaultDisplayContent.getRotation());
   6288         proto.write(LAST_ORIENTATION, defaultDisplayContent.getLastOrientation());
   6289         mAppTransition.writeToProto(proto, APP_TRANSITION);
   6290     }
   6291 
   6292     void traceStateLocked(String where) {
   6293         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "traceStateLocked");
   6294         try {
   6295             mWindowTracing.traceStateLocked(where, this);
   6296         } catch (Exception e) {
   6297             Log.wtf(TAG, "Exception while tracing state", e);
   6298         } finally {
   6299             Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
   6300         }
   6301     }
   6302 
   6303     private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
   6304             ArrayList<WindowState> windows) {
   6305         pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
   6306         dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
   6307     }
   6308 
   6309     private void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
   6310             ArrayList<WindowState> windows) {
   6311         mRoot.dumpWindowsNoHeader(pw, dumpAll, windows);
   6312 
   6313         if (!mHidingNonSystemOverlayWindows.isEmpty()) {
   6314             pw.println();
   6315             pw.println("  Hiding System Alert Windows:");
   6316             for (int i = mHidingNonSystemOverlayWindows.size() - 1; i >= 0; i--) {
   6317                 final WindowState w = mHidingNonSystemOverlayWindows.get(i);
   6318                 pw.print("  #"); pw.print(i); pw.print(' ');
   6319                 pw.print(w);
   6320                 if (dumpAll) {
   6321                     pw.println(":");
   6322                     w.dump(pw, "    ", true);
   6323                 } else {
   6324                     pw.println();
   6325                 }
   6326             }
   6327         }
   6328         if (mPendingRemove.size() > 0) {
   6329             pw.println();
   6330             pw.println("  Remove pending for:");
   6331             for (int i=mPendingRemove.size()-1; i>=0; i--) {
   6332                 WindowState w = mPendingRemove.get(i);
   6333                 if (windows == null || windows.contains(w)) {
   6334                     pw.print("  Remove #"); pw.print(i); pw.print(' ');
   6335                             pw.print(w);
   6336                     if (dumpAll) {
   6337                         pw.println(":");
   6338                         w.dump(pw, "    ", true);
   6339                     } else {
   6340                         pw.println();
   6341                     }
   6342                 }
   6343             }
   6344         }
   6345         if (mForceRemoves != null && mForceRemoves.size() > 0) {
   6346             pw.println();
   6347             pw.println("  Windows force removing:");
   6348             for (int i=mForceRemoves.size()-1; i>=0; i--) {
   6349                 WindowState w = mForceRemoves.get(i);
   6350                 pw.print("  Removing #"); pw.print(i); pw.print(' ');
   6351                         pw.print(w);
   6352                 if (dumpAll) {
   6353                     pw.println(":");
   6354                     w.dump(pw, "    ", true);
   6355                 } else {
   6356                     pw.println();
   6357                 }
   6358             }
   6359         }
   6360         if (mDestroySurface.size() > 0) {
   6361             pw.println();
   6362             pw.println("  Windows waiting to destroy their surface:");
   6363             for (int i=mDestroySurface.size()-1; i>=0; i--) {
   6364                 WindowState w = mDestroySurface.get(i);
   6365                 if (windows == null || windows.contains(w)) {
   6366                     pw.print("  Destroy #"); pw.print(i); pw.print(' ');
   6367                             pw.print(w);
   6368                     if (dumpAll) {
   6369                         pw.println(":");
   6370                         w.dump(pw, "    ", true);
   6371                     } else {
   6372                         pw.println();
   6373                     }
   6374                 }
   6375             }
   6376         }
   6377         if (mLosingFocus.size() > 0) {
   6378             pw.println();
   6379             pw.println("  Windows losing focus:");
   6380             for (int i=mLosingFocus.size()-1; i>=0; i--) {
   6381                 WindowState w = mLosingFocus.get(i);
   6382                 if (windows == null || windows.contains(w)) {
   6383                     pw.print("  Losing #"); pw.print(i); pw.print(' ');
   6384                             pw.print(w);
   6385                     if (dumpAll) {
   6386                         pw.println(":");
   6387                         w.dump(pw, "    ", true);
   6388                     } else {
   6389                         pw.println();
   6390                     }
   6391                 }
   6392             }
   6393         }
   6394         if (mResizingWindows.size() > 0) {
   6395             pw.println();
   6396             pw.println("  Windows waiting to resize:");
   6397             for (int i=mResizingWindows.size()-1; i>=0; i--) {
   6398                 WindowState w = mResizingWindows.get(i);
   6399                 if (windows == null || windows.contains(w)) {
   6400                     pw.print("  Resizing #"); pw.print(i); pw.print(' ');
   6401                             pw.print(w);
   6402                     if (dumpAll) {
   6403                         pw.println(":");
   6404                         w.dump(pw, "    ", true);
   6405                     } else {
   6406                         pw.println();
   6407                     }
   6408                 }
   6409             }
   6410         }
   6411         if (mWaitingForDrawn.size() > 0) {
   6412             pw.println();
   6413             pw.println("  Clients waiting for these windows to be drawn:");
   6414             for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
   6415                 WindowState win = mWaitingForDrawn.get(i);
   6416                 pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(win);
   6417             }
   6418         }
   6419         pw.println();
   6420         pw.print("  mGlobalConfiguration="); pw.println(mRoot.getConfiguration());
   6421         pw.print("  mHasPermanentDpad="); pw.println(mHasPermanentDpad);
   6422         pw.print("  mCurrentFocus="); pw.println(mCurrentFocus);
   6423         if (mLastFocus != mCurrentFocus) {
   6424             pw.print("  mLastFocus="); pw.println(mLastFocus);
   6425         }
   6426         pw.print("  mFocusedApp="); pw.println(mFocusedApp);
   6427         if (mInputMethodTarget != null) {
   6428             pw.print("  mInputMethodTarget="); pw.println(mInputMethodTarget);
   6429         }
   6430         pw.print("  mInTouchMode="); pw.println(mInTouchMode);
   6431         pw.print("  mLastDisplayFreezeDuration=");
   6432                 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
   6433                 if ( mLastFinishedFreezeSource != null) {
   6434                     pw.print(" due to ");
   6435                     pw.print(mLastFinishedFreezeSource);
   6436                 }
   6437                 pw.println();
   6438         pw.print("  mLastWakeLockHoldingWindow=");pw.print(mLastWakeLockHoldingWindow);
   6439                 pw.print(" mLastWakeLockObscuringWindow="); pw.print(mLastWakeLockObscuringWindow);
   6440                 pw.println();
   6441 
   6442         mInputMonitor.dump(pw, "  ");
   6443         mUnknownAppVisibilityController.dump(pw, "  ");
   6444         mTaskSnapshotController.dump(pw, "  ");
   6445 
   6446         if (dumpAll) {
   6447             pw.print("  mSystemDecorLayer="); pw.print(mSystemDecorLayer);
   6448                     pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
   6449             if (mLastStatusBarVisibility != 0) {
   6450                 pw.print("  mLastStatusBarVisibility=0x");
   6451                         pw.println(Integer.toHexString(mLastStatusBarVisibility));
   6452             }
   6453             if (mInputMethodWindow != null) {
   6454                 pw.print("  mInputMethodWindow="); pw.println(mInputMethodWindow);
   6455             }
   6456             mWindowPlacerLocked.dump(pw, "  ");
   6457             mRoot.mWallpaperController.dump(pw, "  ");
   6458             pw.print("  mSystemBooted="); pw.print(mSystemBooted);
   6459                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
   6460 
   6461             mRoot.dumpLayoutNeededDisplayIds(pw);
   6462 
   6463             pw.print("  mTransactionSequence="); pw.println(mTransactionSequence);
   6464             pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
   6465                     pw.print(" windows="); pw.print(mWindowsFreezingScreen);
   6466                     pw.print(" client="); pw.print(mClientFreezingScreen);
   6467                     pw.print(" apps="); pw.print(mAppsFreezingScreen);
   6468                     pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
   6469             final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
   6470             pw.print("  mRotation="); pw.print(defaultDisplayContent.getRotation());
   6471                     pw.print(" mAltOrientation=");
   6472                             pw.println(defaultDisplayContent.getAltOrientation());
   6473             pw.print("  mLastWindowForcedOrientation=");
   6474                     pw.print(defaultDisplayContent.getLastWindowForcedOrientation());
   6475                     pw.print(" mLastOrientation=");
   6476                             pw.println(defaultDisplayContent.getLastOrientation());
   6477             pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
   6478             pw.print("  Animation settings: disabled="); pw.print(mAnimationsDisabled);
   6479                     pw.print(" window="); pw.print(mWindowAnimationScaleSetting);
   6480                     pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
   6481                     pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
   6482             pw.print("  mSkipAppTransitionAnimation=");pw.println(mSkipAppTransitionAnimation);
   6483             pw.println("  mLayoutToAnim:");
   6484             mAppTransition.dump(pw, "    ");
   6485             if (mRecentsAnimationController != null) {
   6486                 pw.print("  mRecentsAnimationController="); pw.println(mRecentsAnimationController);
   6487                 mRecentsAnimationController.dump(pw, "    ");
   6488             }
   6489         }
   6490     }
   6491 
   6492     private boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti,
   6493             boolean dumpAll) {
   6494         final ArrayList<WindowState> windows = new ArrayList();
   6495         if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
   6496             final boolean appsOnly = name.contains("apps");
   6497             final boolean visibleOnly = name.contains("visible");
   6498             synchronized(mWindowMap) {
   6499                 if (appsOnly) {
   6500                     mRoot.dumpDisplayContents(pw);
   6501                 }
   6502 
   6503                 mRoot.forAllWindows((w) -> {
   6504                     if ((!visibleOnly || w.mWinAnimator.getShown())
   6505                             && (!appsOnly || w.mAppToken != null)) {
   6506                         windows.add(w);
   6507                     }
   6508                 }, true /* traverseTopToBottom */);
   6509             }
   6510         } else {
   6511             synchronized(mWindowMap) {
   6512                 mRoot.getWindowsByName(windows, name);
   6513             }
   6514         }
   6515 
   6516         if (windows.size() <= 0) {
   6517             return false;
   6518         }
   6519 
   6520         synchronized(mWindowMap) {
   6521             dumpWindowsLocked(pw, dumpAll, windows);
   6522         }
   6523         return true;
   6524     }
   6525 
   6526     private void dumpLastANRLocked(PrintWriter pw) {
   6527         pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
   6528         if (mLastANRState == null) {
   6529             pw.println("  <no ANR has occurred since boot>");
   6530         } else {
   6531             pw.println(mLastANRState);
   6532         }
   6533     }
   6534 
   6535     /**
   6536      * Saves information about the state of the window manager at
   6537      * the time an ANR occurred before anything else in the system changes
   6538      * in response.
   6539      *
   6540      * @param appWindowToken The application that ANR'd, may be null.
   6541      * @param windowState The window that ANR'd, may be null.
   6542      * @param reason The reason for the ANR, may be null.
   6543      */
   6544     void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, String reason) {
   6545         StringWriter sw = new StringWriter();
   6546         PrintWriter pw = new FastPrintWriter(sw, false, 1024);
   6547         pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
   6548         if (appWindowToken != null) {
   6549             pw.println("  Application at fault: " + appWindowToken.stringName);
   6550         }
   6551         if (windowState != null) {
   6552             pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
   6553         }
   6554         if (reason != null) {
   6555             pw.println("  Reason: " + reason);
   6556         }
   6557         if (!mWinAddedSinceNullFocus.isEmpty()) {
   6558             pw.println("  Windows added since null focus: " + mWinAddedSinceNullFocus);
   6559         }
   6560         if (!mWinRemovedSinceNullFocus.isEmpty()) {
   6561             pw.println("  Windows removed since null focus: " + mWinRemovedSinceNullFocus);
   6562         }
   6563         pw.println();
   6564         dumpWindowsNoHeaderLocked(pw, true, null);
   6565         pw.println();
   6566         pw.println("Last ANR continued");
   6567         mRoot.dumpDisplayContents(pw);
   6568         pw.close();
   6569         mLastANRState = sw.toString();
   6570 
   6571         mH.removeMessages(H.RESET_ANR_MESSAGE);
   6572         mH.sendEmptyMessageDelayed(H.RESET_ANR_MESSAGE, LAST_ANR_LIFETIME_DURATION_MSECS);
   6573     }
   6574 
   6575     @Override
   6576     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   6577         PriorityDump.dump(mPriorityDumper, fd, pw, args);
   6578     }
   6579 
   6580     private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
   6581         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
   6582         boolean dumpAll = false;
   6583 
   6584         int opti = 0;
   6585         while (opti < args.length) {
   6586             String opt = args[opti];
   6587             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
   6588                 break;
   6589             }
   6590             opti++;
   6591             if ("-a".equals(opt)) {
   6592                 dumpAll = true;
   6593             } else if ("-h".equals(opt)) {
   6594                 pw.println("Window manager dump options:");
   6595                 pw.println("  [-a] [-h] [cmd] ...");
   6596                 pw.println("  cmd may be one of:");
   6597                 pw.println("    l[astanr]: last ANR information");
   6598                 pw.println("    p[policy]: policy state");
   6599                 pw.println("    a[animator]: animator state");
   6600                 pw.println("    s[essions]: active sessions");
   6601                 pw.println("    surfaces: active surfaces (debugging enabled only)");
   6602                 pw.println("    d[isplays]: active display contents");
   6603                 pw.println("    t[okens]: token list");
   6604                 pw.println("    w[indows]: window list");
   6605                 pw.println("  cmd may also be a NAME to dump windows.  NAME may");
   6606                 pw.println("    be a partial substring in a window name, a");
   6607                 pw.println("    Window hex object identifier, or");
   6608                 pw.println("    \"all\" for all windows, or");
   6609                 pw.println("    \"visible\" for the visible windows.");
   6610                 pw.println("    \"visible-apps\" for the visible app windows.");
   6611                 pw.println("  -a: include all available server state.");
   6612                 pw.println("  --proto: output dump in protocol buffer format.");
   6613                 return;
   6614             } else {
   6615                 pw.println("Unknown argument: " + opt + "; use -h for help");
   6616             }
   6617         }
   6618 
   6619         if (useProto) {
   6620             final ProtoOutputStream proto = new ProtoOutputStream(fd);
   6621             synchronized (mWindowMap) {
   6622                 writeToProtoLocked(proto, false /* trim */);
   6623             }
   6624             proto.flush();
   6625             return;
   6626         }
   6627         // Is the caller requesting to dump a particular piece of data?
   6628         if (opti < args.length) {
   6629             String cmd = args[opti];
   6630             opti++;
   6631             if ("lastanr".equals(cmd) || "l".equals(cmd)) {
   6632                 synchronized(mWindowMap) {
   6633                     dumpLastANRLocked(pw);
   6634                 }
   6635                 return;
   6636             } else if ("policy".equals(cmd) || "p".equals(cmd)) {
   6637                 synchronized(mWindowMap) {
   6638                     dumpPolicyLocked(pw, args, true);
   6639                 }
   6640                 return;
   6641             } else if ("animator".equals(cmd) || "a".equals(cmd)) {
   6642                 synchronized(mWindowMap) {
   6643                     dumpAnimatorLocked(pw, args, true);
   6644                 }
   6645                 return;
   6646             } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
   6647                 synchronized(mWindowMap) {
   6648                     dumpSessionsLocked(pw, true);
   6649                 }
   6650                 return;
   6651             } else if ("displays".equals(cmd) || "d".equals(cmd)) {
   6652                 synchronized(mWindowMap) {
   6653                     mRoot.dumpDisplayContents(pw);
   6654                 }
   6655                 return;
   6656             } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
   6657                 synchronized(mWindowMap) {
   6658                     dumpTokensLocked(pw, true);
   6659                 }
   6660                 return;
   6661             } else if ("windows".equals(cmd) || "w".equals(cmd)) {
   6662                 synchronized(mWindowMap) {
   6663                     dumpWindowsLocked(pw, true, null);
   6664                 }
   6665                 return;
   6666             } else if ("all".equals(cmd) || "a".equals(cmd)) {
   6667                 synchronized(mWindowMap) {
   6668                     dumpWindowsLocked(pw, true, null);
   6669                 }
   6670                 return;
   6671             } else if ("containers".equals(cmd)) {
   6672                 synchronized(mWindowMap) {
   6673                     mRoot.dumpChildrenNames(pw, " ");
   6674                     pw.println(" ");
   6675                     mRoot.forAllWindows(w -> {pw.println(w);}, true /* traverseTopToBottom */);
   6676                 }
   6677                 return;
   6678             } else {
   6679                 // Dumping a single name?
   6680                 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
   6681                     pw.println("Bad window command, or no windows match: " + cmd);
   6682                     pw.println("Use -h for help.");
   6683                 }
   6684                 return;
   6685             }
   6686         }
   6687 
   6688         synchronized(mWindowMap) {
   6689             pw.println();
   6690             if (dumpAll) {
   6691                 pw.println("-------------------------------------------------------------------------------");
   6692             }
   6693             dumpLastANRLocked(pw);
   6694             pw.println();
   6695             if (dumpAll) {
   6696                 pw.println("-------------------------------------------------------------------------------");
   6697             }
   6698             dumpPolicyLocked(pw, args, dumpAll);
   6699             pw.println();
   6700             if (dumpAll) {
   6701                 pw.println("-------------------------------------------------------------------------------");
   6702             }
   6703             dumpAnimatorLocked(pw, args, dumpAll);
   6704             pw.println();
   6705             if (dumpAll) {
   6706                 pw.println("-------------------------------------------------------------------------------");
   6707             }
   6708             dumpSessionsLocked(pw, dumpAll);
   6709             pw.println();
   6710             if (dumpAll) {
   6711                 pw.println("-------------------------------------------------------------------------------");
   6712             }
   6713             if (dumpAll) {
   6714                 pw.println("-------------------------------------------------------------------------------");
   6715             }
   6716             mRoot.dumpDisplayContents(pw);
   6717             pw.println();
   6718             if (dumpAll) {
   6719                 pw.println("-------------------------------------------------------------------------------");
   6720             }
   6721             dumpTokensLocked(pw, dumpAll);
   6722             pw.println();
   6723             if (dumpAll) {
   6724                 pw.println("-------------------------------------------------------------------------------");
   6725             }
   6726             dumpWindowsLocked(pw, dumpAll, null);
   6727         }
   6728     }
   6729 
   6730     // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
   6731     @Override
   6732     public void monitor() {
   6733         synchronized (mWindowMap) { }
   6734     }
   6735 
   6736     // There is an inherent assumption that this will never return null.
   6737     // TODO(multi-display): Inspect all the call-points of this method to see if they make sense to
   6738     // support non-default display.
   6739     DisplayContent getDefaultDisplayContentLocked() {
   6740         return mRoot.getDisplayContent(DEFAULT_DISPLAY);
   6741     }
   6742 
   6743     public void onDisplayAdded(int displayId) {
   6744         synchronized (mWindowMap) {
   6745             final Display display = mDisplayManager.getDisplay(displayId);
   6746             if (display != null) {
   6747                 displayReady(displayId);
   6748             }
   6749             mWindowPlacerLocked.requestTraversal();
   6750         }
   6751     }
   6752 
   6753     public void onDisplayRemoved(int displayId) {
   6754         synchronized (mWindowMap) {
   6755             mAnimator.removeDisplayLocked(displayId);
   6756             mWindowPlacerLocked.requestTraversal();
   6757         }
   6758     }
   6759 
   6760     public void onOverlayChanged() {
   6761         synchronized (mWindowMap) {
   6762             mPolicy.onOverlayChangedLw();
   6763             getDefaultDisplayContentLocked().updateDisplayInfo();
   6764             requestTraversal();
   6765         }
   6766     }
   6767 
   6768     public void onDisplayChanged(int displayId) {
   6769         synchronized (mWindowMap) {
   6770             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   6771             if (displayContent != null) {
   6772                 displayContent.updateDisplayInfo();
   6773             }
   6774             mWindowPlacerLocked.requestTraversal();
   6775         }
   6776     }
   6777 
   6778     @Override
   6779     public Object getWindowManagerLock() {
   6780         return mWindowMap;
   6781     }
   6782 
   6783     /**
   6784      * Hint to a token that its activity will relaunch, which will trigger removal and addition of
   6785      * a window.
   6786      * @param token Application token for which the activity will be relaunched.
   6787      */
   6788     public void setWillReplaceWindow(IBinder token, boolean animate) {
   6789         synchronized (mWindowMap) {
   6790             final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token);
   6791             if (appWindowToken == null) {
   6792                 Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
   6793                         + token);
   6794                 return;
   6795             }
   6796             if (!appWindowToken.hasContentToDisplay()) {
   6797                 Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content"
   6798                         + token);
   6799                 return;
   6800             }
   6801             appWindowToken.setWillReplaceWindows(animate);
   6802         }
   6803     }
   6804 
   6805     /**
   6806      * Hint to a token that its windows will be replaced across activity relaunch.
   6807      * The windows would otherwise be removed  shortly following this as the
   6808      * activity is torn down.
   6809      * @param token Application token for which the activity will be relaunched.
   6810      * @param childrenOnly Whether to mark only child windows for replacement
   6811      *                     (for the case where main windows are being preserved/
   6812      *                     reused rather than replaced).
   6813      *
   6814      */
   6815     // TODO: The s at the end of the method name is the only difference with the name of the method
   6816     // above. We should combine them or find better names.
   6817     void setWillReplaceWindows(IBinder token, boolean childrenOnly) {
   6818         synchronized (mWindowMap) {
   6819             final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token);
   6820             if (appWindowToken == null) {
   6821                 Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token "
   6822                         + token);
   6823                 return;
   6824             }
   6825             if (!appWindowToken.hasContentToDisplay()) {
   6826                 Slog.w(TAG_WM, "Attempted to set replacing window on app token with no content"
   6827                         + token);
   6828                 return;
   6829             }
   6830 
   6831             if (childrenOnly) {
   6832                 appWindowToken.setWillReplaceChildWindows();
   6833             } else {
   6834                 appWindowToken.setWillReplaceWindows(false /* animate */);
   6835             }
   6836 
   6837             scheduleClearWillReplaceWindows(token, true /* replacing */);
   6838         }
   6839     }
   6840 
   6841     /**
   6842      * If we're replacing the window, schedule a timer to clear the replaced window
   6843      * after a timeout, in case the replacing window is not coming.
   6844      *
   6845      * If we're not replacing the window, clear the replace window settings of the app.
   6846      *
   6847      * @param token Application token for the activity whose window might be replaced.
   6848      * @param replacing Whether the window is being replaced or not.
   6849      */
   6850     public void scheduleClearWillReplaceWindows(IBinder token, boolean replacing) {
   6851         synchronized (mWindowMap) {
   6852             final AppWindowToken appWindowToken = mRoot.getAppWindowToken(token);
   6853             if (appWindowToken == null) {
   6854                 Slog.w(TAG_WM, "Attempted to reset replacing window on non-existing app token "
   6855                         + token);
   6856                 return;
   6857             }
   6858             if (replacing) {
   6859                 scheduleWindowReplacementTimeouts(appWindowToken);
   6860             } else {
   6861                 appWindowToken.clearWillReplaceWindows();
   6862             }
   6863         }
   6864     }
   6865 
   6866     void scheduleWindowReplacementTimeouts(AppWindowToken appWindowToken) {
   6867         if (!mWindowReplacementTimeouts.contains(appWindowToken)) {
   6868             mWindowReplacementTimeouts.add(appWindowToken);
   6869         }
   6870         mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT);
   6871         mH.sendEmptyMessageDelayed(
   6872                 H.WINDOW_REPLACEMENT_TIMEOUT, WINDOW_REPLACEMENT_TIMEOUT_DURATION);
   6873     }
   6874 
   6875     @Override
   6876     public int getDockedStackSide() {
   6877         synchronized (mWindowMap) {
   6878             final TaskStack dockedStack = getDefaultDisplayContentLocked()
   6879                     .getSplitScreenPrimaryStackIgnoringVisibility();
   6880             return dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide();
   6881         }
   6882     }
   6883 
   6884     public void setDockedStackResizing(boolean resizing) {
   6885         synchronized (mWindowMap) {
   6886             getDefaultDisplayContentLocked().getDockedDividerController().setResizing(resizing);
   6887             requestTraversal();
   6888         }
   6889     }
   6890 
   6891     @Override
   6892     public void setDockedStackDividerTouchRegion(Rect touchRegion) {
   6893         synchronized (mWindowMap) {
   6894             getDefaultDisplayContentLocked().getDockedDividerController()
   6895                     .setTouchRegion(touchRegion);
   6896             setFocusTaskRegionLocked(null);
   6897         }
   6898     }
   6899 
   6900     @Override
   6901     public void setResizeDimLayer(boolean visible, int targetWindowingMode, float alpha) {
   6902         synchronized (mWindowMap) {
   6903             getDefaultDisplayContentLocked().getDockedDividerController().setResizeDimLayer(
   6904                     visible, targetWindowingMode, alpha);
   6905         }
   6906     }
   6907 
   6908     public void setForceResizableTasks(boolean forceResizableTasks) {
   6909         synchronized (mWindowMap) {
   6910             mForceResizableTasks = forceResizableTasks;
   6911         }
   6912     }
   6913 
   6914     public void setSupportsPictureInPicture(boolean supportsPictureInPicture) {
   6915         synchronized (mWindowMap) {
   6916             mSupportsPictureInPicture = supportsPictureInPicture;
   6917         }
   6918     }
   6919 
   6920     static int dipToPixel(int dip, DisplayMetrics displayMetrics) {
   6921         return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, displayMetrics);
   6922     }
   6923 
   6924     @Override
   6925     public void registerDockedStackListener(IDockedStackListener listener) {
   6926         if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
   6927                 "registerDockedStackListener()")) {
   6928             return;
   6929         }
   6930         synchronized (mWindowMap) {
   6931             // TODO(multi-display): The listener is registered on the default display only.
   6932             getDefaultDisplayContentLocked().mDividerControllerLocked.registerDockedStackListener(
   6933                     listener);
   6934         }
   6935     }
   6936 
   6937     @Override
   6938     public void registerPinnedStackListener(int displayId, IPinnedStackListener listener) {
   6939         if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS,
   6940                 "registerPinnedStackListener()")) {
   6941             return;
   6942         }
   6943         if (!mSupportsPictureInPicture) {
   6944             return;
   6945         }
   6946         synchronized (mWindowMap) {
   6947             final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
   6948             displayContent.getPinnedStackController().registerPinnedStackListener(listener);
   6949         }
   6950     }
   6951 
   6952     @Override
   6953     public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) {
   6954         try {
   6955             WindowState focusedWindow = getFocusedWindow();
   6956             if (focusedWindow != null && focusedWindow.mClient != null) {
   6957                 getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId);
   6958             }
   6959         } catch (RemoteException e) {
   6960         }
   6961     }
   6962 
   6963     @Override
   6964     public void getStableInsets(int displayId, Rect outInsets) throws RemoteException {
   6965         synchronized (mWindowMap) {
   6966             getStableInsetsLocked(displayId, outInsets);
   6967         }
   6968     }
   6969 
   6970     void getStableInsetsLocked(int displayId, Rect outInsets) {
   6971         outInsets.setEmpty();
   6972         final DisplayContent dc = mRoot.getDisplayContent(displayId);
   6973         if (dc != null) {
   6974             final DisplayInfo di = dc.getDisplayInfo();
   6975             mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
   6976                     di.displayCutout, outInsets);
   6977         }
   6978     }
   6979 
   6980     void intersectDisplayInsetBounds(Rect display, Rect insets, Rect inOutBounds) {
   6981         mTmpRect3.set(display);
   6982         mTmpRect3.inset(insets);
   6983         inOutBounds.intersect(mTmpRect3);
   6984     }
   6985 
   6986     MousePositionTracker mMousePositionTracker = new MousePositionTracker();
   6987 
   6988     private static class MousePositionTracker implements PointerEventListener {
   6989         private boolean mLatestEventWasMouse;
   6990         private float mLatestMouseX;
   6991         private float mLatestMouseY;
   6992 
   6993         void updatePosition(float x, float y) {
   6994             synchronized (this) {
   6995                 mLatestEventWasMouse = true;
   6996                 mLatestMouseX = x;
   6997                 mLatestMouseY = y;
   6998             }
   6999         }
   7000 
   7001         @Override
   7002         public void onPointerEvent(MotionEvent motionEvent) {
   7003             if (motionEvent.isFromSource(InputDevice.SOURCE_MOUSE)) {
   7004                 updatePosition(motionEvent.getRawX(), motionEvent.getRawY());
   7005             } else {
   7006                 synchronized (this) {
   7007                     mLatestEventWasMouse = false;
   7008                 }
   7009             }
   7010         }
   7011     };
   7012 
   7013     void updatePointerIcon(IWindow client) {
   7014         float mouseX, mouseY;
   7015 
   7016         synchronized(mMousePositionTracker) {
   7017             if (!mMousePositionTracker.mLatestEventWasMouse) {
   7018                 return;
   7019             }
   7020             mouseX = mMousePositionTracker.mLatestMouseX;
   7021             mouseY = mMousePositionTracker.mLatestMouseY;
   7022         }
   7023 
   7024         synchronized (mWindowMap) {
   7025             if (mDragDropController.dragDropActiveLocked()) {
   7026                 // Drag cursor overrides the app cursor.
   7027                 return;
   7028             }
   7029             WindowState callingWin = windowForClientLocked(null, client, false);
   7030             if (callingWin == null) {
   7031                 Slog.w(TAG_WM, "Bad requesting window " + client);
   7032                 return;
   7033             }
   7034             final DisplayContent displayContent = callingWin.getDisplayContent();
   7035             if (displayContent == null) {
   7036                 return;
   7037             }
   7038             WindowState windowUnderPointer =
   7039                     displayContent.getTouchableWinAtPointLocked(mouseX, mouseY);
   7040             if (windowUnderPointer != callingWin) {
   7041                 return;
   7042             }
   7043             try {
   7044                 windowUnderPointer.mClient.updatePointerIcon(
   7045                         windowUnderPointer.translateToWindowX(mouseX),
   7046                         windowUnderPointer.translateToWindowY(mouseY));
   7047             } catch (RemoteException e) {
   7048                 Slog.w(TAG_WM, "unable to update pointer icon");
   7049             }
   7050         }
   7051     }
   7052 
   7053     void restorePointerIconLocked(DisplayContent displayContent, float latestX, float latestY) {
   7054         // Mouse position tracker has not been getting updates while dragging, update it now.
   7055         mMousePositionTracker.updatePosition(latestX, latestY);
   7056 
   7057         WindowState windowUnderPointer =
   7058                 displayContent.getTouchableWinAtPointLocked(latestX, latestY);
   7059         if (windowUnderPointer != null) {
   7060             try {
   7061                 windowUnderPointer.mClient.updatePointerIcon(
   7062                         windowUnderPointer.translateToWindowX(latestX),
   7063                         windowUnderPointer.translateToWindowY(latestY));
   7064             } catch (RemoteException e) {
   7065                 Slog.w(TAG_WM, "unable to restore pointer icon");
   7066             }
   7067         } else {
   7068             InputManager.getInstance().setPointerIconType(PointerIcon.TYPE_DEFAULT);
   7069         }
   7070     }
   7071 
   7072     /**
   7073      * Update a tap exclude region with a rectangular area in the window identified by the provided
   7074      * id. Touches on this region will not switch focus to this window. Passing an empty rect will
   7075      * remove the area from the exclude region of this window.
   7076      */
   7077     void updateTapExcludeRegion(IWindow client, int regionId, int left, int top, int width,
   7078             int height) {
   7079         synchronized (mWindowMap) {
   7080             final WindowState callingWin = windowForClientLocked(null, client, false);
   7081             if (callingWin == null) {
   7082                 Slog.w(TAG_WM, "Bad requesting window " + client);
   7083                 return;
   7084             }
   7085             callingWin.updateTapExcludeRegion(regionId, left, top, width, height);
   7086         }
   7087     }
   7088 
   7089     @Override
   7090     public void dontOverrideDisplayInfo(int displayId) {
   7091         synchronized (mWindowMap) {
   7092             final DisplayContent dc = getDisplayContentOrCreate(displayId);
   7093             if (dc == null) {
   7094                 throw new IllegalArgumentException(
   7095                         "Trying to register a non existent display.");
   7096             }
   7097             // We usually set the override info in DisplayManager so that we get consistent
   7098             // values when displays are changing. However, we don't do this for displays that
   7099             // serve as containers for ActivityViews because we don't want letter-/pillar-boxing
   7100             // during resize.
   7101             dc.mShouldOverrideDisplayConfiguration = false;
   7102             mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId,
   7103                     null /* info */);
   7104         }
   7105     }
   7106 
   7107     @Override
   7108     public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
   7109             throws RemoteException {
   7110         if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) {
   7111             throw new SecurityException(
   7112                     "Requires REGISTER_WINDOW_MANAGER_LISTENERS permission");
   7113         }
   7114         mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver);
   7115     }
   7116 
   7117     @Override
   7118     public void requestUserActivityNotification() {
   7119         if (!checkCallingPermission(android.Manifest.permission.USER_ACTIVITY,
   7120                 "requestUserActivityNotification()")) {
   7121             throw new SecurityException("Requires USER_ACTIVITY permission");
   7122         }
   7123         mPolicy.requestUserActivityNotification();
   7124     }
   7125 
   7126     void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
   7127         if (seamlesslyRotated == w.mSeamlesslyRotated) {
   7128             return;
   7129         }
   7130         w.mSeamlesslyRotated = seamlesslyRotated;
   7131         if (seamlesslyRotated) {
   7132             mSeamlessRotationCount++;
   7133         } else {
   7134             mSeamlessRotationCount--;
   7135         }
   7136         if (mSeamlessRotationCount == 0) {
   7137             if (DEBUG_ORIENTATION) {
   7138                 Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
   7139             }
   7140             finishSeamlessRotation();
   7141 
   7142             final DisplayContent displayContent = w.getDisplayContent();
   7143             if (displayContent.updateRotationUnchecked()) {
   7144                 mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
   7145                         .sendToTarget();
   7146             }
   7147         }
   7148     }
   7149 
   7150     private final class LocalService extends WindowManagerInternal {
   7151         @Override
   7152         public void requestTraversalFromDisplayManager() {
   7153             requestTraversal();
   7154         }
   7155 
   7156         @Override
   7157         public void setMagnificationSpec(MagnificationSpec spec) {
   7158             synchronized (mWindowMap) {
   7159                 if (mAccessibilityController != null) {
   7160                     mAccessibilityController.setMagnificationSpecLocked(spec);
   7161                 } else {
   7162                     throw new IllegalStateException("Magnification callbacks not set!");
   7163                 }
   7164             }
   7165             if (Binder.getCallingPid() != myPid()) {
   7166                 spec.recycle();
   7167             }
   7168         }
   7169 
   7170         @Override
   7171         public void setForceShowMagnifiableBounds(boolean show) {
   7172             synchronized (mWindowMap) {
   7173                 if (mAccessibilityController != null) {
   7174                     mAccessibilityController.setForceShowMagnifiableBoundsLocked(show);
   7175                 } else {
   7176                     throw new IllegalStateException("Magnification callbacks not set!");
   7177                 }
   7178             }
   7179         }
   7180 
   7181         @Override
   7182         public void getMagnificationRegion(@NonNull Region magnificationRegion) {
   7183             synchronized (mWindowMap) {
   7184                 if (mAccessibilityController != null) {
   7185                     mAccessibilityController.getMagnificationRegionLocked(magnificationRegion);
   7186                 } else {
   7187                     throw new IllegalStateException("Magnification callbacks not set!");
   7188                 }
   7189             }
   7190         }
   7191 
   7192         @Override
   7193         public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
   7194             synchronized (mWindowMap) {
   7195                 WindowState windowState = mWindowMap.get(windowToken);
   7196                 if (windowState == null) {
   7197                     return null;
   7198                 }
   7199                 MagnificationSpec spec = null;
   7200                 if (mAccessibilityController != null) {
   7201                     spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState);
   7202                 }
   7203                 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
   7204                     return null;
   7205                 }
   7206                 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
   7207                 spec.scale *= windowState.mGlobalScale;
   7208                 return spec;
   7209             }
   7210         }
   7211 
   7212         @Override
   7213         public void setMagnificationCallbacks(@Nullable MagnificationCallbacks callbacks) {
   7214             synchronized (mWindowMap) {
   7215                 if (mAccessibilityController == null) {
   7216                     mAccessibilityController = new AccessibilityController(
   7217                             WindowManagerService.this);
   7218                 }
   7219                 mAccessibilityController.setMagnificationCallbacksLocked(callbacks);
   7220                 if (!mAccessibilityController.hasCallbacksLocked()) {
   7221                     mAccessibilityController = null;
   7222                 }
   7223             }
   7224         }
   7225 
   7226         @Override
   7227         public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
   7228             synchronized (mWindowMap) {
   7229                 if (mAccessibilityController == null) {
   7230                     mAccessibilityController = new AccessibilityController(
   7231                             WindowManagerService.this);
   7232                 }
   7233                 mAccessibilityController.setWindowsForAccessibilityCallback(callback);
   7234                 if (!mAccessibilityController.hasCallbacksLocked()) {
   7235                     mAccessibilityController = null;
   7236                 }
   7237             }
   7238         }
   7239 
   7240         @Override
   7241         public void setInputFilter(IInputFilter filter) {
   7242             mInputManager.setInputFilter(filter);
   7243         }
   7244 
   7245         @Override
   7246         public IBinder getFocusedWindowToken() {
   7247             synchronized (mWindowMap) {
   7248                 WindowState windowState = getFocusedWindowLocked();
   7249                 if (windowState != null) {
   7250                     return windowState.mClient.asBinder();
   7251                 }
   7252                 return null;
   7253             }
   7254         }
   7255 
   7256         @Override
   7257         public boolean isKeyguardLocked() {
   7258             return WindowManagerService.this.isKeyguardLocked();
   7259         }
   7260 
   7261         @Override
   7262         public boolean isKeyguardShowingAndNotOccluded() {
   7263             return WindowManagerService.this.isKeyguardShowingAndNotOccluded();
   7264         }
   7265 
   7266         @Override
   7267         public void showGlobalActions() {
   7268             WindowManagerService.this.showGlobalActions();
   7269         }
   7270 
   7271         @Override
   7272         public void getWindowFrame(IBinder token, Rect outBounds) {
   7273             synchronized (mWindowMap) {
   7274                 WindowState windowState = mWindowMap.get(token);
   7275                 if (windowState != null) {
   7276                     outBounds.set(windowState.mFrame);
   7277                 } else {
   7278                     outBounds.setEmpty();
   7279                 }
   7280             }
   7281         }
   7282 
   7283         @Override
   7284         public void waitForAllWindowsDrawn(Runnable callback, long timeout) {
   7285             boolean allWindowsDrawn = false;
   7286             synchronized (mWindowMap) {
   7287                 mWaitingForDrawnCallback = callback;
   7288                 getDefaultDisplayContentLocked().waitForAllWindowsDrawn();
   7289                 mWindowPlacerLocked.requestTraversal();
   7290                 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
   7291                 if (mWaitingForDrawn.isEmpty()) {
   7292                     allWindowsDrawn = true;
   7293                 } else {
   7294                     mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
   7295                     checkDrawnWindowsLocked();
   7296                 }
   7297             }
   7298             if (allWindowsDrawn) {
   7299                 callback.run();
   7300             }
   7301         }
   7302 
   7303         @Override
   7304         public void addWindowToken(IBinder token, int type, int displayId) {
   7305             WindowManagerService.this.addWindowToken(token, type, displayId);
   7306         }
   7307 
   7308         @Override
   7309         public void removeWindowToken(IBinder binder, boolean removeWindows, int displayId) {
   7310             synchronized(mWindowMap) {
   7311                 if (removeWindows) {
   7312                     final DisplayContent dc = mRoot.getDisplayContent(displayId);
   7313                     if (dc == null) {
   7314                         Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder
   7315                                 + " for non-exiting displayId=" + displayId);
   7316                         return;
   7317                     }
   7318 
   7319                     final WindowToken token = dc.removeWindowToken(binder);
   7320                     if (token == null) {
   7321                         Slog.w(TAG_WM, "removeWindowToken: Attempted to remove non-existing token: "
   7322                                 + binder);
   7323                         return;
   7324                     }
   7325 
   7326                     token.removeAllWindowsIfPossible();
   7327                 }
   7328                 WindowManagerService.this.removeWindowToken(binder, displayId);
   7329             }
   7330         }
   7331 
   7332         @Override
   7333         public void registerAppTransitionListener(AppTransitionListener listener) {
   7334             synchronized (mWindowMap) {
   7335                 mAppTransition.registerListenerLocked(listener);
   7336             }
   7337         }
   7338 
   7339         @Override
   7340         public int getInputMethodWindowVisibleHeight() {
   7341             synchronized (mWindowMap) {
   7342                 // TODO(multi-display): Have caller pass in the display they are interested in.
   7343                 final DisplayContent dc = getDefaultDisplayContentLocked();
   7344                 return dc.mDisplayFrames.getInputMethodWindowVisibleHeight();
   7345             }
   7346         }
   7347 
   7348         @Override
   7349         public void saveLastInputMethodWindowForTransition() {
   7350             synchronized (mWindowMap) {
   7351                 if (mInputMethodWindow != null) {
   7352                     mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
   7353                 }
   7354             }
   7355         }
   7356 
   7357         @Override
   7358         public void clearLastInputMethodWindowForTransition() {
   7359             synchronized (mWindowMap) {
   7360                 mPolicy.setLastInputMethodWindowLw(null, null);
   7361             }
   7362         }
   7363 
   7364         @Override
   7365         public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
   7366                 boolean imeWindowVisible, boolean dismissImeOnBackKeyPressed,
   7367                 @Nullable IBinder targetWindowToken) {
   7368             // TODO (b/34628091): Use this method to address the window animation issue.
   7369             if (DEBUG_INPUT_METHOD) {
   7370                 Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken=" + imeToken
   7371                         + " dismissImeOnBackKeyPressed=" + dismissImeOnBackKeyPressed
   7372                         + " imeWindowVisible=" + imeWindowVisible
   7373                         + " targetWindowToken=" + targetWindowToken);
   7374             }
   7375             mPolicy.setDismissImeOnBackKeyPressed(dismissImeOnBackKeyPressed);
   7376         }
   7377 
   7378         @Override
   7379         public boolean isHardKeyboardAvailable() {
   7380             synchronized (mWindowMap) {
   7381                 return mHardKeyboardAvailable;
   7382             }
   7383         }
   7384 
   7385         @Override
   7386         public void setOnHardKeyboardStatusChangeListener(
   7387                 OnHardKeyboardStatusChangeListener listener) {
   7388             synchronized (mWindowMap) {
   7389                 mHardKeyboardStatusChangeListener = listener;
   7390             }
   7391         }
   7392 
   7393         @Override
   7394         public boolean isStackVisible(int windowingMode) {
   7395             synchronized (mWindowMap) {
   7396                 final DisplayContent dc = getDefaultDisplayContentLocked();
   7397                 return dc.isStackVisible(windowingMode);
   7398             }
   7399         }
   7400 
   7401         @Override
   7402         public boolean isDockedDividerResizing() {
   7403             synchronized (mWindowMap) {
   7404                 return getDefaultDisplayContentLocked().getDockedDividerController().isResizing();
   7405             }
   7406         }
   7407 
   7408         @Override
   7409         public void computeWindowsForAccessibility() {
   7410             final AccessibilityController accessibilityController;
   7411             synchronized (mWindowMap) {
   7412                 accessibilityController = mAccessibilityController;
   7413             }
   7414             if (accessibilityController != null) {
   7415                 accessibilityController.performComputeChangedWindowsNotLocked();
   7416             }
   7417         }
   7418 
   7419         @Override
   7420         public void setVr2dDisplayId(int vr2dDisplayId) {
   7421             if (DEBUG_DISPLAY) {
   7422                 Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
   7423             }
   7424             synchronized (WindowManagerService.this) {
   7425                 mVr2dDisplayId = vr2dDisplayId;
   7426             }
   7427         }
   7428 
   7429         @Override
   7430         public void registerDragDropControllerCallback(IDragDropCallback callback) {
   7431             mDragDropController.registerCallback(callback);
   7432         }
   7433 
   7434         @Override
   7435         public void lockNow() {
   7436             WindowManagerService.this.lockNow(null);
   7437         }
   7438 
   7439         @Override
   7440         public int getWindowOwnerUserId(IBinder token) {
   7441             synchronized (mWindowMap) {
   7442                 WindowState window = mWindowMap.get(token);
   7443                 if (window != null) {
   7444                     return UserHandle.getUserId(window.mOwnerUid);
   7445                 }
   7446                 return UserHandle.USER_NULL;
   7447             }
   7448         }
   7449     }
   7450 
   7451     void registerAppFreezeListener(AppFreezeListener listener) {
   7452         if (!mAppFreezeListeners.contains(listener)) {
   7453             mAppFreezeListeners.add(listener);
   7454         }
   7455     }
   7456 
   7457     void unregisterAppFreezeListener(AppFreezeListener listener) {
   7458         mAppFreezeListeners.remove(listener);
   7459     }
   7460 
   7461     /**
   7462      * WARNING: This interrupts surface updates, be careful! Don't
   7463      * execute within the transaction for longer than you would
   7464      * execute on an animation thread.
   7465      * WARNING: This holds the WindowManager lock, so if exec will acquire
   7466      * the ActivityManager lock, you should hold it BEFORE calling this
   7467      * otherwise there is a risk of deadlock if another thread holding the AM
   7468      * lock waits on the WM lock.
   7469      * WARNING: This method contains locks known to the State of California
   7470      * to cause Deadlocks and other conditions.
   7471      *
   7472      * Begins a surface transaction with which the AM can batch operations.
   7473      * All Surface updates performed by the WindowManager following this
   7474      * will not appear on screen until after the call to
   7475      * closeSurfaceTransaction.
   7476      *
   7477      * ActivityManager can use this to ensure multiple 'commands' will all
   7478      * be reflected in a single frame. For example when reparenting a window
   7479      * which was previously hidden due to it's parent properties, we may
   7480      * need to ensure it is hidden in the same frame that the properties
   7481      * from the new parent are inherited, otherwise it could be revealed
   7482      * mistakenly.
   7483      *
   7484      * TODO(b/36393204): We can investigate totally replacing #deferSurfaceLayout
   7485      * with something like this but it seems that some existing cases of
   7486      * deferSurfaceLayout may be a little too broad, in particular the total
   7487      * enclosure of startActivityUnchecked which could run for quite some time.
   7488      */
   7489     public void inSurfaceTransaction(Runnable exec) {
   7490         // We hold the WindowManger lock to ensure relayoutWindow
   7491         // does not return while a Surface transaction is opening.
   7492         // The client depends on us to have resized the surface
   7493         // by that point (b/36462635)
   7494 
   7495         synchronized (mWindowMap) {
   7496             SurfaceControl.openTransaction();
   7497             try {
   7498                 exec.run();
   7499             } finally {
   7500                 SurfaceControl.closeTransaction();
   7501             }
   7502         }
   7503     }
   7504 
   7505     /** Called to inform window manager if non-Vr UI shoul be disabled or not. */
   7506     public void disableNonVrUi(boolean disable) {
   7507         synchronized (mWindowMap) {
   7508             // Allow alert window notifications to be shown if non-vr UI is enabled.
   7509             final boolean showAlertWindowNotifications = !disable;
   7510             if (showAlertWindowNotifications == mShowAlertWindowNotifications) {
   7511                 return;
   7512             }
   7513             mShowAlertWindowNotifications = showAlertWindowNotifications;
   7514 
   7515             for (int i = mSessions.size() - 1; i >= 0; --i) {
   7516                 final Session s = mSessions.valueAt(i);
   7517                 s.setShowingAlertWindowNotificationAllowed(mShowAlertWindowNotifications);
   7518             }
   7519         }
   7520     }
   7521 
   7522     boolean hasWideColorGamutSupport() {
   7523         return mHasWideColorGamutSupport &&
   7524                 SystemProperties.getInt("persist.sys.sf.native_mode", 0) != 1;
   7525     }
   7526 
   7527     void updateNonSystemOverlayWindowsVisibilityIfNeeded(WindowState win, boolean surfaceShown) {
   7528         if (!win.hideNonSystemOverlayWindowsWhenVisible()
   7529                 && !mHidingNonSystemOverlayWindows.contains(win)) {
   7530             return;
   7531         }
   7532         final boolean systemAlertWindowsHidden = !mHidingNonSystemOverlayWindows.isEmpty();
   7533         if (surfaceShown) {
   7534             if (!mHidingNonSystemOverlayWindows.contains(win)) {
   7535                 mHidingNonSystemOverlayWindows.add(win);
   7536             }
   7537         } else {
   7538             mHidingNonSystemOverlayWindows.remove(win);
   7539         }
   7540 
   7541         final boolean hideSystemAlertWindows = !mHidingNonSystemOverlayWindows.isEmpty();
   7542 
   7543         if (systemAlertWindowsHidden == hideSystemAlertWindows) {
   7544             return;
   7545         }
   7546 
   7547         mRoot.forAllWindows((w) -> {
   7548             w.setForceHideNonSystemOverlayWindowIfNeeded(hideSystemAlertWindows);
   7549         }, false /* traverseTopToBottom */);
   7550     }
   7551 
   7552     public void applyMagnificationSpec(MagnificationSpec spec) {
   7553         getDefaultDisplayContentLocked().applyMagnificationSpec(spec);
   7554     }
   7555 
   7556     SurfaceControl.Builder makeSurfaceBuilder(SurfaceSession s) {
   7557         return mSurfaceBuilderFactory.make(s);
   7558     }
   7559 
   7560     void sendSetRunningRemoteAnimation(int pid, boolean runningRemoteAnimation) {
   7561         mH.obtainMessage(H.SET_RUNNING_REMOTE_ANIMATION, pid, runningRemoteAnimation ? 1 : 0)
   7562                 .sendToTarget();
   7563     }
   7564 
   7565     void startSeamlessRotation() {
   7566         // We are careful to reset this in case a window was removed before it finished
   7567         // seamless rotation.
   7568         mSeamlessRotationCount = 0;
   7569 
   7570         mRotatingSeamlessly = true;
   7571     }
   7572 
   7573     void finishSeamlessRotation() {
   7574         mRotatingSeamlessly = false;
   7575     }
   7576 
   7577     /**
   7578      * Called when the state of lock task mode changes. This should be used to disable immersive
   7579      * mode confirmation.
   7580      *
   7581      * @param lockTaskState the new lock task mode state. One of
   7582      *                      {@link ActivityManager#LOCK_TASK_MODE_NONE},
   7583      *                      {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
   7584      *                      {@link ActivityManager#LOCK_TASK_MODE_PINNED}.
   7585      */
   7586     public void onLockTaskStateChanged(int lockTaskState) {
   7587         synchronized (mWindowMap) {
   7588             mPolicy.onLockTaskStateChangedLw(lockTaskState);
   7589         }
   7590     }
   7591 
   7592     /**
   7593      * Updates {@link WindowManagerPolicy} with new value about whether AOD  is showing. If AOD
   7594      * has changed, this will trigger a {@link WindowSurfacePlacer#performSurfacePlacement} to
   7595      * ensure the new value takes effect.
   7596      */
   7597     public void setAodShowing(boolean aodShowing) {
   7598         synchronized (mWindowMap) {
   7599             if (mPolicy.setAodShowing(aodShowing)) {
   7600                 mWindowPlacerLocked.performSurfacePlacement();
   7601             }
   7602         }
   7603     }
   7604 }
   7605