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 android.Manifest;
     20 import android.animation.ValueAnimator;
     21 import android.annotation.IntDef;
     22 import android.annotation.NonNull;
     23 import android.annotation.Nullable;
     24 import android.app.ActivityManager;
     25 import android.app.ActivityManagerInternal;
     26 import android.app.ActivityManagerNative;
     27 import android.app.AppOpsManager;
     28 import android.app.IActivityManager;
     29 import android.app.Notification;
     30 import android.app.NotificationManager;
     31 import android.app.PendingIntent;
     32 import android.app.admin.DevicePolicyManager;
     33 import android.content.BroadcastReceiver;
     34 import android.content.ContentResolver;
     35 import android.content.Context;
     36 import android.content.Intent;
     37 import android.content.IntentFilter;
     38 import android.content.pm.ActivityInfo;
     39 import android.content.pm.ApplicationInfo;
     40 import android.content.pm.PackageManager;
     41 import android.content.res.CompatibilityInfo;
     42 import android.content.res.Configuration;
     43 import android.database.ContentObserver;
     44 import android.graphics.Bitmap;
     45 import android.graphics.PixelFormat;
     46 import android.graphics.Matrix;
     47 import android.graphics.Point;
     48 import android.graphics.Rect;
     49 import android.graphics.RectF;
     50 import android.graphics.Region;
     51 import android.hardware.display.DisplayManager;
     52 import android.hardware.display.DisplayManagerInternal;
     53 import android.hardware.input.InputManager;
     54 import android.net.Uri;
     55 import android.os.Binder;
     56 import android.os.Build;
     57 import android.os.Bundle;
     58 import android.os.Debug;
     59 import android.os.Handler;
     60 import android.os.IBinder;
     61 import android.os.IRemoteCallback;
     62 import android.os.Looper;
     63 import android.os.Message;
     64 import android.os.Parcel;
     65 import android.os.ParcelFileDescriptor;
     66 import android.os.PowerManager;
     67 import android.os.PowerManagerInternal;
     68 import android.os.Process;
     69 import android.os.RemoteException;
     70 import android.os.ServiceManager;
     71 import android.os.StrictMode;
     72 import android.os.SystemClock;
     73 import android.os.SystemProperties;
     74 import android.os.SystemService;
     75 import android.os.Trace;
     76 import android.os.UserHandle;
     77 import android.os.WorkSource;
     78 import android.provider.Settings;
     79 import android.util.ArraySet;
     80 import android.util.DisplayMetrics;
     81 import android.util.EventLog;
     82 import android.util.Log;
     83 import android.util.Pair;
     84 import android.util.Slog;
     85 import android.util.SparseArray;
     86 import android.util.SparseIntArray;
     87 import android.util.TimeUtils;
     88 import android.util.TypedValue;
     89 import android.view.AppTransitionAnimationSpec;
     90 import android.view.Choreographer;
     91 import android.view.Display;
     92 import android.view.DisplayInfo;
     93 import android.view.Gravity;
     94 import android.view.PointerIcon;
     95 import android.view.IAppTransitionAnimationSpecsFuture;
     96 import android.view.IApplicationToken;
     97 import android.view.IDockedStackListener;
     98 import android.view.IInputFilter;
     99 import android.view.IOnKeyguardExitResult;
    100 import android.view.IRotationWatcher;
    101 import android.view.IWindow;
    102 import android.view.IWindowId;
    103 import android.view.IWindowManager;
    104 import android.view.IWindowSession;
    105 import android.view.IWindowSessionCallback;
    106 import android.view.InputChannel;
    107 import android.view.InputDevice;
    108 import android.view.InputEvent;
    109 import android.view.InputEventReceiver;
    110 import android.view.KeyEvent;
    111 import android.view.MagnificationSpec;
    112 import android.view.MotionEvent;
    113 import android.view.Surface;
    114 import android.view.Surface.OutOfResourcesException;
    115 import android.view.SurfaceControl;
    116 import android.view.SurfaceSession;
    117 import android.view.View;
    118 import android.view.WindowContentFrameStats;
    119 import android.view.WindowManager;
    120 import android.view.WindowManager.LayoutParams;
    121 import android.view.WindowManagerGlobal;
    122 import android.view.WindowManagerInternal;
    123 import android.view.WindowManagerPolicy;
    124 import android.view.WindowManagerPolicy.PointerEventListener;
    125 import android.view.animation.Animation;
    126 import android.view.inputmethod.InputMethodManagerInternal;
    127 
    128 import com.android.internal.R;
    129 import com.android.internal.app.IAssistScreenshotReceiver;
    130 import com.android.internal.os.IResultReceiver;
    131 import com.android.internal.policy.IShortcutService;
    132 import com.android.internal.util.ArrayUtils;
    133 import com.android.internal.util.FastPrintWriter;
    134 import com.android.internal.view.IInputContext;
    135 import com.android.internal.view.IInputMethodClient;
    136 import com.android.internal.view.IInputMethodManager;
    137 import com.android.internal.view.WindowManagerPolicyThread;
    138 import com.android.server.AttributeCache;
    139 import com.android.server.DisplayThread;
    140 import com.android.server.EventLogTags;
    141 import com.android.server.FgThread;
    142 import com.android.server.LocalServices;
    143 import com.android.server.UiThread;
    144 import com.android.server.Watchdog;
    145 import com.android.server.input.InputManagerService;
    146 import com.android.server.policy.PhoneWindowManager;
    147 import com.android.server.power.ShutdownThread;
    148 
    149 import java.io.BufferedWriter;
    150 import java.io.DataInputStream;
    151 import java.io.File;
    152 import java.io.FileDescriptor;
    153 import java.io.FileInputStream;
    154 import java.io.FileNotFoundException;
    155 import java.io.IOException;
    156 import java.io.OutputStream;
    157 import java.io.OutputStreamWriter;
    158 import java.io.PrintWriter;
    159 import java.io.StringWriter;
    160 import java.lang.annotation.Retention;
    161 import java.lang.annotation.RetentionPolicy;
    162 import java.net.Socket;
    163 import java.text.DateFormat;
    164 import java.util.ArrayList;
    165 import java.util.Arrays;
    166 import java.util.Date;
    167 import java.util.HashMap;
    168 import java.util.Iterator;
    169 import java.util.List;
    170 
    171 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
    172 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
    173 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
    174 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
    175 import static android.app.StatusBarManager.DISABLE_MASK;
    176 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
    177 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    178 import static android.view.WindowManager.DOCKED_BOTTOM;
    179 import static android.view.WindowManager.DOCKED_INVALID;
    180 import static android.view.WindowManager.DOCKED_TOP;
    181 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
    182 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
    183 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
    184 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
    185 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
    186 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
    187 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
    188 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
    189 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
    190 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
    191 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
    192 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
    193 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
    194 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
    195 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
    196 import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
    197 import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
    198 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
    199 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
    200 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
    201 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
    202 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
    203 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
    204 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
    205 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
    206 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
    207 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
    208 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
    209 import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
    210 import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
    211 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
    212 import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
    213 import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
    214 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
    215 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
    216 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
    217 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
    218 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
    219 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
    220 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
    221 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_ORIENTATION;
    222 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
    223 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
    224 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
    225 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
    226 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
    227 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
    228 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
    229 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
    230 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
    231 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
    232 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
    233 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
    234 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
    235 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
    236 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
    237 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
    238 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
    239 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
    240 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
    241 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
    242 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
    243 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
    244 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
    245 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
    246 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
    247 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
    248 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
    249 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
    250 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
    251 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
    252 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
    253 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
    254 import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
    255 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
    256 
    257 /** {@hide} */
    258 public class WindowManagerService extends IWindowManager.Stub
    259         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
    260     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowManagerService" : TAG_WM;
    261 
    262     static final int LAYOUT_REPEAT_THRESHOLD = 4;
    263 
    264     static final boolean PROFILE_ORIENTATION = false;
    265     static final boolean localLOGV = DEBUG;
    266 
    267     /** How much to multiply the policy's type layer, to reserve room
    268      * for multiple windows of the same type and Z-ordering adjustment
    269      * with TYPE_LAYER_OFFSET. */
    270     static final int TYPE_LAYER_MULTIPLIER = 10000;
    271 
    272     /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
    273      * or below others in the same layer. */
    274     static final int TYPE_LAYER_OFFSET = 1000;
    275 
    276     /** How much to increment the layer for each window, to reserve room
    277      * for effect surfaces between them.
    278      */
    279     static final int WINDOW_LAYER_MULTIPLIER = 5;
    280 
    281     /**
    282      * Dim surface layer is immediately below target window.
    283      */
    284     static final int LAYER_OFFSET_DIM = 1;
    285 
    286     /**
    287      * Animation thumbnail is as far as possible below the window above
    288      * the thumbnail (or in other words as far as possible above the window
    289      * below it).
    290      */
    291     static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER - 1;
    292 
    293     /** The maximum length we will accept for a loaded animation duration:
    294      * this is 10 seconds.
    295      */
    296     static final int MAX_ANIMATION_DURATION = 10 * 1000;
    297 
    298     /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
    299     static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
    300 
    301     /** Amount of time (in milliseconds) to delay before declaring a seamless rotation timeout. */
    302     static final int SEAMLESS_ROTATION_TIMEOUT_DURATION = 2000;
    303 
    304     /** Amount of time (in milliseconds) to delay before declaring a window replacement timeout. */
    305     static final int WINDOW_REPLACEMENT_TIMEOUT_DURATION = 2000;
    306 
    307     /** Amount of time to allow a last ANR message to exist before freeing the memory. */
    308     static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
    309     /**
    310      * If true, the window manager will do its own custom freezing and general
    311      * management of the screen during rotation.
    312      */
    313     static final boolean CUSTOM_SCREEN_ROTATION = true;
    314 
    315     // Maximum number of milliseconds to wait for input devices to be enumerated before
    316     // proceding with safe mode detection.
    317     private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
    318 
    319     // Default input dispatching timeout in nanoseconds.
    320     static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
    321 
    322     // Poll interval in milliseconds for watching boot animation finished.
    323     private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
    324 
    325     // The name of the boot animation service in init.rc.
    326     private static final String BOOT_ANIMATION_SERVICE = "bootanim";
    327 
    328     static final int UPDATE_FOCUS_NORMAL = 0;
    329     static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
    330     static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
    331     static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
    332 
    333     private static final String SYSTEM_SECURE = "ro.secure";
    334     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
    335 
    336     private static final String DENSITY_OVERRIDE = "ro.config.density_override";
    337     private static final String SIZE_OVERRIDE = "ro.config.size_override";
    338 
    339     private static final int MAX_SCREENSHOT_RETRIES = 3;
    340 
    341     private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
    342 
    343     // Used to indicate that if there is already a transition set, it should be preserved when
    344     // trying to apply a new one.
    345     private static final boolean ALWAYS_KEEP_CURRENT = true;
    346 
    347     private static final float DRAG_SHADOW_ALPHA_TRANSPARENT = .7071f;
    348 
    349     private static final String PROPERTY_BUILD_DATE_UTC = "ro.build.date.utc";
    350 
    351     // Enums for animation scale update types.
    352     @Retention(RetentionPolicy.SOURCE)
    353     @IntDef({WINDOW_ANIMATION_SCALE, TRANSITION_ANIMATION_SCALE, ANIMATION_DURATION_SCALE})
    354     private @interface UpdateAnimationScaleMode {};
    355     private static final int WINDOW_ANIMATION_SCALE = 0;
    356     private static final int TRANSITION_ANIMATION_SCALE = 1;
    357     private static final int ANIMATION_DURATION_SCALE = 2;
    358 
    359     final private KeyguardDisableHandler mKeyguardDisableHandler;
    360 
    361     final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    362         @Override
    363         public void onReceive(Context context, Intent intent) {
    364             final String action = intent.getAction();
    365             if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
    366                 mKeyguardDisableHandler.sendEmptyMessage(
    367                     KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
    368             }
    369         }
    370     };
    371     final WindowSurfacePlacer mWindowPlacerLocked;
    372 
    373     /**
    374      * Current user when multi-user is enabled. Don't show windows of
    375      * non-current user. Also see mCurrentProfileIds.
    376      */
    377     int mCurrentUserId;
    378     /**
    379      * Users that are profiles of the current user. These are also allowed to show windows
    380      * on the current user.
    381      */
    382     int[] mCurrentProfileIds = new int[] {};
    383 
    384     final Context mContext;
    385 
    386     final boolean mHaveInputMethods;
    387 
    388     final boolean mHasPermanentDpad;
    389     final long mDrawLockTimeoutMillis;
    390     final boolean mAllowAnimationsInLowPowerMode;
    391 
    392     final boolean mAllowBootMessages;
    393 
    394     final boolean mLimitedAlphaCompositing;
    395 
    396     final WindowManagerPolicy mPolicy = new PhoneWindowManager();
    397 
    398     final IActivityManager mActivityManager;
    399     final ActivityManagerInternal mAmInternal;
    400 
    401     final AppOpsManager mAppOps;
    402 
    403     final DisplaySettings mDisplaySettings;
    404 
    405     /**
    406      * All currently active sessions with clients.
    407      */
    408     final ArraySet<Session> mSessions = new ArraySet<>();
    409 
    410     /**
    411      * Mapping from an IWindow IBinder to the server's Window object.
    412      * This is also used as the lock for all of our state.
    413      * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
    414      */
    415     final HashMap<IBinder, WindowState> mWindowMap = new HashMap<>();
    416 
    417     /**
    418      * Mapping from a token IBinder to a WindowToken object.
    419      */
    420     final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<>();
    421 
    422     /**
    423      * List of window tokens that have finished starting their application,
    424      * and now need to have the policy remove their windows.
    425      */
    426     final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<>();
    427 
    428     /**
    429      * List of window tokens that have finished drawing their own windows and
    430      * no longer need to show any saved surfaces. Windows that's still showing
    431      * saved surfaces will be cleaned up after next animation pass.
    432      */
    433     final ArrayList<AppWindowToken> mFinishedEarlyAnim = new ArrayList<>();
    434 
    435     /**
    436      * List of app window tokens that are waiting for replacing windows. If the
    437      * replacement doesn't come in time the stale windows needs to be disposed of.
    438      */
    439     final ArrayList<AppWindowToken> mReplacingWindowTimeouts = new ArrayList<>();
    440 
    441     /**
    442      * The input consumer added to the window manager which consumes input events to windows below
    443      * it.
    444      */
    445     InputConsumerImpl mInputConsumer;
    446 
    447     /**
    448      * The input consumer added to the window manager before all wallpaper windows.
    449      */
    450     InputConsumerImpl mWallpaperInputConsumer;
    451 
    452     /**
    453      * Windows that are being resized.  Used so we can tell the client about
    454      * the resize after closing the transaction in which we resized the
    455      * underlying surface.
    456      */
    457     final ArrayList<WindowState> mResizingWindows = new ArrayList<>();
    458 
    459     /**
    460      * Windows whose animations have ended and now must be removed.
    461      */
    462     final ArrayList<WindowState> mPendingRemove = new ArrayList<>();
    463 
    464     /**
    465      * Used when processing mPendingRemove to avoid working on the original array.
    466      */
    467     WindowState[] mPendingRemoveTmp = new WindowState[20];
    468 
    469     /**
    470      * Windows whose surface should be destroyed.
    471      */
    472     final ArrayList<WindowState> mDestroySurface = new ArrayList<>();
    473 
    474     /**
    475      * Windows with a preserved surface waiting to be destroyed. These windows
    476      * are going through a surface change. We keep the old surface around until
    477      * the first frame on the new surface finishes drawing.
    478      */
    479     final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();
    480 
    481     /**
    482      * Windows that have lost input focus and are waiting for the new
    483      * focus window to be displayed before they are told about this.
    484      */
    485     ArrayList<WindowState> mLosingFocus = new ArrayList<>();
    486 
    487     /**
    488      * This is set when we have run out of memory, and will either be an empty
    489      * list or contain windows that need to be force removed.
    490      */
    491     final ArrayList<WindowState> mForceRemoves = new ArrayList<>();
    492 
    493     /**
    494      * Windows that clients are waiting to have drawn.
    495      */
    496     ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
    497     /**
    498      * And the callback to make when they've all been drawn.
    499      */
    500     Runnable mWaitingForDrawnCallback;
    501 
    502     /**
    503      * Used when rebuilding window list to keep track of windows that have
    504      * been removed.
    505      */
    506     WindowState[] mRebuildTmp = new WindowState[20];
    507 
    508     /**
    509      * Stores for each user whether screencapture is disabled
    510      * This array is essentially a cache for all userId for
    511      * {@link android.app.admin.DevicePolicyManager#getScreenCaptureDisabled}
    512      */
    513     SparseArray<Boolean> mScreenCaptureDisabled = new SparseArray<>();
    514 
    515     IInputMethodManager mInputMethodManager;
    516 
    517     AccessibilityController mAccessibilityController;
    518 
    519     final SurfaceSession mFxSession;
    520     Watermark mWatermark;
    521     StrictModeFlash mStrictModeFlash;
    522     CircularDisplayMask mCircularDisplayMask;
    523     EmulatorDisplayOverlay mEmulatorDisplayOverlay;
    524 
    525     final float[] mTmpFloats = new float[9];
    526     final Rect mTmpRect = new Rect();
    527     final Rect mTmpRect2 = new Rect();
    528     final Rect mTmpRect3 = new Rect();
    529     final RectF mTmpRectF = new RectF();
    530 
    531     final Matrix mTmpTransform = new Matrix();
    532 
    533     boolean mDisplayReady;
    534     boolean mSafeMode;
    535     boolean mDisplayEnabled = false;
    536     boolean mSystemBooted = false;
    537     boolean mForceDisplayEnabled = false;
    538     boolean mShowingBootMessages = false;
    539     boolean mBootAnimationStopped = false;
    540 
    541     // Following variables are for debugging screen wakelock only.
    542     WindowState mLastWakeLockHoldingWindow = null;
    543     WindowState mLastWakeLockObscuringWindow = null;
    544 
    545     /** Dump of the windows and app tokens at the time of the last ANR. Cleared after
    546      * LAST_ANR_LIFETIME_DURATION_MSECS */
    547     String mLastANRState;
    548 
    549     /** All DisplayContents in the world, kept here */
    550     SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
    551 
    552     int mRotation = 0;
    553     int mLastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    554     boolean mAltOrientation = false;
    555 
    556     private boolean mKeyguardWaitingForActivityDrawn;
    557 
    558     int mDockedStackCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
    559     Rect mDockedStackCreateBounds;
    560 
    561     private final SparseIntArray mTmpTaskIds = new SparseIntArray();
    562 
    563     private final ArrayList<Integer> mChangedStackList = new ArrayList();
    564 
    565     boolean mForceResizableTasks = false;
    566 
    567     int getDragLayerLocked() {
    568         return mPolicy.windowTypeToLayerLw(LayoutParams.TYPE_DRAG) * TYPE_LAYER_MULTIPLIER
    569                 + TYPE_LAYER_OFFSET;
    570     }
    571 
    572     class RotationWatcher {
    573         IRotationWatcher watcher;
    574         IBinder.DeathRecipient deathRecipient;
    575         RotationWatcher(IRotationWatcher w, IBinder.DeathRecipient d) {
    576             watcher = w;
    577             deathRecipient = d;
    578         }
    579     }
    580     ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
    581     int mDeferredRotationPauseCount;
    582 
    583     int mSystemDecorLayer = 0;
    584     final Rect mScreenRect = new Rect();
    585 
    586     boolean mDisplayFrozen = false;
    587     long mDisplayFreezeTime = 0;
    588     int mLastDisplayFreezeDuration = 0;
    589     Object mLastFinishedFreezeSource = null;
    590     boolean mWaitingForConfig = false;
    591 
    592     final static int WINDOWS_FREEZING_SCREENS_NONE = 0;
    593     final static int WINDOWS_FREEZING_SCREENS_ACTIVE = 1;
    594     final static int WINDOWS_FREEZING_SCREENS_TIMEOUT = 2;
    595     int mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
    596 
    597     boolean mClientFreezingScreen = false;
    598     int mAppsFreezingScreen = 0;
    599     int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    600     int mLastKeyguardForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    601 
    602     int mLayoutSeq = 0;
    603 
    604     // Last systemUiVisibility we received from status bar.
    605     int mLastStatusBarVisibility = 0;
    606     // Last systemUiVisibility we dispatched to windows.
    607     int mLastDispatchedSystemUiVisibility = 0;
    608 
    609     // State while inside of layoutAndPlaceSurfacesLocked().
    610     boolean mFocusMayChange;
    611 
    612     Configuration mCurConfiguration = new Configuration();
    613 
    614     // This is held as long as we have the screen frozen, to give us time to
    615     // perform a rotation animation when turning off shows the lock screen which
    616     // changes the orientation.
    617     private final PowerManager.WakeLock mScreenFrozenLock;
    618 
    619     final AppTransition mAppTransition;
    620     boolean mSkipAppTransitionAnimation = false;
    621 
    622     final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>();
    623     final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>();
    624 
    625     boolean mIsTouchDevice;
    626 
    627     final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
    628     final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
    629     final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
    630     final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
    631 
    632     final H mH = new H();
    633 
    634     final Choreographer mChoreographer = Choreographer.getInstance();
    635 
    636     WindowState mCurrentFocus = null;
    637     WindowState mLastFocus = null;
    638 
    639     /** This just indicates the window the input method is on top of, not
    640      * necessarily the window its input is going to. */
    641     WindowState mInputMethodTarget = null;
    642 
    643     /** If true hold off on modifying the animation layer of mInputMethodTarget */
    644     boolean mInputMethodTargetWaitingAnim;
    645 
    646     WindowState mInputMethodWindow = null;
    647     final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
    648 
    649     /** Temporary list for comparison. Always clear this after use so we don't end up with
    650      * orphaned windows references */
    651     final ArrayList<WindowState> mTmpWindows = new ArrayList<>();
    652 
    653     boolean mHardKeyboardAvailable;
    654     WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
    655     SettingsObserver mSettingsObserver;
    656 
    657     // A count of the windows which are 'seamlessly rotated', e.g. a surface
    658     // at an old orientation is being transformed. We freeze orientation updates
    659     // while any windows are seamlessly rotated, so we need to track when this
    660     // hits zero so we can apply deferred orientation updates.
    661     int mSeamlessRotationCount = 0;
    662 
    663     private final class SettingsObserver extends ContentObserver {
    664         private final Uri mDisplayInversionEnabledUri =
    665                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
    666         private final Uri mWindowAnimationScaleUri =
    667                 Settings.Global.getUriFor(Settings.Global.WINDOW_ANIMATION_SCALE);
    668         private final Uri mTransitionAnimationScaleUri =
    669                 Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE);
    670         private final Uri mAnimationDurationScaleUri =
    671                 Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE);
    672 
    673         public SettingsObserver() {
    674             super(new Handler());
    675             ContentResolver resolver = mContext.getContentResolver();
    676             resolver.registerContentObserver(mDisplayInversionEnabledUri, false, this,
    677                     UserHandle.USER_ALL);
    678             resolver.registerContentObserver(mWindowAnimationScaleUri, false, this,
    679                     UserHandle.USER_ALL);
    680             resolver.registerContentObserver(mTransitionAnimationScaleUri, false, this,
    681                     UserHandle.USER_ALL);
    682             resolver.registerContentObserver(mAnimationDurationScaleUri, false, this,
    683                     UserHandle.USER_ALL);
    684         }
    685 
    686         @Override
    687         public void onChange(boolean selfChange, Uri uri) {
    688             if (uri == null) {
    689                 return;
    690             }
    691 
    692             if (mDisplayInversionEnabledUri.equals(uri)) {
    693                 updateCircularDisplayMaskIfNeeded();
    694             } else {
    695                 @UpdateAnimationScaleMode
    696                 final int mode;
    697                 if (mWindowAnimationScaleUri.equals(uri)) {
    698                     mode = WINDOW_ANIMATION_SCALE;
    699                 } else if (mTransitionAnimationScaleUri.equals(uri)) {
    700                     mode = TRANSITION_ANIMATION_SCALE;
    701                 } else if (mAnimationDurationScaleUri.equals(uri)) {
    702                     mode = ANIMATION_DURATION_SCALE;
    703                 } else {
    704                     // Ignoring unrecognized content changes
    705                     return;
    706                 }
    707                 Message m = mH.obtainMessage(H.UPDATE_ANIMATION_SCALE, mode, 0);
    708                 mH.sendMessage(m);
    709             }
    710         }
    711     }
    712 
    713     WallpaperController mWallpaperControllerLocked;
    714 
    715     final WindowLayersController mLayersController;
    716 
    717     boolean mAnimateWallpaperWithTarget;
    718 
    719     AppWindowToken mFocusedApp = null;
    720 
    721     PowerManager mPowerManager;
    722     PowerManagerInternal mPowerManagerInternal;
    723 
    724     float mWindowAnimationScaleSetting = 1.0f;
    725     float mTransitionAnimationScaleSetting = 1.0f;
    726     float mAnimatorDurationScaleSetting = 1.0f;
    727     boolean mAnimationsDisabled = false;
    728 
    729     final InputManagerService mInputManager;
    730     final DisplayManagerInternal mDisplayManagerInternal;
    731     final DisplayManager mDisplayManager;
    732     final Display[] mDisplays;
    733 
    734     // Who is holding the screen on.
    735     Session mHoldingScreenOn;
    736     PowerManager.WakeLock mHoldingScreenWakeLock;
    737 
    738     boolean mTurnOnScreen;
    739 
    740     // Whether or not a layout can cause a wake up when theater mode is enabled.
    741     boolean mAllowTheaterModeWakeFromLayout;
    742 
    743     TaskPositioner mTaskPositioner;
    744     DragState mDragState = null;
    745 
    746     // For frozen screen animations.
    747     int mExitAnimId, mEnterAnimId;
    748 
    749     boolean mAnimationScheduled;
    750 
    751     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
    752      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
    753     int mTransactionSequence;
    754 
    755     final WindowAnimator mAnimator;
    756 
    757     private final BoundsAnimationController mBoundsAnimationController;
    758 
    759     SparseArray<Task> mTaskIdToTask = new SparseArray<>();
    760 
    761     /** All of the TaskStacks in the window manager, unordered. For an ordered list call
    762      * DisplayContent.getStacks(). */
    763     SparseArray<TaskStack> mStackIdToStack = new SparseArray<>();
    764 
    765     private final PointerEventDispatcher mPointerEventDispatcher;
    766 
    767     private WindowContentFrameStats mTempWindowRenderStats;
    768 
    769     final class DragInputEventReceiver extends InputEventReceiver {
    770         // Set, if stylus button was down at the start of the drag.
    771         private boolean mStylusButtonDownAtStart;
    772         // Indicates the first event to check for button state.
    773         private boolean mIsStartEvent = true;
    774 
    775         public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
    776             super(inputChannel, looper);
    777         }
    778 
    779         @Override
    780         public void onInputEvent(InputEvent event) {
    781             boolean handled = false;
    782             try {
    783                 if (event instanceof MotionEvent
    784                         && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
    785                         && mDragState != null) {
    786                     final MotionEvent motionEvent = (MotionEvent)event;
    787                     boolean endDrag = false;
    788                     final float newX = motionEvent.getRawX();
    789                     final float newY = motionEvent.getRawY();
    790                     final boolean isStylusButtonDown =
    791                             (motionEvent.getButtonState() & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0;
    792 
    793                     if (mIsStartEvent) {
    794                         if (isStylusButtonDown) {
    795                             // First event and the button was down, check for the button being
    796                             // lifted in the future, if that happens we'll drop the item.
    797                             mStylusButtonDownAtStart = true;
    798                         }
    799                         mIsStartEvent = false;
    800                     }
    801 
    802                     switch (motionEvent.getAction()) {
    803                     case MotionEvent.ACTION_DOWN: {
    804                         if (DEBUG_DRAG) {
    805                             Slog.w(TAG_WM, "Unexpected ACTION_DOWN in drag layer");
    806                         }
    807                     } break;
    808 
    809                     case MotionEvent.ACTION_MOVE: {
    810                         if (mStylusButtonDownAtStart && !isStylusButtonDown) {
    811                             if (DEBUG_DRAG) Slog.d(TAG_WM, "Button no longer pressed; dropping at "
    812                                     + newX + "," + newY);
    813                             synchronized (mWindowMap) {
    814                                 endDrag = mDragState.notifyDropLw(newX, newY);
    815                             }
    816                         } else {
    817                             synchronized (mWindowMap) {
    818                                 // move the surface and tell the involved window(s) where we are
    819                                 mDragState.notifyMoveLw(newX, newY);
    820                             }
    821                         }
    822                     } break;
    823 
    824                     case MotionEvent.ACTION_UP: {
    825                         if (DEBUG_DRAG) Slog.d(TAG_WM, "Got UP on move channel; dropping at "
    826                                 + newX + "," + newY);
    827                         synchronized (mWindowMap) {
    828                             endDrag = mDragState.notifyDropLw(newX, newY);
    829                         }
    830                     } break;
    831 
    832                     case MotionEvent.ACTION_CANCEL: {
    833                         if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag cancelled!");
    834                         endDrag = true;
    835                     } break;
    836                     }
    837 
    838                     if (endDrag) {
    839                         if (DEBUG_DRAG) Slog.d(TAG_WM, "Drag ended; tearing down state");
    840                         // tell all the windows that the drag has ended
    841                         synchronized (mWindowMap) {
    842                             mDragState.endDragLw();
    843                         }
    844                         mStylusButtonDownAtStart = false;
    845                         mIsStartEvent = true;
    846                     }
    847 
    848                     handled = true;
    849                 }
    850             } catch (Exception e) {
    851                 Slog.e(TAG_WM, "Exception caught by drag handleMotion", e);
    852             } finally {
    853                 finishInputEvent(event, handled);
    854             }
    855         }
    856     }
    857 
    858     /**
    859      * Whether the UI is currently running in touch mode (not showing
    860      * navigational focus because the user is directly pressing the screen).
    861      */
    862     boolean mInTouchMode;
    863 
    864     private ViewServer mViewServer;
    865     final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
    866     boolean mWindowsChanged = false;
    867 
    868     public interface WindowChangeListener {
    869         public void windowsChanged();
    870         public void focusChanged();
    871     }
    872 
    873     final Configuration mTempConfiguration = new Configuration();
    874 
    875     // The desired scaling factor for compatible apps.
    876     float mCompatibleScreenScale;
    877 
    878     // If true, only the core apps and services are being launched because the device
    879     // is in a special boot mode, such as being encrypted or waiting for a decryption password.
    880     // For example, when this flag is true, there will be no wallpaper service.
    881     final boolean mOnlyCore;
    882 
    883     // List of clients without a transtiton animation that we notify once we are done transitioning
    884     // since they won't be notified through the app window animator.
    885     final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
    886 
    887     // List of displays to reconfigure after configuration changes.
    888     // Some of the information reported for a display is dependent on resources to do the right
    889     // calculations. For example, {@link DisplayInfo#smallestNominalAppWidth} and company are
    890     // dependent on the height and width of the status and nav bar which change depending on the
    891     // current configuration.
    892     private final DisplayContentList mReconfigureOnConfigurationChanged = new DisplayContentList();
    893 
    894     /** Listener to notify activity manager about app transitions. */
    895     private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
    896             = new WindowManagerInternal.AppTransitionListener() {
    897 
    898         @Override
    899         public void onAppTransitionCancelledLocked() {
    900             mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_CANCELLED);
    901         }
    902 
    903         @Override
    904         public void onAppTransitionFinishedLocked(IBinder token) {
    905             mH.sendEmptyMessage(H.NOTIFY_APP_TRANSITION_FINISHED);
    906             AppWindowToken atoken = findAppWindowToken(token);
    907             if (atoken == null) {
    908                 return;
    909             }
    910             if (atoken.mLaunchTaskBehind) {
    911                 try {
    912                     mActivityManager.notifyLaunchTaskBehindComplete(atoken.token);
    913                 } catch (RemoteException e) {
    914                 }
    915                 atoken.mLaunchTaskBehind = false;
    916             } else {
    917                 atoken.updateReportedVisibilityLocked();
    918                 if (atoken.mEnteringAnimation) {
    919                     atoken.mEnteringAnimation = false;
    920                     try {
    921                         mActivityManager.notifyEnterAnimationComplete(atoken.token);
    922                     } catch (RemoteException e) {
    923                     }
    924                 }
    925             }
    926         }
    927     };
    928 
    929     public static WindowManagerService main(final Context context,
    930             final InputManagerService im,
    931             final boolean haveInputMethods, final boolean showBootMsgs,
    932             final boolean onlyCore) {
    933         final WindowManagerService[] holder = new WindowManagerService[1];
    934         DisplayThread.getHandler().runWithScissors(new Runnable() {
    935             @Override
    936             public void run() {
    937                 holder[0] = new WindowManagerService(context, im,
    938                         haveInputMethods, showBootMsgs, onlyCore);
    939             }
    940         }, 0);
    941         return holder[0];
    942     }
    943 
    944     private void initPolicy() {
    945         UiThread.getHandler().runWithScissors(new Runnable() {
    946             @Override
    947             public void run() {
    948                 WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
    949 
    950                 mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
    951             }
    952         }, 0);
    953     }
    954 
    955     private WindowManagerService(Context context, InputManagerService inputManager,
    956             boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
    957         mContext = context;
    958         mHaveInputMethods = haveInputMethods;
    959         mAllowBootMessages = showBootMsgs;
    960         mOnlyCore = onlyCore;
    961         mLimitedAlphaCompositing = context.getResources().getBoolean(
    962                 com.android.internal.R.bool.config_sf_limitedAlpha);
    963         mHasPermanentDpad = context.getResources().getBoolean(
    964                 com.android.internal.R.bool.config_hasPermanentDpad);
    965         mInTouchMode = context.getResources().getBoolean(
    966                 com.android.internal.R.bool.config_defaultInTouchMode);
    967         mDrawLockTimeoutMillis = context.getResources().getInteger(
    968                 com.android.internal.R.integer.config_drawLockTimeoutMillis);
    969         mAllowAnimationsInLowPowerMode = context.getResources().getBoolean(
    970                 com.android.internal.R.bool.config_allowAnimationsInLowPowerMode);
    971         mInputManager = inputManager; // Must be before createDisplayContentLocked.
    972         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
    973         mDisplaySettings = new DisplaySettings();
    974         mDisplaySettings.readSettingsLocked();
    975 
    976         mWallpaperControllerLocked = new WallpaperController(this);
    977         mWindowPlacerLocked = new WindowSurfacePlacer(this);
    978         mLayersController = new WindowLayersController(this);
    979 
    980         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
    981 
    982         mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG_WM));
    983 
    984         mFxSession = new SurfaceSession();
    985         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
    986         mDisplays = mDisplayManager.getDisplays();
    987         for (Display display : mDisplays) {
    988             createDisplayContentLocked(display);
    989         }
    990 
    991         mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
    992 
    993         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
    994         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
    995         mPowerManagerInternal.registerLowPowerModeObserver(
    996                 new PowerManagerInternal.LowPowerModeListener() {
    997             @Override
    998             public void onLowPowerModeChanged(boolean enabled) {
    999                 synchronized (mWindowMap) {
   1000                     if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {
   1001                         mAnimationsDisabled = enabled;
   1002                         dispatchNewAnimatorScaleLocked(null);
   1003                     }
   1004                 }
   1005             }
   1006         });
   1007         mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled();
   1008         mScreenFrozenLock = mPowerManager.newWakeLock(
   1009                 PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
   1010         mScreenFrozenLock.setReferenceCounted(false);
   1011 
   1012         mAppTransition = new AppTransition(context, this);
   1013         mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
   1014 
   1015         mBoundsAnimationController =
   1016                 new BoundsAnimationController(mAppTransition, UiThread.getHandler());
   1017 
   1018         mActivityManager = ActivityManagerNative.getDefault();
   1019         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
   1020         mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
   1021         AppOpsManager.OnOpChangedInternalListener opListener =
   1022                 new AppOpsManager.OnOpChangedInternalListener() {
   1023                     @Override public void onOpChanged(int op, String packageName) {
   1024                         updateAppOpsState();
   1025                     }
   1026                 };
   1027         mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null, opListener);
   1028         mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
   1029 
   1030         // Get persisted window scale setting
   1031         mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
   1032                 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
   1033         mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
   1034                 Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScaleSetting);
   1035         setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
   1036                 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
   1037 
   1038         // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
   1039         IntentFilter filter = new IntentFilter();
   1040         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
   1041         mContext.registerReceiver(mBroadcastReceiver, filter);
   1042 
   1043         mSettingsObserver = new SettingsObserver();
   1044 
   1045         mHoldingScreenWakeLock = mPowerManager.newWakeLock(
   1046                 PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG_WM);
   1047         mHoldingScreenWakeLock.setReferenceCounted(false);
   1048 
   1049         mAnimator = new WindowAnimator(this);
   1050 
   1051         mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean(
   1052                 com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
   1053 
   1054 
   1055         LocalServices.addService(WindowManagerInternal.class, new LocalService());
   1056         initPolicy();
   1057 
   1058         // Add ourself to the Watchdog monitors.
   1059         Watchdog.getInstance().addMonitor(this);
   1060 
   1061         SurfaceControl.openTransaction();
   1062         try {
   1063             createWatermarkInTransaction();
   1064         } finally {
   1065             SurfaceControl.closeTransaction();
   1066         }
   1067 
   1068         showEmulatorDisplayOverlayIfNeeded();
   1069     }
   1070 
   1071     public InputMonitor getInputMonitor() {
   1072         return mInputMonitor;
   1073     }
   1074 
   1075     @Override
   1076     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   1077             throws RemoteException {
   1078         try {
   1079             return super.onTransact(code, data, reply, flags);
   1080         } catch (RuntimeException e) {
   1081             // The window manager only throws security exceptions, so let's
   1082             // log all others.
   1083             if (!(e instanceof SecurityException)) {
   1084                 Slog.wtf(TAG_WM, "Window Manager Crash", e);
   1085             }
   1086             throw e;
   1087         }
   1088     }
   1089 
   1090     private void placeWindowAfter(WindowState pos, WindowState window) {
   1091         final WindowList windows = pos.getWindowList();
   1092         final int i = windows.indexOf(pos);
   1093         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
   1094             TAG_WM, "Adding window " + window + " at "
   1095             + (i+1) + " of " + windows.size() + " (after " + pos + ")");
   1096         windows.add(i+1, window);
   1097         mWindowsChanged = true;
   1098     }
   1099 
   1100     private void placeWindowBefore(WindowState pos, WindowState window) {
   1101         final WindowList windows = pos.getWindowList();
   1102         int i = windows.indexOf(pos);
   1103         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
   1104             TAG_WM, "Adding window " + window + " at "
   1105             + i + " of " + windows.size() + " (before " + pos + ")");
   1106         if (i < 0) {
   1107             Slog.w(TAG_WM, "placeWindowBefore: Unable to find " + pos + " in " + windows);
   1108             i = 0;
   1109         }
   1110         windows.add(i, window);
   1111         mWindowsChanged = true;
   1112     }
   1113 
   1114     //This method finds out the index of a window that has the same app token as
   1115     //win. used for z ordering the windows in mWindows
   1116     private int findIdxBasedOnAppTokens(WindowState win) {
   1117         WindowList windows = win.getWindowList();
   1118         for(int j = windows.size() - 1; j >= 0; j--) {
   1119             WindowState wentry = windows.get(j);
   1120             if(wentry.mAppToken == win.mAppToken) {
   1121                 return j;
   1122             }
   1123         }
   1124         return -1;
   1125     }
   1126 
   1127     /**
   1128      * Return the list of Windows from the passed token on the given Display.
   1129      * @param token The token with all the windows.
   1130      * @param displayContent The display we are interested in.
   1131      * @return List of windows from token that are on displayContent.
   1132      */
   1133     private WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
   1134         final WindowList windowList = new WindowList();
   1135         final int count = token.windows.size();
   1136         for (int i = 0; i < count; i++) {
   1137             final WindowState win = token.windows.get(i);
   1138             if (win.getDisplayContent() == displayContent) {
   1139                 windowList.add(win);
   1140             }
   1141         }
   1142         return windowList;
   1143     }
   1144 
   1145     /**
   1146      * Recursive search through a WindowList and all of its windows' children.
   1147      * @param targetWin The window to search for.
   1148      * @param windows The list to search.
   1149      * @return The index of win in windows or of the window that is an ancestor of win.
   1150      */
   1151     private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) {
   1152         for (int i = windows.size() - 1; i >= 0; i--) {
   1153             final WindowState w = windows.get(i);
   1154             if (w == targetWin) {
   1155                 return i;
   1156             }
   1157             if (!w.mChildWindows.isEmpty()) {
   1158                 if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) {
   1159                     return i;
   1160                 }
   1161             }
   1162         }
   1163         return -1;
   1164     }
   1165 
   1166     private int addAppWindowToListLocked(final WindowState win) {
   1167         final DisplayContent displayContent = win.getDisplayContent();
   1168         if (displayContent == null) {
   1169             // It doesn't matter this display is going away.
   1170             return 0;
   1171         }
   1172         final IWindow client = win.mClient;
   1173         final WindowToken token = win.mToken;
   1174 
   1175         final WindowList windows = displayContent.getWindowList();
   1176         WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
   1177         int tokenWindowsPos = 0;
   1178         if (!tokenWindowList.isEmpty()) {
   1179             return addAppWindowToTokenListLocked(win, token, windows, tokenWindowList);
   1180         }
   1181 
   1182         // No windows from this token on this display
   1183         if (localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window " + client.asBinder()
   1184                 + " (token=" + token + ")");
   1185         // Figure out where the window should go, based on the
   1186         // order of applications.
   1187         WindowState pos = null;
   1188 
   1189         final ArrayList<Task> tasks = displayContent.getTasks();
   1190         int taskNdx;
   1191         int tokenNdx = -1;
   1192         for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
   1193             AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
   1194             for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
   1195                 final AppWindowToken t = tokens.get(tokenNdx);
   1196                 if (t == token) {
   1197                     --tokenNdx;
   1198                     if (tokenNdx < 0) {
   1199                         --taskNdx;
   1200                         if (taskNdx >= 0) {
   1201                             tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
   1202                         }
   1203                     }
   1204                     break;
   1205                 }
   1206 
   1207                 // We haven't reached the token yet; if this token
   1208                 // is not going to the bottom and has windows on this display, we can
   1209                 // use it as an anchor for when we do reach the token.
   1210                 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
   1211                 if (!t.sendingToBottom && tokenWindowList.size() > 0) {
   1212                     pos = tokenWindowList.get(0);
   1213                 }
   1214             }
   1215             if (tokenNdx >= 0) {
   1216                 // early exit
   1217                 break;
   1218             }
   1219         }
   1220 
   1221         // We now know the index into the apps.  If we found
   1222         // an app window above, that gives us the position; else
   1223         // we need to look some more.
   1224         if (pos != null) {
   1225             // Move behind any windows attached to this one.
   1226             WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
   1227             if (atoken != null) {
   1228                 tokenWindowList =
   1229                         getTokenWindowsOnDisplay(atoken, displayContent);
   1230                 final int NC = tokenWindowList.size();
   1231                 if (NC > 0) {
   1232                     WindowState bottom = tokenWindowList.get(0);
   1233                     if (bottom.mSubLayer < 0) {
   1234                         pos = bottom;
   1235                     }
   1236                 }
   1237             }
   1238             placeWindowBefore(pos, win);
   1239             return tokenWindowsPos;
   1240         }
   1241 
   1242         // Continue looking down until we find the first
   1243         // token that has windows on this display.
   1244         for ( ; taskNdx >= 0; --taskNdx) {
   1245             AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
   1246             for ( ; tokenNdx >= 0; --tokenNdx) {
   1247                 final AppWindowToken t = tokens.get(tokenNdx);
   1248                 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
   1249                 final int NW = tokenWindowList.size();
   1250                 if (NW > 0) {
   1251                     pos = tokenWindowList.get(NW-1);
   1252                     break;
   1253                 }
   1254             }
   1255             if (tokenNdx >= 0) {
   1256                 // found
   1257                 break;
   1258             }
   1259         }
   1260 
   1261         if (pos != null) {
   1262             // Move in front of any windows attached to this
   1263             // one.
   1264             WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
   1265             if (atoken != null) {
   1266                 final int NC = atoken.windows.size();
   1267                 if (NC > 0) {
   1268                     WindowState top = atoken.windows.get(NC-1);
   1269                     if (top.mSubLayer >= 0) {
   1270                         pos = top;
   1271                     }
   1272                 }
   1273             }
   1274             placeWindowAfter(pos, win);
   1275             return tokenWindowsPos;
   1276         }
   1277 
   1278         // Just search for the start of this layer.
   1279         final int myLayer = win.mBaseLayer;
   1280         int i;
   1281         for (i = windows.size() - 1; i >= 0; --i) {
   1282             WindowState w = windows.get(i);
   1283             // Dock divider shares the base layer with application windows, but we want to always
   1284             // keep it above the application windows. The sharing of the base layer is intended
   1285             // for window animations, which need to be above the dock divider for the duration
   1286             // of the animation.
   1287             if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
   1288                 break;
   1289             }
   1290         }
   1291         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
   1292                 "Based on layer: Adding window " + win + " at " + (i + 1) + " of "
   1293                         + windows.size());
   1294         windows.add(i + 1, win);
   1295         mWindowsChanged = true;
   1296         return tokenWindowsPos;
   1297     }
   1298 
   1299     private int addAppWindowToTokenListLocked(WindowState win, WindowToken token,
   1300             WindowList windows, WindowList tokenWindowList) {
   1301         int tokenWindowsPos;
   1302         // If this application has existing windows, we
   1303         // simply place the new window on top of them... but
   1304         // keep the starting window on top.
   1305         if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
   1306             // Base windows go behind everything else.
   1307             WindowState lowestWindow = tokenWindowList.get(0);
   1308             placeWindowBefore(lowestWindow, win);
   1309             tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
   1310         } else {
   1311             AppWindowToken atoken = win.mAppToken;
   1312             final int windowListPos = tokenWindowList.size();
   1313             WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
   1314             if (atoken != null && lastWindow == atoken.startingWindow) {
   1315                 placeWindowBefore(lastWindow, win);
   1316                 tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
   1317             } else {
   1318                 int newIdx = findIdxBasedOnAppTokens(win);
   1319                 //there is a window above this one associated with the same
   1320                 //apptoken note that the window could be a floating window
   1321                 //that was created later or a window at the top of the list of
   1322                 //windows associated with this token.
   1323                 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
   1324                         "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
   1325                                 + windows.size());
   1326                 windows.add(newIdx + 1, win);
   1327                 if (newIdx < 0) {
   1328                     // No window from token found on win's display.
   1329                     tokenWindowsPos = 0;
   1330                 } else {
   1331                     tokenWindowsPos = indexOfWinInWindowList(
   1332                             windows.get(newIdx), token.windows) + 1;
   1333                 }
   1334                 mWindowsChanged = true;
   1335             }
   1336         }
   1337         return tokenWindowsPos;
   1338     }
   1339 
   1340     private void addFreeWindowToListLocked(final WindowState win) {
   1341         final WindowList windows = win.getWindowList();
   1342 
   1343         // Figure out where window should go, based on layer.
   1344         final int myLayer = win.mBaseLayer;
   1345         int i;
   1346         for (i = windows.size() - 1; i >= 0; i--) {
   1347             final WindowState otherWin = windows.get(i);
   1348             if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= myLayer) {
   1349                 // Wallpaper wanders through the window list, for example to position itself
   1350                 // directly behind keyguard. Because of this it will break the ordering based on
   1351                 // WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
   1352                 // we don't want the new window to appear above them. An example of this is adding
   1353                 // of the docked stack divider. Consider a scenario with the following ordering (top
   1354                 // to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
   1355                 // to land below the assist preview, so the dock divider must ignore the wallpaper,
   1356                 // with which it shares the base layer.
   1357                 break;
   1358             }
   1359         }
   1360         i++;
   1361         if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
   1362                 "Free window: Adding window " + win + " at " + i + " of " + windows.size());
   1363         windows.add(i, win);
   1364         mWindowsChanged = true;
   1365     }
   1366 
   1367     private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
   1368         final WindowToken token = win.mToken;
   1369         final DisplayContent displayContent = win.getDisplayContent();
   1370         if (displayContent == null) {
   1371             return;
   1372         }
   1373         final WindowState attached = win.mAttachedWindow;
   1374 
   1375         WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
   1376 
   1377         // Figure out this window's ordering relative to the window
   1378         // it is attached to.
   1379         final int NA = tokenWindowList.size();
   1380         final int sublayer = win.mSubLayer;
   1381         int largestSublayer = Integer.MIN_VALUE;
   1382         WindowState windowWithLargestSublayer = null;
   1383         int i;
   1384         for (i = 0; i < NA; i++) {
   1385             WindowState w = tokenWindowList.get(i);
   1386             final int wSublayer = w.mSubLayer;
   1387             if (wSublayer >= largestSublayer) {
   1388                 largestSublayer = wSublayer;
   1389                 windowWithLargestSublayer = w;
   1390             }
   1391             if (sublayer < 0) {
   1392                 // For negative sublayers, we go below all windows
   1393                 // in the same sublayer.
   1394                 if (wSublayer >= sublayer) {
   1395                     if (addToToken) {
   1396                         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
   1397                         token.windows.add(i, win);
   1398                     }
   1399                     placeWindowBefore(wSublayer >= 0 ? attached : w, win);
   1400                     break;
   1401                 }
   1402             } else {
   1403                 // For positive sublayers, we go above all windows
   1404                 // in the same sublayer.
   1405                 if (wSublayer > sublayer) {
   1406                     if (addToToken) {
   1407                         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
   1408                         token.windows.add(i, win);
   1409                     }
   1410                     placeWindowBefore(w, win);
   1411                     break;
   1412                 }
   1413             }
   1414         }
   1415         if (i >= NA) {
   1416             if (addToToken) {
   1417                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
   1418                 token.windows.add(win);
   1419             }
   1420             if (sublayer < 0) {
   1421                 placeWindowBefore(attached, win);
   1422             } else {
   1423                 placeWindowAfter(largestSublayer >= 0
   1424                                  ? windowWithLargestSublayer
   1425                                  : attached,
   1426                                  win);
   1427             }
   1428         }
   1429     }
   1430 
   1431     private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
   1432         if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindowToListInOrderLocked: win=" + win +
   1433                 " Callers=" + Debug.getCallers(4));
   1434         if (win.mAttachedWindow == null) {
   1435             final WindowToken token = win.mToken;
   1436             int tokenWindowsPos = 0;
   1437             if (token.appWindowToken != null) {
   1438                 tokenWindowsPos = addAppWindowToListLocked(win);
   1439             } else {
   1440                 addFreeWindowToListLocked(win);
   1441             }
   1442             if (addToToken) {
   1443                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + token);
   1444                 token.windows.add(tokenWindowsPos, win);
   1445             }
   1446         } else {
   1447             addAttachedWindowToListLocked(win, addToToken);
   1448         }
   1449 
   1450         final AppWindowToken appToken = win.mAppToken;
   1451         if (appToken != null) {
   1452             if (addToToken) {
   1453                 appToken.addWindow(win);
   1454             }
   1455         }
   1456     }
   1457 
   1458     static boolean canBeImeTarget(WindowState w) {
   1459         final int fl = w.mAttrs.flags
   1460                 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
   1461         final int type = w.mAttrs.type;
   1462         if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
   1463                 || type == TYPE_APPLICATION_STARTING) {
   1464             if (DEBUG_INPUT_METHOD) {
   1465                 Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
   1466                 if (!w.isVisibleOrAdding()) {
   1467                     Slog.i(TAG_WM, "  mSurfaceController=" + w.mWinAnimator.mSurfaceController
   1468                             + " relayoutCalled=" + w.mRelayoutCalled
   1469                             + " viewVis=" + w.mViewVisibility
   1470                             + " policyVis=" + w.mPolicyVisibility
   1471                             + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
   1472                             + " attachHid=" + w.mAttachedHidden
   1473                             + " exiting=" + w.mAnimatingExit + " destroying=" + w.mDestroying);
   1474                     if (w.mAppToken != null) {
   1475                         Slog.i(TAG_WM, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
   1476                     }
   1477                 }
   1478             }
   1479             return w.isVisibleOrAdding();
   1480         }
   1481         return false;
   1482     }
   1483 
   1484     /**
   1485      * Dig through the WindowStates and find the one that the Input Method will target.
   1486      * @param willMove
   1487      * @return The index+1 in mWindows of the discovered target.
   1488      */
   1489     int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
   1490         // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
   1491         // same display. Or even when the current IME/target are not on the same screen as the next
   1492         // IME/target. For now only look for input windows on the main screen.
   1493         WindowList windows = getDefaultWindowListLocked();
   1494         WindowState w = null;
   1495         int i;
   1496         for (i = windows.size() - 1; i >= 0; --i) {
   1497             WindowState win = windows.get(i);
   1498 
   1499             if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG_WM, "Checking window @" + i
   1500                     + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
   1501             if (canBeImeTarget(win)) {
   1502                 w = win;
   1503                 //Slog.i(TAG_WM, "Putting input method here!");
   1504 
   1505                 // Yet more tricksyness!  If this window is a "starting"
   1506                 // window, we do actually want to be on top of it, but
   1507                 // it is not -really- where input will go.  So if the caller
   1508                 // is not actually looking to move the IME, look down below
   1509                 // for a real window to target...
   1510                 if (!willMove
   1511                         && w.mAttrs.type == TYPE_APPLICATION_STARTING
   1512                         && i > 0) {
   1513                     WindowState wb = windows.get(i-1);
   1514                     if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
   1515                         i--;
   1516                         w = wb;
   1517                     }
   1518                 }
   1519                 break;
   1520             }
   1521         }
   1522 
   1523         // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
   1524 
   1525         if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG_WM, "Proposed new IME target: " + w);
   1526 
   1527         // Now, a special case -- if the last target's window is in the
   1528         // process of exiting, and is above the new target, keep on the
   1529         // last target to avoid flicker.  Consider for example a Dialog with
   1530         // the IME shown: when the Dialog is dismissed, we want to keep
   1531         // the IME above it until it is completely gone so it doesn't drop
   1532         // behind the dialog or its full-screen scrim.
   1533         final WindowState curTarget = mInputMethodTarget;
   1534         if (curTarget != null
   1535                 && curTarget.isDisplayedLw()
   1536                 && curTarget.isClosing()
   1537                 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
   1538             if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
   1539             return windows.indexOf(curTarget) + 1;
   1540         }
   1541 
   1542         if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Desired input method target="
   1543                 + w + " willMove=" + willMove);
   1544 
   1545         if (willMove && w != null) {
   1546             AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
   1547             if (token != null) {
   1548 
   1549                 // Now some fun for dealing with window animations that
   1550                 // modify the Z order.  We need to look at all windows below
   1551                 // the current target that are in this app, finding the highest
   1552                 // visible one in layering.
   1553                 WindowState highestTarget = null;
   1554                 int highestPos = 0;
   1555                 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
   1556                     WindowList curWindows = curTarget.getWindowList();
   1557                     int pos = curWindows.indexOf(curTarget);
   1558                     while (pos >= 0) {
   1559                         WindowState win = curWindows.get(pos);
   1560                         if (win.mAppToken != token) {
   1561                             break;
   1562                         }
   1563                         if (!win.mRemoved) {
   1564                             if (highestTarget == null || win.mWinAnimator.mAnimLayer >
   1565                                     highestTarget.mWinAnimator.mAnimLayer) {
   1566                                 highestTarget = win;
   1567                                 highestPos = pos;
   1568                             }
   1569                         }
   1570                         pos--;
   1571                     }
   1572                 }
   1573 
   1574                 if (highestTarget != null) {
   1575                     if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
   1576                             + " animating=" + highestTarget.mWinAnimator.isAnimationSet()
   1577                             + " layer=" + highestTarget.mWinAnimator.mAnimLayer
   1578                             + " new layer=" + w.mWinAnimator.mAnimLayer);
   1579 
   1580                     if (mAppTransition.isTransitionSet()) {
   1581                         // If we are currently setting up for an animation,
   1582                         // hold everything until we can find out what will happen.
   1583                         mInputMethodTargetWaitingAnim = true;
   1584                         mInputMethodTarget = highestTarget;
   1585                         return highestPos + 1;
   1586                     } else if (highestTarget.mWinAnimator.isAnimationSet() &&
   1587                             highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
   1588                         // If the window we are currently targeting is involved
   1589                         // with an animation, and it is on top of the next target
   1590                         // we will be over, then hold off on moving until
   1591                         // that is done.
   1592                         mInputMethodTargetWaitingAnim = true;
   1593                         mInputMethodTarget = highestTarget;
   1594                         return highestPos + 1;
   1595                     }
   1596                 }
   1597             }
   1598         }
   1599 
   1600         //Slog.i(TAG_WM, "Placing input method @" + (i+1));
   1601         if (w != null) {
   1602             if (willMove) {
   1603                 if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
   1604                         + w + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
   1605                 mInputMethodTarget = w;
   1606                 mInputMethodTargetWaitingAnim = false;
   1607                 if (w.mAppToken != null) {
   1608                     mLayersController.setInputMethodAnimLayerAdjustment(
   1609                             w.mAppToken.mAppAnimator.animLayerAdjustment);
   1610                 } else {
   1611                     mLayersController.setInputMethodAnimLayerAdjustment(0);
   1612                 }
   1613             }
   1614 
   1615             // If the docked divider is visible, we still need to go through this whole
   1616             // excercise to find the appropriate input method target (used for animations
   1617             // and dialog adjustments), but for purposes of Z ordering we simply wish to
   1618             // place it above the docked divider. Unless it is already above the divider.
   1619             WindowState dockedDivider = w.mDisplayContent.mDividerControllerLocked.getWindow();
   1620             if (dockedDivider != null && dockedDivider.isVisibleLw()) {
   1621                 int dividerIndex = windows.indexOf(dockedDivider);
   1622                 if (dividerIndex > 0 && dividerIndex > i) {
   1623                     return dividerIndex + 1;
   1624                 }
   1625             }
   1626             return i+1;
   1627         }
   1628         if (willMove) {
   1629             if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null."
   1630                     + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
   1631             mInputMethodTarget = null;
   1632             mLayersController.setInputMethodAnimLayerAdjustment(0);
   1633         }
   1634         return -1;
   1635     }
   1636 
   1637     void addInputMethodWindowToListLocked(WindowState win) {
   1638         int pos = findDesiredInputMethodWindowIndexLocked(true);
   1639         if (pos >= 0) {
   1640             win.mTargetAppToken = mInputMethodTarget.mAppToken;
   1641             if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
   1642                     TAG_WM, "Adding input method window " + win + " at " + pos);
   1643             // TODO(multidisplay): IMEs are only supported on the default display.
   1644             getDefaultWindowListLocked().add(pos, win);
   1645             mWindowsChanged = true;
   1646             moveInputMethodDialogsLocked(pos + 1);
   1647             return;
   1648         }
   1649         win.mTargetAppToken = null;
   1650         addWindowToListInOrderLocked(win, true);
   1651         moveInputMethodDialogsLocked(pos);
   1652     }
   1653 
   1654     private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
   1655         WindowList windows = win.getWindowList();
   1656         int wpos = windows.indexOf(win);
   1657         if (wpos >= 0) {
   1658             if (wpos < interestingPos) interestingPos--;
   1659             if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing at " + wpos + ": " + win);
   1660             windows.remove(wpos);
   1661             mWindowsChanged = true;
   1662             int NC = win.mChildWindows.size();
   1663             while (NC > 0) {
   1664                 NC--;
   1665                 WindowState cw = win.mChildWindows.get(NC);
   1666                 int cpos = windows.indexOf(cw);
   1667                 if (cpos >= 0) {
   1668                     if (cpos < interestingPos) interestingPos--;
   1669                     if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Temp removing child at "
   1670                             + cpos + ": " + cw);
   1671                     windows.remove(cpos);
   1672                 }
   1673             }
   1674         }
   1675         return interestingPos;
   1676     }
   1677 
   1678     private void reAddWindowToListInOrderLocked(WindowState win) {
   1679         addWindowToListInOrderLocked(win, false);
   1680         // This is a hack to get all of the child windows added as well
   1681         // at the right position.  Child windows should be rare and
   1682         // this case should be rare, so it shouldn't be that big a deal.
   1683         WindowList windows = win.getWindowList();
   1684         int wpos = windows.indexOf(win);
   1685         if (wpos >= 0) {
   1686             if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "ReAdd removing from " + wpos + ": " + win);
   1687             windows.remove(wpos);
   1688             mWindowsChanged = true;
   1689             reAddWindowLocked(wpos, win);
   1690         }
   1691     }
   1692 
   1693     void logWindowList(final WindowList windows, String prefix) {
   1694         int N = windows.size();
   1695         while (N > 0) {
   1696             N--;
   1697             Slog.v(TAG_WM, prefix + "#" + N + ": " + windows.get(N));
   1698         }
   1699     }
   1700 
   1701     void moveInputMethodDialogsLocked(int pos) {
   1702         ArrayList<WindowState> dialogs = mInputMethodDialogs;
   1703 
   1704         // TODO(multidisplay): IMEs are only supported on the default display.
   1705         WindowList windows = getDefaultWindowListLocked();
   1706         final int N = dialogs.size();
   1707         if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Removing " + N + " dialogs w/pos=" + pos);
   1708         for (int i=0; i<N; i++) {
   1709             pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
   1710         }
   1711         if (DEBUG_INPUT_METHOD) {
   1712             Slog.v(TAG_WM, "Window list w/pos=" + pos);
   1713             logWindowList(windows, "  ");
   1714         }
   1715 
   1716         if (pos >= 0) {
   1717             final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
   1718             // Skip windows owned by the input method.
   1719             if (mInputMethodWindow != null) {
   1720                 while (pos < windows.size()) {
   1721                     WindowState wp = windows.get(pos);
   1722                     if (wp == mInputMethodWindow || wp.mAttachedWindow == mInputMethodWindow) {
   1723                         pos++;
   1724                         continue;
   1725                     }
   1726                     break;
   1727                 }
   1728             }
   1729             if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Adding " + N + " dialogs at pos=" + pos);
   1730             for (int i=0; i<N; i++) {
   1731                 WindowState win = dialogs.get(i);
   1732                 win.mTargetAppToken = targetAppToken;
   1733                 pos = reAddWindowLocked(pos, win);
   1734             }
   1735             if (DEBUG_INPUT_METHOD) {
   1736                 Slog.v(TAG_WM, "Final window list:");
   1737                 logWindowList(windows, "  ");
   1738             }
   1739             return;
   1740         }
   1741         for (int i=0; i<N; i++) {
   1742             WindowState win = dialogs.get(i);
   1743             win.mTargetAppToken = null;
   1744             reAddWindowToListInOrderLocked(win);
   1745             if (DEBUG_INPUT_METHOD) {
   1746                 Slog.v(TAG_WM, "No IM target, final list:");
   1747                 logWindowList(windows, "  ");
   1748             }
   1749         }
   1750     }
   1751 
   1752     boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
   1753         final WindowState imWin = mInputMethodWindow;
   1754         final int DN = mInputMethodDialogs.size();
   1755         if (imWin == null && DN == 0) {
   1756             return false;
   1757         }
   1758 
   1759         // TODO(multidisplay): IMEs are only supported on the default display.
   1760         WindowList windows = getDefaultWindowListLocked();
   1761 
   1762         int imPos = findDesiredInputMethodWindowIndexLocked(true);
   1763         if (imPos >= 0) {
   1764             // In this case, the input method windows are to be placed
   1765             // immediately above the window they are targeting.
   1766 
   1767             // First check to see if the input method windows are already
   1768             // located here, and contiguous.
   1769             final int N = windows.size();
   1770             WindowState firstImWin = imPos < N
   1771                     ? windows.get(imPos) : null;
   1772 
   1773             // Figure out the actual input method window that should be
   1774             // at the bottom of their stack.
   1775             WindowState baseImWin = imWin != null
   1776                     ? imWin : mInputMethodDialogs.get(0);
   1777             if (baseImWin.mChildWindows.size() > 0) {
   1778                 WindowState cw = baseImWin.mChildWindows.get(0);
   1779                 if (cw.mSubLayer < 0) baseImWin = cw;
   1780             }
   1781 
   1782             if (firstImWin == baseImWin) {
   1783                 // The windows haven't moved...  but are they still contiguous?
   1784                 // First find the top IM window.
   1785                 int pos = imPos+1;
   1786                 while (pos < N) {
   1787                     if (!(windows.get(pos)).mIsImWindow) {
   1788                         break;
   1789                     }
   1790                     pos++;
   1791                 }
   1792                 pos++;
   1793                 // Now there should be no more input method windows above.
   1794                 while (pos < N) {
   1795                     if ((windows.get(pos)).mIsImWindow) {
   1796                         break;
   1797                     }
   1798                     pos++;
   1799                 }
   1800                 if (pos >= N) {
   1801                     // Z order is good.
   1802                     // The IM target window may be changed, so update the mTargetAppToken.
   1803                     if (imWin != null) {
   1804                         imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
   1805                     }
   1806                     return false;
   1807                 }
   1808             }
   1809 
   1810             if (imWin != null) {
   1811                 if (DEBUG_INPUT_METHOD) {
   1812                     Slog.v(TAG_WM, "Moving IM from " + imPos);
   1813                     logWindowList(windows, "  ");
   1814                 }
   1815                 imPos = tmpRemoveWindowLocked(imPos, imWin);
   1816                 if (DEBUG_INPUT_METHOD) {
   1817                     Slog.v(TAG_WM, "List after removing with new pos " + imPos + ":");
   1818                     logWindowList(windows, "  ");
   1819                 }
   1820                 imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
   1821                 reAddWindowLocked(imPos, imWin);
   1822                 if (DEBUG_INPUT_METHOD) {
   1823                     Slog.v(TAG_WM, "List after moving IM to " + imPos + ":");
   1824                     logWindowList(windows, "  ");
   1825                 }
   1826                 if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
   1827             } else {
   1828                 moveInputMethodDialogsLocked(imPos);
   1829             }
   1830 
   1831         } else {
   1832             // In this case, the input method windows go in a fixed layer,
   1833             // because they aren't currently associated with a focus window.
   1834 
   1835             if (imWin != null) {
   1836                 if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Moving IM from " + imPos);
   1837                 tmpRemoveWindowLocked(0, imWin);
   1838                 imWin.mTargetAppToken = null;
   1839                 reAddWindowToListInOrderLocked(imWin);
   1840                 if (DEBUG_INPUT_METHOD) {
   1841                     Slog.v(TAG_WM, "List with no IM target:");
   1842                     logWindowList(windows, "  ");
   1843                 }
   1844                 if (DN > 0) moveInputMethodDialogsLocked(-1);
   1845             } else {
   1846                 moveInputMethodDialogsLocked(-1);
   1847             }
   1848 
   1849         }
   1850 
   1851         if (needAssignLayers) {
   1852             mLayersController.assignLayersLocked(windows);
   1853         }
   1854 
   1855         return true;
   1856     }
   1857 
   1858     private static boolean excludeWindowTypeFromTapOutTask(int windowType) {
   1859         switch (windowType) {
   1860             case TYPE_STATUS_BAR:
   1861             case TYPE_NAVIGATION_BAR:
   1862             case TYPE_INPUT_METHOD_DIALOG:
   1863                 return true;
   1864         }
   1865         return false;
   1866     }
   1867 
   1868     public int addWindow(Session session, IWindow client, int seq,
   1869             WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
   1870             Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
   1871             InputChannel outInputChannel) {
   1872         int[] appOp = new int[1];
   1873         int res = mPolicy.checkAddPermission(attrs, appOp);
   1874         if (res != WindowManagerGlobal.ADD_OKAY) {
   1875             return res;
   1876         }
   1877 
   1878         boolean reportNewConfig = false;
   1879         WindowState attachedWindow = null;
   1880         long origId;
   1881         final int callingUid = Binder.getCallingUid();
   1882         final int type = attrs.type;
   1883 
   1884         synchronized(mWindowMap) {
   1885             if (!mDisplayReady) {
   1886                 throw new IllegalStateException("Display has not been initialialized");
   1887             }
   1888 
   1889             final DisplayContent displayContent = getDisplayContentLocked(displayId);
   1890             if (displayContent == null) {
   1891                 Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
   1892                         + displayId + ".  Aborting.");
   1893                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
   1894             }
   1895             if (!displayContent.hasAccess(session.mUid)) {
   1896                 Slog.w(TAG_WM, "Attempted to add window to a display for which the application "
   1897                         + "does not have access: " + displayId + ".  Aborting.");
   1898                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
   1899             }
   1900 
   1901             if (mWindowMap.containsKey(client.asBinder())) {
   1902                 Slog.w(TAG_WM, "Window " + client + " is already added");
   1903                 return WindowManagerGlobal.ADD_DUPLICATE_ADD;
   1904             }
   1905 
   1906             if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
   1907                 attachedWindow = windowForClientLocked(null, attrs.token, false);
   1908                 if (attachedWindow == null) {
   1909                     Slog.w(TAG_WM, "Attempted to add window with token that is not a window: "
   1910                           + attrs.token + ".  Aborting.");
   1911                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
   1912                 }
   1913                 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
   1914                         && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
   1915                     Slog.w(TAG_WM, "Attempted to add window with token that is a sub-window: "
   1916                             + attrs.token + ".  Aborting.");
   1917                     return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
   1918                 }
   1919             }
   1920 
   1921             if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
   1922                 Slog.w(TAG_WM, "Attempted to add private presentation window to a non-private display.  Aborting.");
   1923                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
   1924             }
   1925 
   1926             boolean addToken = false;
   1927             WindowToken token = mTokenMap.get(attrs.token);
   1928             AppWindowToken atoken = null;
   1929             boolean addToastWindowRequiresToken = false;
   1930 
   1931             if (token == null) {
   1932                 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
   1933                     Slog.w(TAG_WM, "Attempted to add application window with unknown token "
   1934                           + attrs.token + ".  Aborting.");
   1935                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1936                 }
   1937                 if (type == TYPE_INPUT_METHOD) {
   1938                     Slog.w(TAG_WM, "Attempted to add input method window with unknown token "
   1939                           + attrs.token + ".  Aborting.");
   1940                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1941                 }
   1942                 if (type == TYPE_VOICE_INTERACTION) {
   1943                     Slog.w(TAG_WM, "Attempted to add voice interaction window with unknown token "
   1944                           + attrs.token + ".  Aborting.");
   1945                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1946                 }
   1947                 if (type == TYPE_WALLPAPER) {
   1948                     Slog.w(TAG_WM, "Attempted to add wallpaper window with unknown token "
   1949                           + attrs.token + ".  Aborting.");
   1950                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1951                 }
   1952                 if (type == TYPE_DREAM) {
   1953                     Slog.w(TAG_WM, "Attempted to add Dream window with unknown token "
   1954                           + attrs.token + ".  Aborting.");
   1955                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1956                 }
   1957                 if (type == TYPE_QS_DIALOG) {
   1958                     Slog.w(TAG_WM, "Attempted to add QS dialog window with unknown token "
   1959                           + attrs.token + ".  Aborting.");
   1960                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1961                 }
   1962                 if (type == TYPE_ACCESSIBILITY_OVERLAY) {
   1963                     Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with unknown token "
   1964                             + attrs.token + ".  Aborting.");
   1965                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1966                 }
   1967                 if (type == TYPE_TOAST) {
   1968                     // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
   1969                     if (doesAddToastWindowRequireToken(attrs.packageName, callingUid,
   1970                             attachedWindow)) {
   1971                         Slog.w(TAG_WM, "Attempted to add a toast window with unknown token "
   1972                                 + attrs.token + ".  Aborting.");
   1973                         return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   1974                     }
   1975                 }
   1976                 token = new WindowToken(this, attrs.token, -1, false);
   1977                 addToken = true;
   1978             } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
   1979                 atoken = token.appWindowToken;
   1980                 if (atoken == null) {
   1981                     Slog.w(TAG_WM, "Attempted to add window with non-application token "
   1982                           + token + ".  Aborting.");
   1983                     return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
   1984                 } else if (atoken.removed) {
   1985                     Slog.w(TAG_WM, "Attempted to add window with exiting application token "
   1986                           + token + ".  Aborting.");
   1987                     return WindowManagerGlobal.ADD_APP_EXITING;
   1988                 }
   1989                 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
   1990                     // No need for this guy!
   1991                     if (DEBUG_STARTING_WINDOW || localLOGV) Slog.v(
   1992                             TAG_WM, "**** NO NEED TO START: " + attrs.getTitle());
   1993                     return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
   1994                 }
   1995             } else if (type == TYPE_INPUT_METHOD) {
   1996                 if (token.windowType != TYPE_INPUT_METHOD) {
   1997                     Slog.w(TAG_WM, "Attempted to add input method window with bad token "
   1998                             + attrs.token + ".  Aborting.");
   1999                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2000                 }
   2001             } else if (type == TYPE_VOICE_INTERACTION) {
   2002                 if (token.windowType != TYPE_VOICE_INTERACTION) {
   2003                     Slog.w(TAG_WM, "Attempted to add voice interaction window with bad token "
   2004                             + attrs.token + ".  Aborting.");
   2005                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2006                 }
   2007             } else if (type == TYPE_WALLPAPER) {
   2008                 if (token.windowType != TYPE_WALLPAPER) {
   2009                     Slog.w(TAG_WM, "Attempted to add wallpaper window with bad token "
   2010                             + attrs.token + ".  Aborting.");
   2011                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2012                 }
   2013             } else if (type == TYPE_DREAM) {
   2014                 if (token.windowType != TYPE_DREAM) {
   2015                     Slog.w(TAG_WM, "Attempted to add Dream window with bad token "
   2016                             + attrs.token + ".  Aborting.");
   2017                       return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2018                 }
   2019             } else if (type == TYPE_ACCESSIBILITY_OVERLAY) {
   2020                 if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) {
   2021                     Slog.w(TAG_WM, "Attempted to add Accessibility overlay window with bad token "
   2022                             + attrs.token + ".  Aborting.");
   2023                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2024                 }
   2025             } else if (type == TYPE_TOAST) {
   2026                 // Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
   2027                 addToastWindowRequiresToken = doesAddToastWindowRequireToken(attrs.packageName,
   2028                         callingUid, attachedWindow);
   2029                 if (addToastWindowRequiresToken && token.windowType != TYPE_TOAST) {
   2030                     Slog.w(TAG_WM, "Attempted to add a toast window with bad token "
   2031                             + attrs.token + ".  Aborting.");
   2032                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2033                 }
   2034             } else if (type == TYPE_QS_DIALOG) {
   2035                 if (token.windowType != TYPE_QS_DIALOG) {
   2036                     Slog.w(TAG_WM, "Attempted to add QS dialog window with bad token "
   2037                             + attrs.token + ".  Aborting.");
   2038                     return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
   2039                 }
   2040             } else if (token.appWindowToken != null) {
   2041                 Slog.w(TAG_WM, "Non-null appWindowToken for system window of type=" + type);
   2042                 // It is not valid to use an app token with other system types; we will
   2043                 // instead make a new token for it (as if null had been passed in for the token).
   2044                 attrs.token = null;
   2045                 token = new WindowToken(this, null, -1, false);
   2046                 addToken = true;
   2047             }
   2048 
   2049             WindowState win = new WindowState(this, session, client, token,
   2050                     attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
   2051             if (win.mDeathRecipient == null) {
   2052                 // Client has apparently died, so there is no reason to
   2053                 // continue.
   2054                 Slog.w(TAG_WM, "Adding window client " + client.asBinder()
   2055                         + " that is dead, aborting.");
   2056                 return WindowManagerGlobal.ADD_APP_EXITING;
   2057             }
   2058 
   2059             if (win.getDisplayContent() == null) {
   2060                 Slog.w(TAG_WM, "Adding window to Display that has been removed.");
   2061                 return WindowManagerGlobal.ADD_INVALID_DISPLAY;
   2062             }
   2063 
   2064             mPolicy.adjustWindowParamsLw(win.mAttrs);
   2065             win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
   2066 
   2067             res = mPolicy.prepareAddWindowLw(win, attrs);
   2068             if (res != WindowManagerGlobal.ADD_OKAY) {
   2069                 return res;
   2070             }
   2071 
   2072             final boolean openInputChannels = (outInputChannel != null
   2073                     && (attrs.inputFeatures & INPUT_FEATURE_NO_INPUT_CHANNEL) == 0);
   2074             if  (openInputChannels) {
   2075                 win.openInputChannel(outInputChannel);
   2076             }
   2077 
   2078             // If adding a toast requires a token for this app we always schedule hiding
   2079             // toast windows to make sure they don't stick around longer then necessary.
   2080             // We hide instead of remove such windows as apps aren't prepared to handle
   2081             // windows being removed under them.
   2082             //
   2083             // If the app is older it can add toasts without a token and hence overlay
   2084             // other apps. To be maximally compatible with these apps we will hide the
   2085             // window after the toast timeout only if the focused window is from another
   2086             // UID, otherwise we allow unlimited duration. When a UID looses focus we
   2087             // schedule hiding all of its toast windows.
   2088             if (type == TYPE_TOAST) {
   2089                 if (!getDefaultDisplayContentLocked().canAddToastWindowForUid(callingUid)) {
   2090                     Slog.w(TAG_WM, "Adding more than one toast window for UID at a time.");
   2091                     return WindowManagerGlobal.ADD_DUPLICATE_ADD;
   2092                 }
   2093                 // Make sure this happens before we moved focus as one can make the
   2094                 // toast focusable to force it not being hidden after the timeout.
   2095                 // Focusable toasts are always timed out to prevent a focused app to
   2096                 // show a focusable toasts while it has focus which will be kept on
   2097                 // the screen after the activity goes away.
   2098                 if (addToastWindowRequiresToken
   2099                         || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0
   2100                         || mCurrentFocus == null
   2101                         || mCurrentFocus.mOwnerUid != callingUid) {
   2102                     mH.sendMessageDelayed(
   2103                             mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win),
   2104                             win.mAttrs.hideTimeoutMilliseconds);
   2105                 }
   2106             }
   2107 
   2108             // From now on, no exceptions or errors allowed!
   2109 
   2110             res = WindowManagerGlobal.ADD_OKAY;
   2111 
   2112             if (excludeWindowTypeFromTapOutTask(type)) {
   2113                 displayContent.mTapExcludedWindows.add(win);
   2114             }
   2115 
   2116             origId = Binder.clearCallingIdentity();
   2117 
   2118             if (addToken) {
   2119                 mTokenMap.put(attrs.token, token);
   2120             }
   2121             win.attach();
   2122             mWindowMap.put(client.asBinder(), win);
   2123             if (win.mAppOp != AppOpsManager.OP_NONE) {
   2124                 int startOpResult = mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(),
   2125                         win.getOwningPackage());
   2126                 if ((startOpResult != AppOpsManager.MODE_ALLOWED) &&
   2127                         (startOpResult != AppOpsManager.MODE_DEFAULT)) {
   2128                     win.setAppOpVisibilityLw(false);
   2129                 }
   2130             }
   2131 
   2132             if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
   2133                 token.appWindowToken.startingWindow = win;
   2134                 if (DEBUG_STARTING_WINDOW) Slog.v (TAG_WM, "addWindow: " + token.appWindowToken
   2135                         + " startingWindow=" + win);
   2136             }
   2137 
   2138             boolean imMayMove = true;
   2139 
   2140             if (type == TYPE_INPUT_METHOD) {
   2141                 win.mGivenInsetsPending = true;
   2142                 mInputMethodWindow = win;
   2143                 addInputMethodWindowToListLocked(win);
   2144                 imMayMove = false;
   2145             } else if (type == TYPE_INPUT_METHOD_DIALOG) {
   2146                 mInputMethodDialogs.add(win);
   2147                 addWindowToListInOrderLocked(win, true);
   2148                 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
   2149                 imMayMove = false;
   2150             } else {
   2151                 addWindowToListInOrderLocked(win, true);
   2152                 if (type == TYPE_WALLPAPER) {
   2153                     mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
   2154                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   2155                 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
   2156                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   2157                 } else if (mWallpaperControllerLocked.isBelowWallpaperTarget(win)) {
   2158                     // If there is currently a wallpaper being shown, and
   2159                     // the base layer of the new window is below the current
   2160                     // layer of the target window, then adjust the wallpaper.
   2161                     // This is to avoid a new window being placed between the
   2162                     // wallpaper and its target.
   2163                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
   2164                 }
   2165             }
   2166 
   2167             // If the window is being added to a task that's docked but non-resizeable,
   2168             // we need to update this new window's scroll position when it's added.
   2169             win.applyScrollIfNeeded();
   2170 
   2171             // If the window is being added to a stack that's currently adjusted for IME,
   2172             // make sure to apply the same adjust to this new window.
   2173             win.applyAdjustForImeIfNeeded();
   2174 
   2175             if (type == TYPE_DOCK_DIVIDER) {
   2176                 getDefaultDisplayContentLocked().getDockedDividerController().setWindow(win);
   2177             }
   2178 
   2179             final WindowStateAnimator winAnimator = win.mWinAnimator;
   2180             winAnimator.mEnterAnimationPending = true;
   2181             winAnimator.mEnteringAnimation = true;
   2182             // Check if we need to prepare a transition for replacing window first.
   2183             if (atoken != null && !prepareWindowReplacementTransition(atoken)) {
   2184                 // If not, check if need to set up a dummy transition during display freeze
   2185                 // so that the unfreeze wait for the apps to draw. This might be needed if
   2186                 // the app is relaunching.
   2187                 prepareNoneTransitionForRelaunching(atoken);
   2188             }
   2189 
   2190             if (displayContent.isDefaultDisplay) {
   2191                 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
   2192                 final Rect taskBounds;
   2193                 if (atoken != null && atoken.mTask != null) {
   2194                     taskBounds = mTmpRect;
   2195                     atoken.mTask.getBounds(mTmpRect);
   2196                 } else {
   2197                     taskBounds = null;
   2198                 }
   2199                 if (mPolicy.getInsetHintLw(win.mAttrs, taskBounds, mRotation,
   2200                         displayInfo.logicalWidth, displayInfo.logicalHeight, outContentInsets,
   2201                         outStableInsets, outOutsets)) {
   2202                     res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_NAV_BAR;
   2203                 }
   2204             } else {
   2205                 outContentInsets.setEmpty();
   2206                 outStableInsets.setEmpty();
   2207             }
   2208 
   2209             if (mInTouchMode) {
   2210                 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
   2211             }
   2212             if (win.mAppToken == null || !win.mAppToken.clientHidden) {
   2213                 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
   2214             }
   2215 
   2216             mInputMonitor.setUpdateInputWindowsNeededLw();
   2217 
   2218             boolean focusChanged = false;
   2219             if (win.canReceiveKeys()) {
   2220                 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
   2221                         false /*updateInputWindows*/);
   2222                 if (focusChanged) {
   2223                     imMayMove = false;
   2224                 }
   2225             }
   2226 
   2227             if (imMayMove) {
   2228                 moveInputMethodWindowsIfNeededLocked(false);
   2229             }
   2230 
   2231             mLayersController.assignLayersLocked(displayContent.getWindowList());
   2232             // Don't do layout here, the window must call
   2233             // relayout to be displayed, so we'll do it there.
   2234 
   2235             if (focusChanged) {
   2236                 mInputMonitor.setInputFocusLw(mCurrentFocus, false /*updateInputWindows*/);
   2237             }
   2238             mInputMonitor.updateInputWindowsLw(false /*force*/);
   2239 
   2240             if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addWindow: New client "
   2241                     + client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
   2242 
   2243             if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
   2244                 reportNewConfig = true;
   2245             }
   2246         }
   2247 
   2248         if (reportNewConfig) {
   2249             sendNewConfiguration();
   2250         }
   2251 
   2252         Binder.restoreCallingIdentity(origId);
   2253 
   2254         return res;
   2255     }
   2256 
   2257     private boolean doesAddToastWindowRequireToken(String packageName, int callingUid,
   2258             WindowState attachedWindow) {
   2259         // Try using the target SDK of the root window
   2260         if (attachedWindow != null) {
   2261             return attachedWindow.mAppToken != null
   2262                     && attachedWindow.mAppToken.targetSdk > Build.VERSION_CODES.N_MR1;
   2263         } else {
   2264             // Otherwise, look at the package
   2265             try {
   2266                 ApplicationInfo appInfo = mContext.getPackageManager()
   2267                         .getApplicationInfoAsUser(packageName, 0,
   2268                                 UserHandle.getUserId(callingUid));
   2269                 if (appInfo.uid != callingUid) {
   2270                     throw new SecurityException("Package " + packageName + " not in UID "
   2271                             + callingUid);
   2272                 }
   2273                 if (appInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1) {
   2274                     return true;
   2275                 }
   2276             } catch (PackageManager.NameNotFoundException e) {
   2277                 /* ignore */
   2278             }
   2279         }
   2280         return false;
   2281     }
   2282 
   2283     /**
   2284      * Returns true if we're done setting up any transitions.
   2285      */
   2286     private boolean prepareWindowReplacementTransition(AppWindowToken atoken) {
   2287         atoken.clearAllDrawn();
   2288         WindowState replacedWindow = null;
   2289         for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) {
   2290             WindowState candidate = atoken.windows.get(i);
   2291             if (candidate.mAnimatingExit && candidate.mWillReplaceWindow
   2292                     && candidate.mAnimateReplacingWindow) {
   2293                 replacedWindow = candidate;
   2294             }
   2295         }
   2296         if (replacedWindow == null) {
   2297             // We expect to already receive a request to remove the old window. If it did not
   2298             // happen, let's just simply add a window.
   2299             return false;
   2300         }
   2301         // We use the visible frame, because we want the animation to morph the window from what
   2302         // was visible to the user to the final destination of the new window.
   2303         Rect frame = replacedWindow.mVisibleFrame;
   2304         // We treat this as if this activity was opening, so we can trigger the app transition
   2305         // animation and piggy-back on existing transition animation infrastructure.
   2306         mOpeningApps.add(atoken);
   2307         prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_RELAUNCH, ALWAYS_KEEP_CURRENT);
   2308         mAppTransition.overridePendingAppTransitionClipReveal(frame.left, frame.top,
   2309                 frame.width(), frame.height());
   2310         executeAppTransition();
   2311         return true;
   2312     }
   2313 
   2314     private void prepareNoneTransitionForRelaunching(AppWindowToken atoken) {
   2315         // Set up a none-transition and add the app to opening apps, so that the display
   2316         // unfreeze wait for the apps to be drawn.
   2317         // Note that if the display unfroze already because app unfreeze timed out,
   2318         // we don't set up the transition anymore and just let it go.
   2319         if (mDisplayFrozen && !mOpeningApps.contains(atoken) && atoken.isRelaunching()) {
   2320             mOpeningApps.add(atoken);
   2321             prepareAppTransition(AppTransition.TRANSIT_NONE, !ALWAYS_KEEP_CURRENT);
   2322             executeAppTransition();
   2323         }
   2324     }
   2325 
   2326     /**
   2327      * Returns whether screen capture is disabled for all windows of a specific user.
   2328      */
   2329     boolean isScreenCaptureDisabledLocked(int userId) {
   2330         Boolean disabled = mScreenCaptureDisabled.get(userId);
   2331         if (disabled == null) {
   2332             return false;
   2333         }
   2334         return disabled;
   2335     }
   2336 
   2337     boolean isSecureLocked(WindowState w) {
   2338         if ((w.mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
   2339             return true;
   2340         }
   2341         if (isScreenCaptureDisabledLocked(UserHandle.getUserId(w.mOwnerUid))) {
   2342             return true;
   2343         }
   2344         return false;
   2345     }
   2346 
   2347     /**
   2348      * Set mScreenCaptureDisabled for specific user
   2349      */
   2350     @Override
   2351     public void setScreenCaptureDisabled(int userId, boolean disabled) {
   2352         int callingUid = Binder.getCallingUid();
   2353         if (callingUid != Process.SYSTEM_UID) {
   2354             throw new SecurityException("Only system can call setScreenCaptureDisabled.");
   2355         }
   2356 
   2357         synchronized(mWindowMap) {
   2358             mScreenCaptureDisabled.put(userId, disabled);
   2359             // Update secure surface for all windows belonging to this user.
   2360             for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
   2361                 WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
   2362                 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
   2363                     final WindowState win = windows.get(winNdx);
   2364                     if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
   2365                         win.mWinAnimator.setSecureLocked(disabled);
   2366                     }
   2367                 }
   2368             }
   2369         }
   2370     }
   2371 
   2372     private void setupWindowForRemoveOnExit(WindowState win) {
   2373         win.mRemoveOnExit = true;
   2374         win.setDisplayLayoutNeeded();
   2375         // Request a focus update as this window's input channel is already gone. Otherwise
   2376         // we could have no focused window in input manager.
   2377         final boolean focusChanged = updateFocusedWindowLocked(
   2378                 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
   2379         mWindowPlacerLocked.performSurfacePlacement();
   2380         if (focusChanged) {
   2381             mInputMonitor.updateInputWindowsLw(false /*force*/);
   2382         }
   2383     }
   2384 
   2385     public void removeWindow(Session session, IWindow client) {
   2386         synchronized(mWindowMap) {
   2387             WindowState win = windowForClientLocked(session, client, false);
   2388             if (win == null) {
   2389                 return;
   2390             }
   2391             removeWindowLocked(win);
   2392         }
   2393     }
   2394 
   2395     void removeWindowLocked(WindowState win) {
   2396         removeWindowLocked(win, false);
   2397     }
   2398 
   2399     void removeWindowLocked(WindowState win, boolean keepVisibleDeadWindow) {
   2400         win.mWindowRemovalAllowed = true;
   2401         if (DEBUG_ADD_REMOVE) Slog.v(TAG,
   2402                 "removeWindowLocked: " + win + " callers=" + Debug.getCallers(4));
   2403 
   2404         final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING;
   2405         if (startingWindow) {
   2406             if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win);
   2407         }
   2408 
   2409         if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win == mCurrentFocus) Slog.v(
   2410                 TAG_WM, "Remove " + win + " client="
   2411                 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
   2412                 + ", surfaceController=" + win.mWinAnimator.mSurfaceController + " Callers="
   2413                 + Debug.getCallers(4));
   2414 
   2415         final long origId = Binder.clearCallingIdentity();
   2416 
   2417         win.disposeInputChannel();
   2418 
   2419         if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
   2420                 "Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
   2421                 + " mAnimatingExit=" + win.mAnimatingExit
   2422                 + " mRemoveOnExit=" + win.mRemoveOnExit
   2423                 + " mHasSurface=" + win.mHasSurface
   2424                 + " surfaceShowing=" + win.mWinAnimator.getShown()
   2425                 + " isAnimationSet=" + win.mWinAnimator.isAnimationSet()
   2426                 + " app-animation="
   2427                 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
   2428                 + " mWillReplaceWindow=" + win.mWillReplaceWindow
   2429                 + " inPendingTransaction="
   2430                 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
   2431                 + " mDisplayFrozen=" + mDisplayFrozen
   2432                 + " callers=" + Debug.getCallers(6));
   2433         // Visibility of the removed window. Will be used later to update orientation later on.
   2434         boolean wasVisible = false;
   2435         // First, see if we need to run an animation. If we do, we have to hold off on removing the
   2436         // window until the animation is done. If the display is frozen, just remove immediately,
   2437         // since the animation wouldn't be seen.
   2438         if (win.mHasSurface && okToDisplay()) {
   2439             final AppWindowToken appToken = win.mAppToken;
   2440             if (win.mWillReplaceWindow) {
   2441                 // This window is going to be replaced. We need to keep it around until the new one
   2442                 // gets added, then we will get rid of this one.
   2443                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
   2444                         + "added");
   2445                 // TODO: We are overloading mAnimatingExit flag to prevent the window state from
   2446                 // been removed. We probably need another flag to indicate that window removal
   2447                 // should be deffered vs. overloading the flag that says we are playing an exit
   2448                 // animation.
   2449                 win.mAnimatingExit = true;
   2450                 win.mReplacingRemoveRequested = true;
   2451                 Binder.restoreCallingIdentity(origId);
   2452                 return;
   2453             }
   2454 
   2455             if (win.isAnimatingWithSavedSurface() && !appToken.allDrawnExcludingSaved) {
   2456                 // We started enter animation early with a saved surface, now the app asks to remove
   2457                 // this window. If we remove it now and the app is not yet drawn, we'll show a
   2458                 // flicker. Delay the removal now until it's really drawn.
   2459                 if (DEBUG_ADD_REMOVE) {
   2460                     Slog.d(TAG_WM, "removeWindowLocked: delay removal of " + win
   2461                             + " due to early animation");
   2462                 }
   2463                 // Do not set mAnimatingExit to true here, it will cause the surface to be hidden
   2464                 // immediately after the enter animation is done. If the app is not yet drawn then
   2465                 // it will show up as a flicker.
   2466                 setupWindowForRemoveOnExit(win);
   2467                 Binder.restoreCallingIdentity(origId);
   2468                 return;
   2469             }
   2470             // If we are not currently running the exit animation, we need to see about starting one
   2471             wasVisible = win.isWinVisibleLw();
   2472 
   2473             if (keepVisibleDeadWindow) {
   2474                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
   2475                         "Not removing " + win + " because app died while it's visible");
   2476 
   2477                 win.mAppDied = true;
   2478                 win.setDisplayLayoutNeeded();
   2479                 mWindowPlacerLocked.performSurfacePlacement();
   2480 
   2481                 // Set up a replacement input channel since the app is now dead.
   2482                 // We need to catch tapping on the dead window to restart the app.
   2483                 win.openInputChannel(null);
   2484                 mInputMonitor.updateInputWindowsLw(true /*force*/);
   2485 
   2486                 Binder.restoreCallingIdentity(origId);
   2487                 return;
   2488             }
   2489 
   2490             final WindowStateAnimator winAnimator = win.mWinAnimator;
   2491             if (wasVisible) {
   2492                 final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
   2493 
   2494                 // Try starting an animation.
   2495                 if (winAnimator.applyAnimationLocked(transit, false)) {
   2496                     win.mAnimatingExit = true;
   2497                 }
   2498                 //TODO (multidisplay): Magnification is supported only for the default display.
   2499                 if (mAccessibilityController != null
   2500                         && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
   2501                     mAccessibilityController.onWindowTransitionLocked(win, transit);
   2502                 }
   2503             }
   2504             final boolean isAnimating =
   2505                     winAnimator.isAnimationSet() && !winAnimator.isDummyAnimation();
   2506             final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
   2507                     && appToken.allAppWindows.size() == 1;
   2508             // We delay the removal of a window if it has a showing surface that can be used to run
   2509             // exit animation and it is marked as exiting.
   2510             // Also, If isn't the an animating starting window that is the last window in the app.
   2511             // We allow the removal of the non-animating starting window now as there is no
   2512             // additional window or animation that will trigger its removal.
   2513             if (winAnimator.getShown() && win.mAnimatingExit
   2514                     && (!lastWindowIsStartingWindow || isAnimating)) {
   2515                 // The exit animation is running or should run... wait for it!
   2516                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
   2517                         "Not removing " + win + " due to exit animation ");
   2518                 setupWindowForRemoveOnExit(win);
   2519                 if (appToken != null) {
   2520                     appToken.updateReportedVisibilityLocked();
   2521                 }
   2522                 Binder.restoreCallingIdentity(origId);
   2523                 return;
   2524             }
   2525         }
   2526 
   2527         removeWindowInnerLocked(win);
   2528         // Removing a visible window will effect the computed orientation
   2529         // So just update orientation if needed.
   2530         if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
   2531             mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
   2532         }
   2533         updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
   2534         Binder.restoreCallingIdentity(origId);
   2535     }
   2536 
   2537     void removeWindowInnerLocked(WindowState win) {
   2538         if (win.mRemoved) {
   2539             // Nothing to do.
   2540             if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
   2541                     "removeWindowInnerLocked: " + win + " Already removed...");
   2542             return;
   2543         }
   2544 
   2545         for (int i = win.mChildWindows.size() - 1; i >= 0; i--) {
   2546             WindowState cwin = win.mChildWindows.get(i);
   2547             Slog.w(TAG_WM, "Force-removing child win " + cwin + " from container " + win);
   2548             removeWindowInnerLocked(cwin);
   2549         }
   2550 
   2551         win.mRemoved = true;
   2552 
   2553         if (mInputMethodTarget == win) {
   2554             moveInputMethodWindowsIfNeededLocked(false);
   2555         }
   2556 
   2557         if (false) {
   2558             RuntimeException e = new RuntimeException("here");
   2559             e.fillInStackTrace();
   2560             Slog.w(TAG_WM, "Removing window " + win, e);
   2561         }
   2562 
   2563         final int type = win.mAttrs.type;
   2564         if (excludeWindowTypeFromTapOutTask(type)) {
   2565             final DisplayContent displaycontent = win.getDisplayContent();
   2566             displaycontent.mTapExcludedWindows.remove(win);
   2567         }
   2568         mPolicy.removeWindowLw(win);
   2569         win.removeLocked();
   2570 
   2571         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "removeWindowInnerLocked: " + win);
   2572         mWindowMap.remove(win.mClient.asBinder());
   2573         if (win.mAppOp != AppOpsManager.OP_NONE) {
   2574             mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
   2575         }
   2576 
   2577         mPendingRemove.remove(win);
   2578         mResizingWindows.remove(win);
   2579         mWindowsChanged = true;
   2580         if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG_WM, "Final remove of window: " + win);
   2581 
   2582         if (mInputMethodWindow == win) {
   2583             mInputMethodWindow = null;
   2584         } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
   2585             mInputMethodDialogs.remove(win);
   2586         }
   2587 
   2588         final WindowToken token = win.mToken;
   2589         final AppWindowToken atoken = win.mAppToken;
   2590         if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token);
   2591         token.windows.remove(win);
   2592         if (atoken != null) {
   2593             atoken.allAppWindows.remove(win);
   2594         }
   2595         if (localLOGV) Slog.v(
   2596                 TAG_WM, "**** Removing window " + win + ": count="
   2597                 + token.windows.size());
   2598         if (token.windows.size() == 0) {
   2599             if (!token.explicit) {
   2600                 mTokenMap.remove(token.token);
   2601             } else if (atoken != null) {
   2602                 atoken.firstWindowDrawn = false;
   2603                 atoken.clearAllDrawn();
   2604             }
   2605         }
   2606 
   2607         if (atoken != null) {
   2608             if (atoken.startingWindow == win) {
   2609                 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
   2610                 scheduleRemoveStartingWindowLocked(atoken);
   2611             } else
   2612             if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
   2613                 // If this is the last window and we had requested a starting
   2614                 // transition window, well there is no point now.
   2615                 if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
   2616                 atoken.startingData = null;
   2617             } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
   2618                 // If this is the last window except for a starting transition
   2619                 // window, we need to get rid of the starting transition.
   2620                 scheduleRemoveStartingWindowLocked(atoken);
   2621             }
   2622         }
   2623 
   2624         if (type == TYPE_WALLPAPER) {
   2625             mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
   2626             getDefaultDisplayContentLocked().pendingLayoutChanges |=
   2627                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
   2628         } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
   2629             getDefaultDisplayContentLocked().pendingLayoutChanges |=
   2630                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
   2631         }
   2632 
   2633         final WindowList windows = win.getWindowList();
   2634         if (windows != null) {
   2635             windows.remove(win);
   2636             if (!mWindowPlacerLocked.isInLayout()) {
   2637                 mLayersController.assignLayersLocked(windows);
   2638                 win.setDisplayLayoutNeeded();
   2639                 mWindowPlacerLocked.performSurfacePlacement();
   2640                 if (win.mAppToken != null) {
   2641                     win.mAppToken.updateReportedVisibilityLocked();
   2642                 }
   2643             }
   2644         }
   2645 
   2646         mInputMonitor.updateInputWindowsLw(true /*force*/);
   2647     }
   2648 
   2649     public void updateAppOpsState() {
   2650         synchronized(mWindowMap) {
   2651             final int numDisplays = mDisplayContents.size();
   2652             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
   2653                 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
   2654                 final int numWindows = windows.size();
   2655                 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
   2656                     final WindowState win = windows.get(winNdx);
   2657                     if (win.mAppOp != AppOpsManager.OP_NONE) {
   2658                         final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
   2659                                 win.getOwningPackage());
   2660                         win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED ||
   2661                                 mode == AppOpsManager.MODE_DEFAULT);
   2662                     }
   2663                 }
   2664             }
   2665         }
   2666     }
   2667 
   2668     static void logSurface(WindowState w, String msg, boolean withStackTrace) {
   2669         String str = "  SURFACE " + msg + ": " + w;
   2670         if (withStackTrace) {
   2671             logWithStack(TAG, str);
   2672         } else {
   2673             Slog.i(TAG_WM, str);
   2674         }
   2675     }
   2676 
   2677     static void logSurface(SurfaceControl s, String title, String msg) {
   2678         String str = "  SURFACE " + s + ": " + msg + " / " + title;
   2679         Slog.i(TAG_WM, str);
   2680     }
   2681 
   2682     static void logWithStack(String tag, String s) {
   2683         RuntimeException e = null;
   2684         if (SHOW_STACK_CRAWLS) {
   2685             e = new RuntimeException();
   2686             e.fillInStackTrace();
   2687         }
   2688         Slog.i(tag, s, e);
   2689     }
   2690 
   2691     void setTransparentRegionWindow(Session session, IWindow client, Region region) {
   2692         long origId = Binder.clearCallingIdentity();
   2693         try {
   2694             synchronized (mWindowMap) {
   2695                 WindowState w = windowForClientLocked(session, client, false);
   2696                 if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
   2697                         "transparentRegionHint=" + region, false);
   2698 
   2699                 if ((w != null) && w.mHasSurface) {
   2700                     w.mWinAnimator.setTransparentRegionHintLocked(region);
   2701                 }
   2702             }
   2703         } finally {
   2704             Binder.restoreCallingIdentity(origId);
   2705         }
   2706     }
   2707 
   2708     void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets,
   2709             Rect visibleInsets, Region touchableRegion) {
   2710         long origId = Binder.clearCallingIdentity();
   2711         try {
   2712             synchronized (mWindowMap) {
   2713                 WindowState w = windowForClientLocked(session, client, false);
   2714                 if (DEBUG_LAYOUT) Slog.d(TAG, "setInsetsWindow " + w
   2715                         + ", contentInsets=" + w.mGivenContentInsets + " -> " + contentInsets
   2716                         + ", visibleInsets=" + w.mGivenVisibleInsets + " -> " + visibleInsets
   2717                         + ", touchableRegion=" + w.mGivenTouchableRegion + " -> " + touchableRegion
   2718                         + ", touchableInsets " + w.mTouchableInsets + " -> " + touchableInsets);
   2719                 if (w != null) {
   2720                     w.mGivenInsetsPending = false;
   2721                     w.mGivenContentInsets.set(contentInsets);
   2722                     w.mGivenVisibleInsets.set(visibleInsets);
   2723                     w.mGivenTouchableRegion.set(touchableRegion);
   2724                     w.mTouchableInsets = touchableInsets;
   2725                     if (w.mGlobalScale != 1) {
   2726                         w.mGivenContentInsets.scale(w.mGlobalScale);
   2727                         w.mGivenVisibleInsets.scale(w.mGlobalScale);
   2728                         w.mGivenTouchableRegion.scale(w.mGlobalScale);
   2729                     }
   2730                     w.setDisplayLayoutNeeded();
   2731                     mWindowPlacerLocked.performSurfacePlacement();
   2732                 }
   2733             }
   2734         } finally {
   2735             Binder.restoreCallingIdentity(origId);
   2736         }
   2737     }
   2738 
   2739     public void getWindowDisplayFrame(Session session, IWindow client,
   2740             Rect outDisplayFrame) {
   2741         synchronized(mWindowMap) {
   2742             WindowState win = windowForClientLocked(session, client, false);
   2743             if (win == null) {
   2744                 outDisplayFrame.setEmpty();
   2745                 return;
   2746             }
   2747             outDisplayFrame.set(win.mDisplayFrame);
   2748         }
   2749     }
   2750 
   2751     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
   2752         synchronized (mWindowMap) {
   2753             if (mAccessibilityController != null) {
   2754                 WindowState window = mWindowMap.get(token);
   2755                 //TODO (multidisplay): Magnification is supported only for the default display.
   2756                 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
   2757                     mAccessibilityController.onRectangleOnScreenRequestedLocked(rectangle);
   2758                 }
   2759             }
   2760         }
   2761     }
   2762 
   2763     public IWindowId getWindowId(IBinder token) {
   2764         synchronized (mWindowMap) {
   2765             WindowState window = mWindowMap.get(token);
   2766             return window != null ? window.mWindowId : null;
   2767         }
   2768     }
   2769 
   2770     public void pokeDrawLock(Session session, IBinder token) {
   2771         synchronized (mWindowMap) {
   2772             WindowState window = windowForClientLocked(session, token, false);
   2773             if (window != null) {
   2774                 window.pokeDrawLockLw(mDrawLockTimeoutMillis);
   2775             }
   2776         }
   2777     }
   2778 
   2779     void repositionChild(Session session, IWindow client,
   2780             int left, int top, int right, int bottom,
   2781             long frameNumber, Rect outFrame) {
   2782         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "repositionChild");
   2783         long origId = Binder.clearCallingIdentity();
   2784 
   2785         try {
   2786             synchronized(mWindowMap) {
   2787                 WindowState win = windowForClientLocked(session, client, false);
   2788                 if (win == null) {
   2789                     return;
   2790                 }
   2791                 if (win.mAttachedWindow == null) {
   2792                     throw new IllegalArgumentException(
   2793                             "repositionChild called but window is not"
   2794                             + "attached to a parent win=" + win);
   2795                 }
   2796 
   2797                 win.mAttrs.x = left;
   2798                 win.mAttrs.y = top;
   2799                 win.mAttrs.width = right - left;
   2800                 win.mAttrs.height = bottom - top;
   2801                 win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
   2802 
   2803                 if (win.mHasSurface) {
   2804                     if (SHOW_TRANSACTIONS) {
   2805                         Slog.i(TAG_WM, ">>> OPEN TRANSACTION repositionChild");
   2806                     }
   2807 
   2808                     SurfaceControl.openTransaction();
   2809 
   2810                     try {
   2811 
   2812                         win.applyGravityAndUpdateFrame(win.mContainingFrame, win.mDisplayFrame);
   2813                         win.mWinAnimator.computeShownFrameLocked();
   2814 
   2815                         win.mWinAnimator.setSurfaceBoundariesLocked(false);
   2816 
   2817                         if (frameNumber > 0) {
   2818                             win.mWinAnimator.deferTransactionUntilParentFrame(frameNumber);
   2819                         }
   2820 
   2821                     } finally {
   2822                         SurfaceControl.closeTransaction();
   2823                         if (SHOW_TRANSACTIONS) {
   2824                             Slog.i(TAG_WM, "<<< CLOSE TRANSACTION repositionChild");
   2825                         }
   2826                     }
   2827                 }
   2828 
   2829                 outFrame = win.mCompatFrame;
   2830             }
   2831         } finally {
   2832             Binder.restoreCallingIdentity(origId);
   2833             Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
   2834         }
   2835     }
   2836 
   2837     public int relayoutWindow(Session session, IWindow client, int seq,
   2838             WindowManager.LayoutParams attrs, int requestedWidth,
   2839             int requestedHeight, int viewVisibility, int flags,
   2840             Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
   2841             Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
   2842             Configuration outConfig, Surface outSurface) {
   2843         int result = 0;
   2844         boolean configChanged;
   2845         boolean hasStatusBarPermission =
   2846                 mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
   2847                         == PackageManager.PERMISSION_GRANTED;
   2848 
   2849         long origId = Binder.clearCallingIdentity();
   2850         synchronized(mWindowMap) {
   2851             WindowState win = windowForClientLocked(session, client, false);
   2852             if (win == null) {
   2853                 return 0;
   2854             }
   2855 
   2856             WindowStateAnimator winAnimator = win.mWinAnimator;
   2857             if (viewVisibility != View.GONE) {
   2858                 win.setRequestedSize(requestedWidth, requestedHeight);
   2859             }
   2860 
   2861             int attrChanges = 0;
   2862             int flagChanges = 0;
   2863             if (attrs != null) {
   2864                 mPolicy.adjustWindowParamsLw(attrs);
   2865                 // if they don't have the permission, mask out the status bar bits
   2866                 if (seq == win.mSeq) {
   2867                     int systemUiVisibility = attrs.systemUiVisibility
   2868                             | attrs.subtreeSystemUiVisibility;
   2869                     if ((systemUiVisibility & DISABLE_MASK) != 0) {
   2870                         if (!hasStatusBarPermission) {
   2871                             systemUiVisibility &= ~DISABLE_MASK;
   2872                         }
   2873                     }
   2874                     win.mSystemUiVisibility = systemUiVisibility;
   2875                 }
   2876                 if (win.mAttrs.type != attrs.type) {
   2877                     throw new IllegalArgumentException(
   2878                             "Window type can not be changed after the window is added.");
   2879                 }
   2880 
   2881                 // Odd choice but less odd than embedding in copyFrom()
   2882                 if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY)
   2883                         != 0) {
   2884                     attrs.x = win.mAttrs.x;
   2885                     attrs.y = win.mAttrs.y;
   2886                     attrs.width = win.mAttrs.width;
   2887                     attrs.height = win.mAttrs.height;
   2888                 }
   2889 
   2890                 flagChanges = win.mAttrs.flags ^= attrs.flags;
   2891                 attrChanges = win.mAttrs.copyFrom(attrs);
   2892                 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
   2893                         | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
   2894                     win.mLayoutNeeded = true;
   2895                 }
   2896             }
   2897 
   2898             if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
   2899                     + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
   2900             winAnimator.mSurfaceDestroyDeferred = (flags & RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
   2901             win.mEnforceSizeCompat =
   2902                     (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
   2903             if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
   2904                 winAnimator.mAlpha = attrs.alpha;
   2905             }
   2906             win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
   2907 
   2908             if (win.mAttrs.surfaceInsets.left != 0
   2909                     || win.mAttrs.surfaceInsets.top != 0
   2910                     || win.mAttrs.surfaceInsets.right != 0
   2911                     || win.mAttrs.surfaceInsets.bottom != 0) {
   2912                 winAnimator.setOpaqueLocked(false);
   2913             }
   2914 
   2915             boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
   2916             final boolean isDefaultDisplay = win.isDefaultDisplay();
   2917             boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
   2918                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
   2919                     || (!win.mRelayoutCalled));
   2920 
   2921             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
   2922                     && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
   2923             wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
   2924             if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {
   2925                 winAnimator.mSurfaceController.setSecure(isSecureLocked(win));
   2926             }
   2927 
   2928             win.mRelayoutCalled = true;
   2929             win.mInRelayout = true;
   2930 
   2931             final int oldVisibility = win.mViewVisibility;
   2932             win.mViewVisibility = viewVisibility;
   2933             if (DEBUG_SCREEN_ON) {
   2934                 RuntimeException stack = new RuntimeException();
   2935                 stack.fillInStackTrace();
   2936                 Slog.i(TAG_WM, "Relayout " + win + ": oldVis=" + oldVisibility
   2937                         + " newVis=" + viewVisibility, stack);
   2938             }
   2939             if (viewVisibility == View.VISIBLE &&
   2940                     (win.mAppToken == null || !win.mAppToken.clientHidden)) {
   2941                 result = relayoutVisibleWindow(outConfig, result, win, winAnimator, attrChanges,
   2942                         oldVisibility);
   2943                 try {
   2944                     result = createSurfaceControl(outSurface, result, win, winAnimator);
   2945                 } catch (Exception e) {
   2946                     mInputMonitor.updateInputWindowsLw(true /*force*/);
   2947 
   2948                     Slog.w(TAG_WM, "Exception thrown when creating surface for client "
   2949                              + client + " (" + win.mAttrs.getTitle() + ")",
   2950                              e);
   2951                     Binder.restoreCallingIdentity(origId);
   2952                     return 0;
   2953                 }
   2954                 if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
   2955                     focusMayChange = isDefaultDisplay;
   2956                 }
   2957                 if (win.mAttrs.type == TYPE_INPUT_METHOD && mInputMethodWindow == null) {
   2958                     mInputMethodWindow = win;
   2959                     imMayMove = true;
   2960                 }
   2961                 win.adjustStartingWindowFlags();
   2962             } else {
   2963                 winAnimator.mEnterAnimationPending = false;
   2964                 winAnimator.mEnteringAnimation = false;
   2965                 final boolean usingSavedSurfaceBeforeVisible =
   2966                         oldVisibility != View.VISIBLE && win.isAnimatingWithSavedSurface();
   2967                 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
   2968                     if (winAnimator.hasSurface() && !win.mAnimatingExit
   2969                             && usingSavedSurfaceBeforeVisible) {
   2970                         Slog.d(TAG, "Ignoring layout to invisible when using saved surface " + win);
   2971                     }
   2972                 }
   2973 
   2974                 if (winAnimator.hasSurface() && !win.mAnimatingExit
   2975                         && !usingSavedSurfaceBeforeVisible) {
   2976                     if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Relayout invis " + win
   2977                             + ": mAnimatingExit=" + win.mAnimatingExit);
   2978                     // If we are not currently running the exit animation, we
   2979                     // need to see about starting one.
   2980                     // We don't want to animate visibility of windows which are pending
   2981                     // replacement. In the case of activity relaunch child windows
   2982                     // could request visibility changes as they are detached from the main
   2983                     // application window during the tear down process. If we satisfied
   2984                     // these visibility changes though, we would cause a visual glitch
   2985                     // hiding the window before it's replacement was available.
   2986                     // So we just do nothing on our side.
   2987                     if (!win.mWillReplaceWindow) {
   2988                         focusMayChange = tryStartExitingAnimation(
   2989                                 win, winAnimator, isDefaultDisplay, focusMayChange);
   2990                     }
   2991                     result |= RELAYOUT_RES_SURFACE_CHANGED;
   2992                 }
   2993                 if (viewVisibility == View.VISIBLE && winAnimator.hasSurface()) {
   2994                     // We already told the client to go invisible, but the message may not be
   2995                     // handled yet, or it might want to draw a last frame. If we already have a
   2996                     // surface, let the client use that, but don't create new surface at this point.
   2997                     winAnimator.mSurfaceController.getSurface(outSurface);
   2998                 } else {
   2999                     if (DEBUG_VISIBILITY) Slog.i(TAG_WM, "Releasing surface in: " + win);
   3000 
   3001                     try {
   3002                         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmReleaseOutSurface_"
   3003                                 + win.mAttrs.getTitle());
   3004                         outSurface.release();
   3005                     } finally {
   3006                         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
   3007                     }
   3008                 }
   3009             }
   3010 
   3011             if (focusMayChange) {
   3012                 //System.out.println("Focus may change: " + win.mAttrs.getTitle());
   3013                 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
   3014                         false /*updateInputWindows*/)) {
   3015                     imMayMove = false;
   3016                 }
   3017                 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
   3018             }
   3019 
   3020             // updateFocusedWindowLocked() already assigned layers so we only need to
   3021             // reassign them at this point if the IM window state gets shuffled
   3022             boolean toBeDisplayed = (result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
   3023             if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
   3024                 // Little hack here -- we -should- be able to rely on the
   3025                 // function to return true if the IME has moved and needs
   3026                 // its layer recomputed.  However, if the IME was hidden
   3027                 // and isn't actually moved in the list, its layer may be
   3028                 // out of data so we make sure to recompute it.
   3029                 mLayersController.assignLayersLocked(win.getWindowList());
   3030             }
   3031 
   3032             if (wallpaperMayMove) {
   3033                 getDefaultDisplayContentLocked().pendingLayoutChanges |=
   3034                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
   3035             }
   3036 
   3037             win.setDisplayLayoutNeeded();
   3038             win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
   3039             configChanged = updateOrientationFromAppTokensLocked(false);
   3040             mWindowPlacerLocked.performSurfacePlacement();
   3041             if (toBeDisplayed && win.mIsWallpaper) {
   3042                 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
   3043                 mWallpaperControllerLocked.updateWallpaperOffset(
   3044                         win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
   3045             }
   3046             if (win.mAppToken != null) {
   3047                 win.mAppToken.updateReportedVisibilityLocked();
   3048             }
   3049             if (winAnimator.mReportSurfaceResized) {
   3050                 winAnimator.mReportSurfaceResized = false;
   3051                 result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED;
   3052             }
   3053             if (mPolicy.isNavBarForcedShownLw(win)) {
   3054                 result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR;
   3055             }
   3056             if (!win.isGoneForLayoutLw()) {
   3057                 win.mResizedWhileGone = false;
   3058             }
   3059             outFrame.set(win.mCompatFrame);
   3060             outOverscanInsets.set(win.mOverscanInsets);
   3061             outContentInsets.set(win.mContentInsets);
   3062             outVisibleInsets.set(win.mVisibleInsets);
   3063             outStableInsets.set(win.mStableInsets);
   3064             outOutsets.set(win.mOutsets);
   3065             outBackdropFrame.set(win.getBackdropFrame(win.mFrame));
   3066             if (localLOGV) Slog.v(
   3067                 TAG_WM, "Relayout given client " + client.asBinder()
   3068                 + ", requestedWidth=" + requestedWidth
   3069                 + ", requestedHeight=" + requestedHeight
   3070                 + ", viewVisibility=" + viewVisibility
   3071                 + "\nRelayout returning frame=" + outFrame
   3072                 + ", surface=" + outSurface);
   3073 
   3074             if (localLOGV || DEBUG_FOCUS) Slog.v(
   3075                 TAG_WM, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
   3076 
   3077             result |= mInTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0;
   3078 
   3079             mInputMonitor.updateInputWindowsLw(true /*force*/);
   3080 
   3081             if (DEBUG_LAYOUT) {
   3082                 Slog.v(TAG_WM, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
   3083             }
   3084             win.mInRelayout = false;
   3085         }
   3086 
   3087         if (configChanged) {
   3088             sendNewConfiguration();
   3089         }
   3090         Binder.restoreCallingIdentity(origId);
   3091         return result;
   3092     }
   3093 
   3094     private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator,
   3095             boolean isDefaultDisplay, boolean focusMayChange) {
   3096         // Try starting an animation; if there isn't one, we
   3097         // can destroy the surface right away.
   3098         int transit = WindowManagerPolicy.TRANSIT_EXIT;
   3099         if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
   3100             transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
   3101         }
   3102         if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
   3103             focusMayChange = isDefaultDisplay;
   3104             win.mAnimatingExit = true;
   3105             win.mWinAnimator.mAnimating = true;
   3106         } else if (win.mWinAnimator.isAnimationSet()) {
   3107             // Currently in a hide animation... turn this into
   3108             // an exit.
   3109             win.mAnimatingExit = true;
   3110             win.mWinAnimator.mAnimating = true;
   3111         } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
   3112             // If the wallpaper is currently behind this
   3113             // window, we need to change both of them inside
   3114             // of a transaction to avoid artifacts.
   3115             win.mAnimatingExit = true;
   3116             win.mWinAnimator.mAnimating = true;
   3117         } else {
   3118             if (mInputMethodWindow == win) {
   3119                 mInputMethodWindow = null;
   3120             }
   3121             win.destroyOrSaveSurface();
   3122         }
   3123         //TODO (multidisplay): Magnification is supported only for the default
   3124         if (mAccessibilityController != null
   3125                 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
   3126             mAccessibilityController.onWindowTransitionLocked(win, transit);
   3127         }
   3128         return focusMayChange;
   3129     }
   3130 
   3131     private int createSurfaceControl(Surface outSurface, int result, WindowState win,
   3132             WindowStateAnimator winAnimator) {
   3133         if (!win.mHasSurface) {
   3134             result |= RELAYOUT_RES_SURFACE_CHANGED;
   3135         }
   3136         WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
   3137         if (surfaceController != null) {
   3138             surfaceController.getSurface(outSurface);
   3139             if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, "  OUT SURFACE " + outSurface + ": copied");
   3140         } else {
   3141             // For some reason there isn't a surface.  Clear the
   3142             // caller's object so they see the same state.
   3143             Slog.w(TAG_WM, "Failed to create surface control for " + win);
   3144             outSurface.release();
   3145         }
   3146         return result;
   3147     }
   3148 
   3149     private int relayoutVisibleWindow(Configuration outConfig, int result, WindowState win,
   3150             WindowStateAnimator winAnimator, int attrChanges, int oldVisibility) {
   3151         result |= !win.isVisibleLw() ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0;
   3152         if (win.mAnimatingExit) {
   3153             Slog.d(TAG, "relayoutVisibleWindow: " + win + " mAnimatingExit=true, mRemoveOnExit="
   3154                     + win.mRemoveOnExit + ", mDestroying=" + win.mDestroying);
   3155 
   3156             winAnimator.cancelExitAnimationForNextAnimationLocked();
   3157             win.mAnimatingExit = false;
   3158         }
   3159         if (win.mDestroying) {
   3160             win.mDestroying = false;
   3161             mDestroySurface.remove(win);
   3162         }
   3163         if (oldVisibility == View.GONE) {
   3164             winAnimator.mEnterAnimationPending = true;
   3165         }
   3166 
   3167         win.mLastVisibleLayoutRotation = mRotation;
   3168 
   3169         winAnimator.mEnteringAnimation = true;
   3170         if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
   3171             win.prepareWindowToDisplayDuringRelayout(outConfig);
   3172         }
   3173         if ((attrChanges & LayoutParams.FORMAT_CHANGED) != 0) {
   3174             // If the format can't be changed in place, preserve the old surface until the app draws
   3175             // on the new one. This prevents blinking when we change elevation of freeform and
   3176             // pinned windows.
   3177             if (!winAnimator.tryChangeFormatInPlaceLocked()) {
   3178                 winAnimator.preserveSurfaceLocked();
   3179                 result |= RELAYOUT_RES_SURFACE_CHANGED
   3180                         | WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
   3181             }
   3182         }
   3183 
   3184         // If we're starting a drag-resize, we'll be changing the surface size as well as
   3185         // notifying the client to render to with an offset from the surface's top-left.
   3186         if (win.isDragResizeChanged() || win.isResizedWhileNotDragResizing()) {
   3187             win.setDragResizing();
   3188             win.setResizedWhileNotDragResizing(false);
   3189             // We can only change top level windows to the full-screen surface when
   3190             // resizing (as we only have one full-screen surface). So there is no need
   3191             // to preserve and destroy windows which are attached to another, they
   3192             // will keep their surface and its size may change over time.
   3193             if (win.mHasSurface && win.mAttachedWindow == null) {
   3194                 winAnimator.preserveSurfaceLocked();
   3195                 result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
   3196             }
   3197         }
   3198         final boolean freeformResizing = win.isDragResizing()
   3199                 && win.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;
   3200         final boolean dockedResizing = win.isDragResizing()
   3201                 && win.getResizeMode() == DRAG_RESIZE_MODE_DOCKED_DIVIDER;
   3202         result |= freeformResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM : 0;
   3203         result |= dockedResizing ? WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_DOCKED : 0;
   3204         if (win.isAnimatingWithSavedSurface()) {
   3205             // If we're animating with a saved surface now, request client to report draw.
   3206             // We still need to know when the real thing is drawn.
   3207             result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
   3208         }
   3209         return result;
   3210     }
   3211 
   3212     public void performDeferredDestroyWindow(Session session, IWindow client) {
   3213         long origId = Binder.clearCallingIdentity();
   3214 
   3215         try {
   3216             synchronized (mWindowMap) {
   3217                 WindowState win = windowForClientLocked(session, client, false);
   3218                 if (win == null || win.mWillReplaceWindow) {
   3219                     return;
   3220                 }
   3221 
   3222                 win.mWinAnimator.destroyDeferredSurfaceLocked();
   3223             }
   3224         } finally {
   3225             Binder.restoreCallingIdentity(origId);
   3226         }
   3227     }
   3228 
   3229     public boolean outOfMemoryWindow(Session session, IWindow client) {
   3230         long origId = Binder.clearCallingIdentity();
   3231 
   3232         try {
   3233             synchronized (mWindowMap) {
   3234                 WindowState win = windowForClientLocked(session, client, false);
   3235                 if (win == null) {
   3236                     return false;
   3237                 }
   3238                 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
   3239             }
   3240         } finally {
   3241             Binder.restoreCallingIdentity(origId);
   3242         }
   3243     }
   3244 
   3245     public void finishDrawingWindow(Session session, IWindow client) {
   3246         final long origId = Binder.clearCallingIdentity();
   3247         try {
   3248             synchronized (mWindowMap) {
   3249                 WindowState win = windowForClientLocked(session, client, false);
   3250                 if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
   3251                         + (win != null ? win.mWinAnimator.drawStateToString() : "null"));
   3252                 if (win != null && win.mWinAnimator.finishDrawingLocked()) {
   3253                     if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
   3254                         getDefaultDisplayContentLocked().pendingLayoutChanges |=
   3255                                 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
   3256                     }
   3257                     win.setDisplayLayoutNeeded();
   3258                     mWindowPlacerLocked.requestTraversal();
   3259                 }
   3260             }
   3261         } finally {
   3262             Binder.restoreCallingIdentity(origId);
   3263         }
   3264     }
   3265 
   3266     private boolean applyAnimationLocked(AppWindowToken atoken, WindowManager.LayoutParams lp,
   3267             int transit, boolean enter, boolean isVoiceInteraction) {
   3268         // Only apply an animation if the display isn't frozen.  If it is
   3269         // frozen, there is no reason to animate and it can cause strange
   3270         // artifacts when we unfreeze the display if some different animation
   3271         // is running.
   3272         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
   3273         if (okToDisplay()) {
   3274             DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
   3275             final int width = displayInfo.appWidth;
   3276             final int height = displayInfo.appHeight;
   3277             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG_WM,
   3278                     "applyAnimation: atoken=" + atoken);
   3279 
   3280             // Determine the visible rect to calculate the thumbnail clip
   3281             final WindowState win = atoken.findMainWindow();
   3282             final Rect frame = new Rect(0, 0, width, height);
   3283             final Rect displayFrame = new Rect(0, 0,
   3284                     displayInfo.logicalWidth, displayInfo.logicalHeight);
   3285             final Rect insets = new Rect();
   3286             Rect surfaceInsets = null;
   3287             final boolean freeform = win != null && win.inFreeformWorkspace();
   3288             if (win != null) {
   3289                 // Containing frame will usually cover the whole screen, including dialog windows.
   3290                 // For freeform workspace windows it will not cover the whole screen and it also
   3291                 // won't exactly match the final freeform window frame (e.g. when overlapping with
   3292                 // the status bar). In that case we need to use the final frame.
   3293                 if (freeform) {
   3294                     frame.set(win.mFrame);
   3295                 } else {
   3296                     frame.set(win.mContainingFrame);
   3297                 }
   3298                 surfaceInsets = win.getAttrs().surfaceInsets;
   3299                 insets.set(win.mContentInsets);
   3300             }
   3301 
   3302             if (atoken.mLaunchTaskBehind) {
   3303                 // Differentiate the two animations. This one which is briefly on the screen
   3304                 // gets the !enter animation, and the other activity which remains on the
   3305                 // screen gets the enter animation. Both appear in the mOpeningApps set.
   3306                 enter = false;
   3307             }
   3308             if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition."
   3309                     + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter
   3310                     + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets);
   3311             Animation a = mAppTransition.loadAnimation(lp, transit, enter, mCurConfiguration.uiMode,
   3312                     mCurConfiguration.orientation, frame, displayFrame, insets, surfaceInsets,
   3313                     isVoiceInteraction, freeform, atoken.mTask.mTaskId);
   3314             if (a != null) {
   3315                 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken);
   3316                 final int containingWidth = frame.width();
   3317                 final int containingHeight = frame.height();
   3318                 atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight,
   3319                         mAppTransition.canSkipFirstFrame(), mAppTransition.getAppStackClipMode());
   3320             }
   3321         } else {
   3322             atoken.mAppAnimator.clearAnimation();
   3323         }
   3324         Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
   3325 
   3326         return atoken.mAppAnimator.animation != null;
   3327     }
   3328 
   3329     // -------------------------------------------------------------
   3330     // Application Window Tokens
   3331     // -------------------------------------------------------------
   3332 
   3333     public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
   3334         synchronized (mWindowMap) {
   3335             int t = tasks.size() - 1;
   3336             if (t < 0) {
   3337                 Slog.w(TAG_WM, "validateAppTokens: empty task list");
   3338                 return;
   3339             }
   3340 
   3341             TaskGroup task = tasks.get(0);
   3342             int taskId = task.taskId;
   3343             Task targetTask = mTaskIdToTask.get(taskId);
   3344             DisplayContent displayContent = targetTask.getDisplayContent();
   3345             if (displayContent == null) {
   3346                 Slog.w(TAG_WM, "validateAppTokens: no Display for taskId=" + taskId);
   3347                 return;
   3348             }
   3349 
   3350             final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
   3351             int taskNdx;
   3352             for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
   3353                 AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
   3354                 task = tasks.get(t);
   3355                 List<IApplicationToken> tokens = task.tokens;
   3356 
   3357                 DisplayContent lastDisplayContent = displayContent;
   3358                 displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
   3359                 if (displayContent != lastDisplayContent) {
   3360                     Slog.w(TAG_WM, "validateAppTokens: displayContent changed in TaskGroup list!"