WindowManagerService.java revision 85b764e22babfe5508286fbad5d7fee12345704f
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server.wm; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static android.view.WindowManager.LayoutParams.*; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 210795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopianimport static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 220795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopianimport android.app.AppOpsManager; 230795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopianimport android.util.ArraySet; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TimeUtils; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowId; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowSessionCallback; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowContentFrameStats; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.app.IBatteryStats; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.policy.PolicyManager; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.policy.impl.PhoneWindowManager; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.util.FastPrintWriter; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputContext; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodClient; 35242d65bf9faf1d2bc3468490e510551140e23462San Mehatimport com.android.internal.view.IInputMethodManager; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.WindowManagerPolicyThread; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.AttributeCache; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.DisplayThread; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.EventLogTags; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.LocalServices; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.UiThread; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.Watchdog; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.am.BatteryStatsService; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.input.InputManagerService; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.power.ShutdownThread; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.Manifest; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.IActivityManager; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.StatusBarManager; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.admin.DevicePolicyManager; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.animation.ValueAnimator; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 54957e58670baad8c5995f1368e3b5280f0dbd891fSan Mehatimport android.content.ContentResolver; 55a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehatimport android.content.Context; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ActivityInfo; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.CompatibilityInfo; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Configuration; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap.Config; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Matrix; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Point; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.RectF; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Region; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.hardware.display.DisplayManager; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.hardware.display.DisplayManagerInternal; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 79e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.IRemoteCallback; 80e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.Looper; 81e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.Message; 82e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.Parcel; 83e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.ParcelFileDescriptor; 84e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.PowerManager; 85e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.PowerManagerInternal; 86e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.Process; 87e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.RemoteException; 88e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.ServiceManager; 89e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.StrictMode; 90e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.SystemClock; 91e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.SystemProperties; 92e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.Trace; 93e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.UserHandle; 94e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.os.WorkSource; 95e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.provider.Settings; 96e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.util.DisplayMetrics; 97e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.util.EventLog; 98e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.util.Log; 99e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.util.SparseArray; 100e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehatimport android.util.Pair; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Slog; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseIntArray; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Choreographer; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Display; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.DisplayInfo; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IApplicationToken; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IInputFilter; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IOnKeyguardExitResult; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IRotationWatcher; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindow; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowSession; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.InputChannel; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.InputDevice; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.InputEvent; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.InputEventReceiver; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MagnificationSpec; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManagerInternal; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface.OutOfResourcesException; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SurfaceControl; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.SurfaceSession; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewTreeObserver; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManagerGlobal; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManagerPolicy; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager.LayoutParams; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManagerPolicy.FakeWindow; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManagerPolicy.PointerEventListener; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Animation; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.AnimationUtils; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.Transformation; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.BufferedWriter; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.DataInputStream; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStreamWriter; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.StringWriter; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.net.Socket; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.text.DateFormat; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Date; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** {@hide} */ 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WindowManagerService extends IWindowManager.Stub 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "WindowManager"; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG = false; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_ADD_REMOVE = false; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_FOCUS = false; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_ANIM = false; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_LAYOUT = false; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_RESIZE = false; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_LAYERS = false; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_INPUT = false; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_INPUT_METHOD = false; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_VISIBILITY = false; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_WINDOW_MOVEMENT = false; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_TOKEN_MOVEMENT = false; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_ORIENTATION = false; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_APP_ORIENTATION = false; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_CONFIGURATION = false; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_APP_TRANSITIONS = false; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_STARTING_WINDOW = false; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_REORDER = false; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_WALLPAPER = false; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_DRAG = false; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_SCREEN_ON = false; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_SCREENSHOT = false; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_BOOT = false; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_LAYOUT_REPEATS = true; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_SURFACE_TRACE = false; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_WINDOW_TRACE = false; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_TASK_MOVEMENT = false; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG_STACK = false; 192e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat static final boolean DEBUG_DISPLAY = false; 193e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat static final boolean SHOW_SURFACE_ALLOC = false; 194e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat static final boolean SHOW_TRANSACTIONS = false; 195e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS; 196e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat static final boolean HIDE_STACK_CRAWLS = true; 197e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat static final int LAYOUT_REPEAT_THRESHOLD = 4; 198e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat 199242d65bf9faf1d2bc3468490e510551140e23462San Mehat static final boolean PROFILE_ORIENTATION = false; 200242d65bf9faf1d2bc3468490e510551140e23462San Mehat static final boolean localLOGV = DEBUG; 201242d65bf9faf1d2bc3468490e510551140e23462San Mehat 202242d65bf9faf1d2bc3468490e510551140e23462San Mehat /** How much to multiply the policy's type layer, to reserve room 203e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat * for multiple windows of the same type and Z-ordering adjustment 204e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat * with TYPE_LAYER_OFFSET. */ 2053e458241d9930465a20a861ecb42744355d48e48San Mehat static final int TYPE_LAYER_MULTIPLIER = 10000; 2063e458241d9930465a20a861ecb42744355d48e48San Mehat 2073e458241d9930465a20a861ecb42744355d48e48San Mehat /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above 2083e458241d9930465a20a861ecb42744355d48e48San Mehat * or below others in the same layer. */ 2093e458241d9930465a20a861ecb42744355d48e48San Mehat static final int TYPE_LAYER_OFFSET = 1000; 2103e458241d9930465a20a861ecb42744355d48e48San Mehat 2113e458241d9930465a20a861ecb42744355d48e48San Mehat /** How much to increment the layer for each window, to reserve room 2123e458241d9930465a20a861ecb42744355d48e48San Mehat * for effect surfaces between them. 2133e458241d9930465a20a861ecb42744355d48e48San Mehat */ 2143e458241d9930465a20a861ecb42744355d48e48San Mehat static final int WINDOW_LAYER_MULTIPLIER = 5; 2153e458241d9930465a20a861ecb42744355d48e48San Mehat 2163e458241d9930465a20a861ecb42744355d48e48San Mehat /** 217a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat * Dim surface layer is immediately below target window. 218a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat */ 219a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat static final int LAYER_OFFSET_DIM = 1; 220a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat 221a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat /** 222a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat * Blur surface layer is immediately below dim layer. 223a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat */ 224a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat static final int LAYER_OFFSET_BLUR = 2; 225a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat 226a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat /** 227a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat * FocusedStackFrame layer is immediately above focused window. 228a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat */ 229a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat static final int LAYER_OFFSET_FOCUSED_STACK = 1; 230a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat 231a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat /** 232a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat * Animation thumbnail is as far as possible below the window above 233a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat * the thumbnail (or in other words as far as possible above the window 234a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat * below it). 235a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat */ 236a5109a878eeff22e32ee5ce1b1cd15e8daad5234San Mehat static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1; 2373e458241d9930465a20a861ecb42744355d48e48San Mehat 2383e458241d9930465a20a861ecb42744355d48e48San Mehat /** 2391fd0ec738b0a2b97cc28701aa37b1a9869afc684San Mehat * Layer at which to put the rotation freeze snapshot. 2401fd0ec738b0a2b97cc28701aa37b1a9869afc684San Mehat */ 2411fd0ec738b0a2b97cc28701aa37b1a9869afc684San Mehat static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1; 2423e458241d9930465a20a861ecb42744355d48e48San Mehat 2433e458241d9930465a20a861ecb42744355d48e48San Mehat /** 2443e458241d9930465a20a861ecb42744355d48e48San Mehat * Layer at which to put the mask for emulated screen sizes. 2453e458241d9930465a20a861ecb42744355d48e48San Mehat */ 2467e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200; 2477e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat 2487e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat /** The maximum length we will accept for a loaded animation duration: 2493e458241d9930465a20a861ecb42744355d48e48San Mehat * this is 10 seconds. 2503e458241d9930465a20a861ecb42744355d48e48San Mehat */ 2517e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat static final int MAX_ANIMATION_DURATION = 10*1000; 2527e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat 2537e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat /** Amount of time (in milliseconds) to animate the fade-in-out transition for 2547e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat * compatible windows. 2557e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat */ 2567e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat static final int DEFAULT_FADE_IN_OUT_DURATION = 400; 2571fd0ec738b0a2b97cc28701aa37b1a9869afc684San Mehat 2587e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */ 2597e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000; 2607e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat 2617e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat /** 2627e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat * If true, the window manager will do its own custom freezing and general 2637e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat * management of the screen during rotation. 2647e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat */ 2657e63789a0e0689d940609b1daceebc1bc08dcbefSan Mehat static final boolean CUSTOM_SCREEN_ROTATION = true; 266242d65bf9faf1d2bc3468490e510551140e23462San Mehat 267242d65bf9faf1d2bc3468490e510551140e23462San Mehat // Maximum number of milliseconds to wait for input devices to be enumerated before 268242d65bf9faf1d2bc3468490e510551140e23462San Mehat // proceding with safe mode detection. 269242d65bf9faf1d2bc3468490e510551140e23462San Mehat private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000; 2703e458241d9930465a20a861ecb42744355d48e48San Mehat 2713e458241d9930465a20a861ecb42744355d48e48San Mehat // Default input dispatching timeout in nanoseconds. 2723e458241d9930465a20a861ecb42744355d48e48San Mehat static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; 2733e458241d9930465a20a861ecb42744355d48e48San Mehat 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum value for attachStack and resizeStack weight value */ 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float STACK_WEIGHT_MIN = 0.2f; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 277242d65bf9faf1d2bc3468490e510551140e23462San Mehat /** Maximum value for attachStack and resizeStack weight value */ 278242d65bf9faf1d2bc3468490e510551140e23462San Mehat public static final float STACK_WEIGHT_MAX = 0.8f; 2797d619f18a277ee3114624df7301db94db83936b9San Mehat 280242d65bf9faf1d2bc3468490e510551140e23462San Mehat static final int UPDATE_FOCUS_NORMAL = 0; 2817d619f18a277ee3114624df7301db94db83936b9San Mehat static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1; 282242d65bf9faf1d2bc3468490e510551140e23462San Mehat static final int UPDATE_FOCUS_PLACING_SURFACES = 2; 283242d65bf9faf1d2bc3468490e510551140e23462San Mehat static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3; 284242d65bf9faf1d2bc3468490e510551140e23462San Mehat 285242d65bf9faf1d2bc3468490e510551140e23462San Mehat private static final String SYSTEM_SECURE = "ro.secure"; 286242d65bf9faf1d2bc3468490e510551140e23462San Mehat private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 287e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat 288e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat private static final String DENSITY_OVERRIDE = "ro.config.density_override"; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String SIZE_OVERRIDE = "ro.config.size_override"; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SCREENSHOT_RETRIES = 3; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The flag describing a full screen app window (where the app takes care of drawing under the 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // SystemUI bars) 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN = 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final private KeyguardDisableHandler mKeyguardDisableHandler; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String action = intent.getAction(); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) { 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeyguardDisableHandler.sendEmptyMessage( 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Current user when multi-user is enabled. Don't show windows of 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * non-current user. Also see mCurrentProfileIds. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCurrentUserId; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Users that are profiles of the current user. These are also allowed to show windows 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on the current user. 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Context mContext; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean mHaveInputMethods; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean mAllowBootMessages; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean mLimitedAlphaCompositing; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager(); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IActivityManager mActivityManager; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IBatteryStats mBatteryStats; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final AppOpsManager mAppOps; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplaySettings mDisplaySettings; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All currently active sessions with clients. 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArraySet<Session> mSessions = new ArraySet<Session>(); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mapping from an IWindow IBinder to the server's Window object. 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is also used as the lock for all of our state. 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * NOTE: Never call into methods that lock ActivityManagerService while holding this object. 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>(); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mapping from a token IBinder to a WindowToken object. 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>(); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * List of window tokens that have finished starting their application, 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and now need to have the policy remove their windows. 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>(); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fake windows added to the window manager. Note: ordered from top to 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * bottom, opposite of mWindows. 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>(); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Windows that are being resized. Used so we can tell the client about 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the resize after closing the transaction in which we resized the 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying surface. 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>(); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Windows whose animations have ended and now must be removed. 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3820bca96bcbfe559f9330a01f723c5c9cba51ec05aMarco Nelissen * Stacks whose animations have ended and whose tasks, apps, selves may now be removed. 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArraySet<TaskStack> mPendingStacksRemove = new ArraySet<TaskStack>(); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Used when processing mPendingRemove to avoid working on the original array. 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState[] mPendingRemoveTmp = new WindowState[20]; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Windows whose surface should be destroyed. 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>(); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Windows that have lost input focus and are waiting for the new 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * focus window to be displayed before they are told about this. 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>(); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4020bca96bcbfe559f9330a01f723c5c9cba51ec05aMarco Nelissen /** 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is set when we have run out of memory, and will either be an empty 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * list or contain windows that need to be force removed. 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<WindowState> mForceRemoves; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Windows that clients are waiting to have drawn. 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<WindowState> mWaitingForDrawn = new ArrayList<WindowState>(); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * And the callback to make when they've all been drawn. 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Runnable mWaitingForDrawnCallback; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Windows that have called relayout() while we were running animations, 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * so we need to tell when the animation is done. 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4210bca96bcbfe559f9330a01f723c5c9cba51ec05aMarco Nelissen final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>(); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Used when rebuilding window list to keep track of windows that have 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * been removed. 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState[] mRebuildTmp = new WindowState[20]; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Stores for each user whether screencapture is disabled 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This array is essentially a cache for all userId for 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.app.admin.DevicePolicyManager#getScreenCaptureDisabled} 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SparseArray<Boolean> mScreenCaptureDisabled = new SparseArray<Boolean>(); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputMethodManager mInputMethodManager; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AccessibilityController mAccessibilityController; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SurfaceSession mFxSession; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Watermark mWatermark; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StrictModeFlash mStrictModeFlash; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CircularDisplayMask mCircularDisplayMask; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FocusedStackFrame mFocusedStackFrame; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mFocusedStackLayer; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] mTmpFloats = new float[9]; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mTmpContentRect = new Rect(); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mDisplayReady; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mSafeMode; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mDisplayEnabled = false; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mSystemBooted = false; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mForceDisplayEnabled = false; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mShowingBootMessages = false; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mLastANRState; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** All DisplayContents in the world, kept here */ 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mRotation = 0; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAltOrientation = false; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mKeyguardWaitingForActivityDrawn; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class RotationWatcher { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IRotationWatcher watcher; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder.DeathRecipient deathRecipient; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RotationWatcher(IRotationWatcher w, IBinder.DeathRecipient d) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project watcher = w; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deathRecipient = d; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>(); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mDeferredRotationPauseCount; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSystemDecorLayer = 0; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Rect mScreenRect = new Rect(); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mTraversalScheduled = false; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mDisplayFrozen = false; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mDisplayFreezeTime = 0; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLastDisplayFreezeDuration = 0; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object mLastFinishedFreezeSource = null; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWaitingForConfig = false; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWindowsFreezingScreen = false; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mClientFreezingScreen = false; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mAppsFreezingScreen = 0; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLayoutSeq = 0; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mLastStatusBarVisibility = 0; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // State while inside of layoutAndPlaceSurfacesLocked(). 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mFocusMayChange; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Configuration mCurConfiguration = new Configuration(); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is held as long as we have the screen frozen, to give us time to 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // perform a rotation animation when turning off shows the lock screen which 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // changes the orientation. 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PowerManager.WakeLock mScreenFrozenLock; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final AppTransition mAppTransition; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mStartingIconInTransition = false; 510add868cebaf62cffe96e79764ea0b7f2320a03ebAmith Yamasani boolean mSkipAppTransitionAnimation = false; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<AppWindowToken>(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArraySet<AppWindowToken> mClosingApps = new ArraySet<AppWindowToken>(); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mIsTouchDevice; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplayMetrics mDisplayMetrics = new DisplayMetrics(); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics(); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics(); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics(); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final H mH = new H(); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Choreographer mChoreographer = Choreographer.getInstance(); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mCurrentFocus = null; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mLastFocus = null; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This just indicates the window the input method is on top of, not 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * necessarily the window its input is going to. */ 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mInputMethodTarget = null; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** If true hold off on modifying the animation layer of mInputMethodTarget */ 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mInputMethodTargetWaitingAnim; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mInputMethodAnimLayerAdjustment; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mInputMethodWindow = null; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>(); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mHardKeyboardAvailable; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mShowImeWithHardKeyboard; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SettingsObserver mSettingsObserver; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class SettingsObserver extends ContentObserver { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SettingsObserver() { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(new Handler()); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resolver.registerContentObserver(Settings.Secure.getUriFor( 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onChange(boolean selfChange) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateShowImeWithHardKeyboard(); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>(); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If non-null, this is the currently visible window that is associated 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with the wallpaper. 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mWallpaperTarget = null; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If non-null, we are in the middle of animating from one wallpaper target 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to another, and this is the lower one in Z-order. 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mLowerWallpaperTarget = null; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If non-null, we are in the middle of animating from one wallpaper target 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to another, and this is the higher one in Z-order. 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mUpperWallpaperTarget = null; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mWallpaperAnimLayerAdjustment; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mLastWallpaperX = -1; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mLastWallpaperY = -1; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mLastWallpaperXStep = -1; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mLastWallpaperYStep = -1; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is set when we are waiting for a wallpaper to tell us it is done 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // changing its scroll position. 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowState mWaitingOnWallpaper; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The last time we had a timeout when waiting for a wallpaper. 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mLastWallpaperTimeoutTime; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We give a wallpaper up to 150ms to finish scrolling. 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final long WALLPAPER_TIMEOUT = 150; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Time we wait after a timeout before trying to wait again. 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final long WALLPAPER_TIMEOUT_RECOVERY = 10000; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAnimateWallpaperWithTarget; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AppWindowToken mFocusedApp = null; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager mPowerManager; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManagerInternal mPowerManagerInternal; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mWindowAnimationScaleSetting = 1.0f; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mTransitionAnimationScaleSetting = 1.0f; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mAnimatorDurationScaleSetting = 1.0f; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAnimationsDisabled = false; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputManagerService mInputManager; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplayManagerInternal mDisplayManagerInternal; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final DisplayManager mDisplayManager; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Who is holding the screen on. 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Session mHoldingScreenOn; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager.WakeLock mHoldingScreenWakeLock; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mTurnOnScreen; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DragState mDragState = null; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For frozen screen animations. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mExitAnimId, mEnterAnimId; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * methods. */ 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class LayoutFields { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int SET_UPDATE_ROTATION = 1 << 0; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int SET_FORCE_HIDING_CHANGED = 1 << 2; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int SET_TURN_ON_SCREEN = 1 << 4; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWallpaperForceHidingChanged = false; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWallpaperMayChange = false; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mOrientationChangeComplete = true; 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object mLastWindowFreezeSource = null; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Session mHoldScreen = null; 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mObscured = false; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mSyswin = false; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mScreenBrightness = -1; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mButtonBrightness = -1; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mUserActivityTimeout = -1; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mUpdateRotation = false; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mWallpaperActionPending = false; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set to true when the display contains content to show the user. 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // When false, the display manager may choose to mirror or blank the display. 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mDisplayHasContent = false; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 638c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // Only set while traversing the default display based on its content. 639c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // Affects the behavior of mirroring on secondary displays. 640c64edde69d18498fb2954f71a546357b07ab996aEvan Millar boolean mObscureApplicationContentOnSecondaryDisplays = false; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float mPreferredRefreshRate = 0; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final LayoutFields mInnerFields = new LayoutFields(); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mAnimationScheduled; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */ 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTransactionSequence; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Only do a maximum of 6 repeated layouts. After that quit */ 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLayoutRepeatCount; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowAnimator mAnimator; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SparseArray<Task> mTaskIdToTask = new SparseArray<Task>(); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** All of the TaskStacks in the window manager, unordered. For an ordered list call 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * DisplayContent.getStacks(). */ 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>(); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final PointerEventDispatcher mPointerEventDispatcher; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WindowContentFrameStats mTempWindowRenderStats; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final class DragInputEventReceiver extends InputEventReceiver { 668c64edde69d18498fb2954f71a546357b07ab996aEvan Millar public DragInputEventReceiver(InputChannel inputChannel, Looper looper) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(inputChannel, looper); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onInputEvent(InputEvent event) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = false; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event instanceof MotionEvent 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mDragState != null) { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final MotionEvent motionEvent = (MotionEvent)event; 680c64edde69d18498fb2954f71a546357b07ab996aEvan Millar boolean endDrag = false; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float newX = motionEvent.getRawX(); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float newY = motionEvent.getRawY(); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (motionEvent.getAction()) { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_DOWN: { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_DRAG) { 687c64edde69d18498fb2954f71a546357b07ab996aEvan Millar Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer"); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_MOVE: { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mWindowMap) { 693c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // move the surface and tell the involved window(s) where we are 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDragState.notifyMoveLw(newX, newY); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_UP: { 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at " 700c64edde69d18498fb2954f71a546357b07ab996aEvan Millar + newX + "," + newY); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mWindowMap) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endDrag = mDragState.notifyDropLw(newX, newY); 703c64edde69d18498fb2954f71a546357b07ab996aEvan Millar } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MotionEvent.ACTION_CANCEL: { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!"); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endDrag = true; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (endDrag) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state"); 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // tell all the windows that the drag has ended 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mWindowMap) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDragState.endDragLw(); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handled = true; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Slog.e(TAG, "Exception caught by drag handleMotion", e); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finishInputEvent(event, handled); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Whether the UI is currently running in touch mode (not showing 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * navigational focus because the user is directly pressing the screen). 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mInTouchMode = true; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ViewServer mViewServer; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<WindowChangeListener> mWindowChangeListeners = 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ArrayList<WindowChangeListener>(); 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mWindowsChanged = false; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface WindowChangeListener { 742c64edde69d18498fb2954f71a546357b07ab996aEvan Millar public void windowsChanged(); 743c64edde69d18498fb2954f71a546357b07ab996aEvan Millar public void focusChanged(); 744c64edde69d18498fb2954f71a546357b07ab996aEvan Millar } 745c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 746c64edde69d18498fb2954f71a546357b07ab996aEvan Millar final Configuration mTempConfiguration = new Configuration(); 747c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 748c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // The desired scaling factor for compatible apps. 749c64edde69d18498fb2954f71a546357b07ab996aEvan Millar float mCompatibleScreenScale; 750c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 751c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // If true, only the core apps and services are being launched because the device 752c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // is in a special boot mode, such as being encrypted or waiting for a decryption password. 753c64edde69d18498fb2954f71a546357b07ab996aEvan Millar // For example, when this flag is true, there will be no wallpaper service. 754c64edde69d18498fb2954f71a546357b07ab996aEvan Millar final boolean mOnlyCore; 755c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 756c64edde69d18498fb2954f71a546357b07ab996aEvan Millar public static WindowManagerService main(final Context context, 757c64edde69d18498fb2954f71a546357b07ab996aEvan Millar final InputManagerService im, 758c64edde69d18498fb2954f71a546357b07ab996aEvan Millar final boolean haveInputMethods, final boolean showBootMsgs, 759c64edde69d18498fb2954f71a546357b07ab996aEvan Millar final boolean onlyCore) { 760c64edde69d18498fb2954f71a546357b07ab996aEvan Millar final WindowManagerService[] holder = new WindowManagerService[1]; 761c64edde69d18498fb2954f71a546357b07ab996aEvan Millar DisplayThread.getHandler().runWithScissors(new Runnable() { 762c64edde69d18498fb2954f71a546357b07ab996aEvan Millar @Override 763c64edde69d18498fb2954f71a546357b07ab996aEvan Millar public void run() { 764c64edde69d18498fb2954f71a546357b07ab996aEvan Millar holder[0] = new WindowManagerService(context, im, 765c64edde69d18498fb2954f71a546357b07ab996aEvan Millar haveInputMethods, showBootMsgs, onlyCore); 766c64edde69d18498fb2954f71a546357b07ab996aEvan Millar } 767c64edde69d18498fb2954f71a546357b07ab996aEvan Millar }, 0); 768c64edde69d18498fb2954f71a546357b07ab996aEvan Millar return holder[0]; 769c64edde69d18498fb2954f71a546357b07ab996aEvan Millar } 770c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 771c64edde69d18498fb2954f71a546357b07ab996aEvan Millar private void initPolicy() { 772c64edde69d18498fb2954f71a546357b07ab996aEvan Millar UiThread.getHandler().runWithScissors(new Runnable() { 773c64edde69d18498fb2954f71a546357b07ab996aEvan Millar @Override 774c64edde69d18498fb2954f71a546357b07ab996aEvan Millar public void run() { 775c64edde69d18498fb2954f71a546357b07ab996aEvan Millar WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper()); 776c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 777c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this); 778c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer() 779c64edde69d18498fb2954f71a546357b07ab996aEvan Millar * TYPE_LAYER_MULTIPLIER 780c64edde69d18498fb2954f71a546357b07ab996aEvan Millar + TYPE_LAYER_OFFSET; 781c64edde69d18498fb2954f71a546357b07ab996aEvan Millar } 782c64edde69d18498fb2954f71a546357b07ab996aEvan Millar }, 0); 783c64edde69d18498fb2954f71a546357b07ab996aEvan Millar } 784c64edde69d18498fb2954f71a546357b07ab996aEvan Millar 785c64edde69d18498fb2954f71a546357b07ab996aEvan Millar private WindowManagerService(Context context, InputManagerService inputManager, 786c64edde69d18498fb2954f71a546357b07ab996aEvan Millar boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) { 787c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mContext = context; 788c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mHaveInputMethods = haveInputMethods; 789c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mAllowBootMessages = showBootMsgs; 790c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mOnlyCore = onlyCore; 791c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mLimitedAlphaCompositing = context.getResources().getBoolean( 792c64edde69d18498fb2954f71a546357b07ab996aEvan Millar com.android.internal.R.bool.config_sf_limitedAlpha); 793c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mInputManager = inputManager; // Must be before createDisplayContentLocked. 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplaySettings = new DisplaySettings(context); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplaySettings.readSettingsLocked(); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LocalServices.addService(WindowManagerPolicy.class, mPolicy); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG)); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFxSession = new SurfaceSession(); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Display[] displays = mDisplayManager.getDisplays(); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Display display : displays) { 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createDisplayContentLocked(display); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPowerManagerInternal.registerLowPowerModeObserver( 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new PowerManagerInternal.LowPowerModeListener() { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onLowPowerModeChanged(boolean enabled) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mWindowMap) { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAnimationsDisabled != enabled) { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationsDisabled = enabled; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dispatchNewAnimatorScaleLocked(null); 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAnimationsDisabled = mPowerManagerInternal.getLowPowerModeEnabled(); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenFrozenLock = mPowerManager.newWakeLock( 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN"); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenFrozenLock.setReferenceCounted(false); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAppTransition = new AppTransition(context, mH); 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActivityManager = ActivityManagerNative.getDefault(); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatteryStats = BatteryStatsService.getService(); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AppOpsManager.OnOpChangedInternalListener opListener = 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new AppOpsManager.OnOpChangedInternalListener() { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void onOpChanged(int op, String packageName) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateAppOpsState(); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null, opListener); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get persisted window scale setting 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(), 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(), 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScaleSetting); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(), 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting)); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Track changes to DevicePolicyManager state so we can enable/disable keyguard. 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter filter = new IntentFilter(); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(mBroadcastReceiver, filter); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSettingsObserver = new SettingsObserver(); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateShowImeWithHardKeyboard(); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHoldingScreenWakeLock = mPowerManager.newWakeLock( 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, TAG); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHoldingScreenWakeLock.setReferenceCounted(false); 863e9d376b801b7890b1ef5006ed55de4208e64bb63San Mehat 8643e458241d9930465a20a861ecb42744355d48e48San Mehat mAnimator = new WindowAnimator(this); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LocalServices.addService(WindowManagerInternal.class, new LocalService()); 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initPolicy(); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Add ourself to the Watchdog monitors. 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Watchdog.getInstance().addMonitor(this); 8710bca96bcbfe559f9330a01f723c5c9cba51ec05aMarco Nelissen 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SurfaceControl.openTransaction(); 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project createWatermarkInTransaction(); 875c64edde69d18498fb2954f71a546357b07ab996aEvan Millar mFocusedStackFrame = new FocusedStackFrame( 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getDefaultDisplayContentLocked().getDisplay(), mFxSession); 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SurfaceControl.closeTransaction(); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showCircularDisplayMaskIfNeeded(); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public InputMonitor getInputMonitor() { 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mInputMonitor; 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws RemoteException { 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTransact(code, data, reply, flags); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 894 // The window manager only throws security exceptions, so let's 895 // log all others. 896 if (!(e instanceof SecurityException)) { 897 Slog.wtf(TAG, "Window Manager Crash", e); 898 } 899 throw e; 900 } 901 } 902 903 private void placeWindowAfter(WindowState pos, WindowState window) { 904 final WindowList windows = pos.getWindowList(); 905 final int i = windows.indexOf(pos); 906 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( 907 TAG, "Adding window " + window + " at " 908 + (i+1) + " of " + windows.size() + " (after " + pos + ")"); 909 windows.add(i+1, window); 910 mWindowsChanged = true; 911 } 912 913 private void placeWindowBefore(WindowState pos, WindowState window) { 914 final WindowList windows = pos.getWindowList(); 915 int i = windows.indexOf(pos); 916 if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( 917 TAG, "Adding window " + window + " at " 918 + i + " of " + windows.size() + " (before " + pos + ")"); 919 if (i < 0) { 920 Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows); 921 i = 0; 922 } 923 windows.add(i, window); 924 mWindowsChanged = true; 925 } 926 927 //This method finds out the index of a window that has the same app token as 928 //win. used for z ordering the windows in mWindows 929 private int findIdxBasedOnAppTokens(WindowState win) { 930 WindowList windows = win.getWindowList(); 931 for(int j = windows.size() - 1; j >= 0; j--) { 932 WindowState wentry = windows.get(j); 933 if(wentry.mAppToken == win.mAppToken) { 934 return j; 935 } 936 } 937 return -1; 938 } 939 940 /** 941 * Return the list of Windows from the passed token on the given Display. 942 * @param token The token with all the windows. 943 * @param displayContent The display we are interested in. 944 * @return List of windows from token that are on displayContent. 945 */ 946 WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) { 947 final WindowList windowList = new WindowList(); 948 final int count = token.windows.size(); 949 for (int i = 0; i < count; i++) { 950 final WindowState win = token.windows.get(i); 951 if (win.getDisplayContent() == displayContent) { 952 windowList.add(win); 953 } 954 } 955 return windowList; 956 } 957 958 /** 959 * Recursive search through a WindowList and all of its windows' children. 960 * @param targetWin The window to search for. 961 * @param windows The list to search. 962 * @return The index of win in windows or of the window that is an ancestor of win. 963 */ 964 private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) { 965 for (int i = windows.size() - 1; i >= 0; i--) { 966 final WindowState w = windows.get(i); 967 if (w == targetWin) { 968 return i; 969 } 970 if (!w.mChildWindows.isEmpty()) { 971 if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) { 972 return i; 973 } 974 } 975 } 976 return -1; 977 } 978 979 private int addAppWindowToListLocked(final WindowState win) { 980 final IWindow client = win.mClient; 981 final WindowToken token = win.mToken; 982 final DisplayContent displayContent = win.getDisplayContent(); 983 if (displayContent == null) { 984 // It doesn't matter this display is going away. 985 return 0; 986 } 987 988 final WindowList windows = win.getWindowList(); 989 final int N = windows.size(); 990 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent); 991 int tokenWindowsPos = 0; 992 int windowListPos = tokenWindowList.size(); 993 if (!tokenWindowList.isEmpty()) { 994 // If this application has existing windows, we 995 // simply place the new window on top of them... but 996 // keep the starting window on top. 997 if (win.mAttrs.type == TYPE_BASE_APPLICATION) { 998 // Base windows go behind everything else. 999 WindowState lowestWindow = tokenWindowList.get(0); 1000 placeWindowBefore(lowestWindow, win); 1001 tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows); 1002 } else { 1003 AppWindowToken atoken = win.mAppToken; 1004 WindowState lastWindow = tokenWindowList.get(windowListPos - 1); 1005 if (atoken != null && lastWindow == atoken.startingWindow) { 1006 placeWindowBefore(lastWindow, win); 1007 tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows); 1008 } else { 1009 int newIdx = findIdxBasedOnAppTokens(win); 1010 //there is a window above this one associated with the same 1011 //apptoken note that the window could be a floating window 1012 //that was created later or a window at the top of the list of 1013 //windows associated with this token. 1014 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, 1015 "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " + 1016 N); 1017 windows.add(newIdx + 1, win); 1018 if (newIdx < 0) { 1019 // No window from token found on win's display. 1020 tokenWindowsPos = 0; 1021 } else { 1022 tokenWindowsPos = indexOfWinInWindowList( 1023 windows.get(newIdx), token.windows) + 1; 1024 } 1025 mWindowsChanged = true; 1026 } 1027 } 1028 return tokenWindowsPos; 1029 } 1030 1031 // No windows from this token on this display 1032 if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder() 1033 + " (token=" + token + ")"); 1034 // Figure out where the window should go, based on the 1035 // order of applications. 1036 WindowState pos = null; 1037 1038 final ArrayList<Task> tasks = displayContent.getTasks(); 1039 int taskNdx; 1040 int tokenNdx = -1; 1041 for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 1042 AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 1043 for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 1044 final AppWindowToken t = tokens.get(tokenNdx); 1045 if (t == token) { 1046 --tokenNdx; 1047 if (tokenNdx < 0) { 1048 --taskNdx; 1049 if (taskNdx >= 0) { 1050 tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1; 1051 } 1052 } 1053 break; 1054 } 1055 1056 // We haven't reached the token yet; if this token 1057 // is not going to the bottom and has windows on this display, we can 1058 // use it as an anchor for when we do reach the token. 1059 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent); 1060 if (!t.sendingToBottom && tokenWindowList.size() > 0) { 1061 pos = tokenWindowList.get(0); 1062 } 1063 } 1064 if (tokenNdx >= 0) { 1065 // early exit 1066 break; 1067 } 1068 } 1069 1070 // We now know the index into the apps. If we found 1071 // an app window above, that gives us the position; else 1072 // we need to look some more. 1073 if (pos != null) { 1074 // Move behind any windows attached to this one. 1075 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder()); 1076 if (atoken != null) { 1077 tokenWindowList = 1078 getTokenWindowsOnDisplay(atoken, displayContent); 1079 final int NC = tokenWindowList.size(); 1080 if (NC > 0) { 1081 WindowState bottom = tokenWindowList.get(0); 1082 if (bottom.mSubLayer < 0) { 1083 pos = bottom; 1084 } 1085 } 1086 } 1087 placeWindowBefore(pos, win); 1088 return tokenWindowsPos; 1089 } 1090 1091 // Continue looking down until we find the first 1092 // token that has windows on this display. 1093 for ( ; taskNdx >= 0; --taskNdx) { 1094 AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 1095 for ( ; tokenNdx >= 0; --tokenNdx) { 1096 final AppWindowToken t = tokens.get(tokenNdx); 1097 tokenWindowList = getTokenWindowsOnDisplay(t, displayContent); 1098 final int NW = tokenWindowList.size(); 1099 if (NW > 0) { 1100 pos = tokenWindowList.get(NW-1); 1101 break; 1102 } 1103 } 1104 if (tokenNdx >= 0) { 1105 // found 1106 break; 1107 } 1108 } 1109 1110 if (pos != null) { 1111 // Move in front of any windows attached to this 1112 // one. 1113 WindowToken atoken = mTokenMap.get(pos.mClient.asBinder()); 1114 if (atoken != null) { 1115 final int NC = atoken.windows.size(); 1116 if (NC > 0) { 1117 WindowState top = atoken.windows.get(NC-1); 1118 if (top.mSubLayer >= 0) { 1119 pos = top; 1120 } 1121 } 1122 } 1123 placeWindowAfter(pos, win); 1124 return tokenWindowsPos; 1125 } 1126 1127 // Just search for the start of this layer. 1128 final int myLayer = win.mBaseLayer; 1129 int i; 1130 for (i = 0; i < N; i++) { 1131 WindowState w = windows.get(i); 1132 if (w.mBaseLayer > myLayer) { 1133 break; 1134 } 1135 } 1136 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, 1137 "Based on layer: Adding window " + win + " at " + i + " of " + N); 1138 windows.add(i, win); 1139 mWindowsChanged = true; 1140 return tokenWindowsPos; 1141 } 1142 1143 private void addFreeWindowToListLocked(final WindowState win) { 1144 final WindowList windows = win.getWindowList(); 1145 1146 // Figure out where window should go, based on layer. 1147 final int myLayer = win.mBaseLayer; 1148 int i; 1149 for (i = windows.size() - 1; i >= 0; i--) { 1150 if (windows.get(i).mBaseLayer <= myLayer) { 1151 break; 1152 } 1153 } 1154 i++; 1155 if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, 1156 "Free window: Adding window " + win + " at " + i + " of " + windows.size()); 1157 windows.add(i, win); 1158 mWindowsChanged = true; 1159 } 1160 1161 private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) { 1162 final WindowToken token = win.mToken; 1163 final DisplayContent displayContent = win.getDisplayContent(); 1164 if (displayContent == null) { 1165 return; 1166 } 1167 final WindowState attached = win.mAttachedWindow; 1168 1169 WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent); 1170 1171 // Figure out this window's ordering relative to the window 1172 // it is attached to. 1173 final int NA = tokenWindowList.size(); 1174 final int sublayer = win.mSubLayer; 1175 int largestSublayer = Integer.MIN_VALUE; 1176 WindowState windowWithLargestSublayer = null; 1177 int i; 1178 for (i = 0; i < NA; i++) { 1179 WindowState w = tokenWindowList.get(i); 1180 final int wSublayer = w.mSubLayer; 1181 if (wSublayer >= largestSublayer) { 1182 largestSublayer = wSublayer; 1183 windowWithLargestSublayer = w; 1184 } 1185 if (sublayer < 0) { 1186 // For negative sublayers, we go below all windows 1187 // in the same sublayer. 1188 if (wSublayer >= sublayer) { 1189 if (addToToken) { 1190 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token); 1191 token.windows.add(i, win); 1192 } 1193 placeWindowBefore(wSublayer >= 0 ? attached : w, win); 1194 break; 1195 } 1196 } else { 1197 // For positive sublayers, we go above all windows 1198 // in the same sublayer. 1199 if (wSublayer > sublayer) { 1200 if (addToToken) { 1201 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token); 1202 token.windows.add(i, win); 1203 } 1204 placeWindowBefore(w, win); 1205 break; 1206 } 1207 } 1208 } 1209 if (i >= NA) { 1210 if (addToToken) { 1211 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token); 1212 token.windows.add(win); 1213 } 1214 if (sublayer < 0) { 1215 placeWindowBefore(attached, win); 1216 } else { 1217 placeWindowAfter(largestSublayer >= 0 1218 ? windowWithLargestSublayer 1219 : attached, 1220 win); 1221 } 1222 } 1223 } 1224 1225 private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) { 1226 if (DEBUG_FOCUS_LIGHT) Slog.d(TAG, "addWindowToListInOrderLocked: win=" + win + 1227 " Callers=" + Debug.getCallers(4)); 1228 if (win.mAttachedWindow == null) { 1229 final WindowToken token = win.mToken; 1230 int tokenWindowsPos = 0; 1231 if (token.appWindowToken != null) { 1232 tokenWindowsPos = addAppWindowToListLocked(win); 1233 } else { 1234 addFreeWindowToListLocked(win); 1235 } 1236 if (addToToken) { 1237 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token); 1238 token.windows.add(tokenWindowsPos, win); 1239 } 1240 } else { 1241 addAttachedWindowToListLocked(win, addToToken); 1242 } 1243 1244 if (win.mAppToken != null && addToToken) { 1245 win.mAppToken.allAppWindows.add(win); 1246 } 1247 } 1248 1249 static boolean canBeImeTarget(WindowState w) { 1250 final int fl = w.mAttrs.flags 1251 & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM); 1252 if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) 1253 || w.mAttrs.type == TYPE_APPLICATION_STARTING) { 1254 if (DEBUG_INPUT_METHOD) { 1255 Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding()); 1256 if (!w.isVisibleOrAdding()) { 1257 Slog.i(TAG, " mSurface=" + w.mWinAnimator.mSurfaceControl 1258 + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility 1259 + " policyVis=" + w.mPolicyVisibility 1260 + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim 1261 + " attachHid=" + w.mAttachedHidden 1262 + " exiting=" + w.mExiting + " destroying=" + w.mDestroying); 1263 if (w.mAppToken != null) { 1264 Slog.i(TAG, " mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested); 1265 } 1266 } 1267 } 1268 return w.isVisibleOrAdding(); 1269 } 1270 return false; 1271 } 1272 1273 /** 1274 * Dig through the WindowStates and find the one that the Input Method will target. 1275 * @param willMove 1276 * @return The index+1 in mWindows of the discovered target. 1277 */ 1278 int findDesiredInputMethodWindowIndexLocked(boolean willMove) { 1279 // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the 1280 // same display. Or even when the current IME/target are not on the same screen as the next 1281 // IME/target. For now only look for input windows on the main screen. 1282 WindowList windows = getDefaultWindowListLocked(); 1283 WindowState w = null; 1284 int i; 1285 for (i = windows.size() - 1; i >= 0; --i) { 1286 WindowState win = windows.get(i); 1287 1288 if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i 1289 + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags)); 1290 if (canBeImeTarget(win)) { 1291 w = win; 1292 //Slog.i(TAG, "Putting input method here!"); 1293 1294 // Yet more tricksyness! If this window is a "starting" 1295 // window, we do actually want to be on top of it, but 1296 // it is not -really- where input will go. So if the caller 1297 // is not actually looking to move the IME, look down below 1298 // for a real window to target... 1299 if (!willMove 1300 && w.mAttrs.type == TYPE_APPLICATION_STARTING 1301 && i > 0) { 1302 WindowState wb = windows.get(i-1); 1303 if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) { 1304 i--; 1305 w = wb; 1306 } 1307 } 1308 break; 1309 } 1310 } 1311 1312 // Now w is either mWindows[0] or an IME (or null if mWindows is empty). 1313 1314 if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w); 1315 1316 // Now, a special case -- if the last target's window is in the 1317 // process of exiting, and is above the new target, keep on the 1318 // last target to avoid flicker. Consider for example a Dialog with 1319 // the IME shown: when the Dialog is dismissed, we want to keep 1320 // the IME above it until it is completely gone so it doesn't drop 1321 // behind the dialog or its full-screen scrim. 1322 final WindowState curTarget = mInputMethodTarget; 1323 if (curTarget != null 1324 && curTarget.isDisplayedLw() 1325 && curTarget.isClosing() 1326 && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) { 1327 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing"); 1328 return windows.indexOf(curTarget) + 1; 1329 } 1330 1331 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target=" 1332 + w + " willMove=" + willMove); 1333 1334 if (willMove && w != null) { 1335 AppWindowToken token = curTarget == null ? null : curTarget.mAppToken; 1336 if (token != null) { 1337 1338 // Now some fun for dealing with window animations that 1339 // modify the Z order. We need to look at all windows below 1340 // the current target that are in this app, finding the highest 1341 // visible one in layering. 1342 WindowState highestTarget = null; 1343 int highestPos = 0; 1344 if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) { 1345 WindowList curWindows = curTarget.getWindowList(); 1346 int pos = curWindows.indexOf(curTarget); 1347 while (pos >= 0) { 1348 WindowState win = curWindows.get(pos); 1349 if (win.mAppToken != token) { 1350 break; 1351 } 1352 if (!win.mRemoved) { 1353 if (highestTarget == null || win.mWinAnimator.mAnimLayer > 1354 highestTarget.mWinAnimator.mAnimLayer) { 1355 highestTarget = win; 1356 highestPos = pos; 1357 } 1358 } 1359 pos--; 1360 } 1361 } 1362 1363 if (highestTarget != null) { 1364 if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget 1365 + " animating=" + highestTarget.mWinAnimator.isAnimating() 1366 + " layer=" + highestTarget.mWinAnimator.mAnimLayer 1367 + " new layer=" + w.mWinAnimator.mAnimLayer); 1368 1369 if (mAppTransition.isTransitionSet()) { 1370 // If we are currently setting up for an animation, 1371 // hold everything until we can find out what will happen. 1372 mInputMethodTargetWaitingAnim = true; 1373 mInputMethodTarget = highestTarget; 1374 return highestPos + 1; 1375 } else if (highestTarget.mWinAnimator.isAnimating() && 1376 highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) { 1377 // If the window we are currently targeting is involved 1378 // with an animation, and it is on top of the next target 1379 // we will be over, then hold off on moving until 1380 // that is done. 1381 mInputMethodTargetWaitingAnim = true; 1382 mInputMethodTarget = highestTarget; 1383 return highestPos + 1; 1384 } 1385 } 1386 } 1387 } 1388 1389 //Slog.i(TAG, "Placing input method @" + (i+1)); 1390 if (w != null) { 1391 if (willMove) { 1392 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to " 1393 + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4))); 1394 mInputMethodTarget = w; 1395 mInputMethodTargetWaitingAnim = false; 1396 if (w.mAppToken != null) { 1397 setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment); 1398 } else { 1399 setInputMethodAnimLayerAdjustment(0); 1400 } 1401 } 1402 return i+1; 1403 } 1404 if (willMove) { 1405 if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null." 1406 + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4))); 1407 mInputMethodTarget = null; 1408 setInputMethodAnimLayerAdjustment(0); 1409 } 1410 return -1; 1411 } 1412 1413 void addInputMethodWindowToListLocked(WindowState win) { 1414 int pos = findDesiredInputMethodWindowIndexLocked(true); 1415 if (pos >= 0) { 1416 win.mTargetAppToken = mInputMethodTarget.mAppToken; 1417 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v( 1418 TAG, "Adding input method window " + win + " at " + pos); 1419 // TODO(multidisplay): IMEs are only supported on the default display. 1420 getDefaultWindowListLocked().add(pos, win); 1421 mWindowsChanged = true; 1422 moveInputMethodDialogsLocked(pos+1); 1423 return; 1424 } 1425 win.mTargetAppToken = null; 1426 addWindowToListInOrderLocked(win, true); 1427 moveInputMethodDialogsLocked(pos); 1428 } 1429 1430 void setInputMethodAnimLayerAdjustment(int adj) { 1431 if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj); 1432 mInputMethodAnimLayerAdjustment = adj; 1433 WindowState imw = mInputMethodWindow; 1434 if (imw != null) { 1435 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj; 1436 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw 1437 + " anim layer: " + imw.mWinAnimator.mAnimLayer); 1438 int wi = imw.mChildWindows.size(); 1439 while (wi > 0) { 1440 wi--; 1441 WindowState cw = imw.mChildWindows.get(wi); 1442 cw.mWinAnimator.mAnimLayer = cw.mLayer + adj; 1443 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw 1444 + " anim layer: " + cw.mWinAnimator.mAnimLayer); 1445 } 1446 } 1447 int di = mInputMethodDialogs.size(); 1448 while (di > 0) { 1449 di --; 1450 imw = mInputMethodDialogs.get(di); 1451 imw.mWinAnimator.mAnimLayer = imw.mLayer + adj; 1452 if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw 1453 + " anim layer: " + imw.mWinAnimator.mAnimLayer); 1454 } 1455 } 1456 1457 private int tmpRemoveWindowLocked(int interestingPos, WindowState win) { 1458 WindowList windows = win.getWindowList(); 1459 int wpos = windows.indexOf(win); 1460 if (wpos >= 0) { 1461 if (wpos < interestingPos) interestingPos--; 1462 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win); 1463 windows.remove(wpos); 1464 mWindowsChanged = true; 1465 int NC = win.mChildWindows.size(); 1466 while (NC > 0) { 1467 NC--; 1468 WindowState cw = win.mChildWindows.get(NC); 1469 int cpos = windows.indexOf(cw); 1470 if (cpos >= 0) { 1471 if (cpos < interestingPos) interestingPos--; 1472 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at " 1473 + cpos + ": " + cw); 1474 windows.remove(cpos); 1475 } 1476 } 1477 } 1478 return interestingPos; 1479 } 1480 1481 private void reAddWindowToListInOrderLocked(WindowState win) { 1482 addWindowToListInOrderLocked(win, false); 1483 // This is a hack to get all of the child windows added as well 1484 // at the right position. Child windows should be rare and 1485 // this case should be rare, so it shouldn't be that big a deal. 1486 WindowList windows = win.getWindowList(); 1487 int wpos = windows.indexOf(win); 1488 if (wpos >= 0) { 1489 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win); 1490 windows.remove(wpos); 1491 mWindowsChanged = true; 1492 reAddWindowLocked(wpos, win); 1493 } 1494 } 1495 1496 void logWindowList(final WindowList windows, String prefix) { 1497 int N = windows.size(); 1498 while (N > 0) { 1499 N--; 1500 Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N)); 1501 } 1502 } 1503 1504 void moveInputMethodDialogsLocked(int pos) { 1505 ArrayList<WindowState> dialogs = mInputMethodDialogs; 1506 1507 // TODO(multidisplay): IMEs are only supported on the default display. 1508 WindowList windows = getDefaultWindowListLocked(); 1509 final int N = dialogs.size(); 1510 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos); 1511 for (int i=0; i<N; i++) { 1512 pos = tmpRemoveWindowLocked(pos, dialogs.get(i)); 1513 } 1514 if (DEBUG_INPUT_METHOD) { 1515 Slog.v(TAG, "Window list w/pos=" + pos); 1516 logWindowList(windows, " "); 1517 } 1518 1519 if (pos >= 0) { 1520 final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken; 1521 // Skip windows owned by the input method. 1522 if (mInputMethodWindow != null) { 1523 while (pos < windows.size()) { 1524 WindowState wp = windows.get(pos); 1525 if (wp == mInputMethodWindow || wp.mAttachedWindow == mInputMethodWindow) { 1526 pos++; 1527 continue; 1528 } 1529 break; 1530 } 1531 } 1532 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos); 1533 for (int i=0; i<N; i++) { 1534 WindowState win = dialogs.get(i); 1535 win.mTargetAppToken = targetAppToken; 1536 pos = reAddWindowLocked(pos, win); 1537 } 1538 if (DEBUG_INPUT_METHOD) { 1539 Slog.v(TAG, "Final window list:"); 1540 logWindowList(windows, " "); 1541 } 1542 return; 1543 } 1544 for (int i=0; i<N; i++) { 1545 WindowState win = dialogs.get(i); 1546 win.mTargetAppToken = null; 1547 reAddWindowToListInOrderLocked(win); 1548 if (DEBUG_INPUT_METHOD) { 1549 Slog.v(TAG, "No IM target, final list:"); 1550 logWindowList(windows, " "); 1551 } 1552 } 1553 } 1554 1555 boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) { 1556 final WindowState imWin = mInputMethodWindow; 1557 final int DN = mInputMethodDialogs.size(); 1558 if (imWin == null && DN == 0) { 1559 return false; 1560 } 1561 1562 // TODO(multidisplay): IMEs are only supported on the default display. 1563 WindowList windows = getDefaultWindowListLocked(); 1564 1565 int imPos = findDesiredInputMethodWindowIndexLocked(true); 1566 if (imPos >= 0) { 1567 // In this case, the input method windows are to be placed 1568 // immediately above the window they are targeting. 1569 1570 // First check to see if the input method windows are already 1571 // located here, and contiguous. 1572 final int N = windows.size(); 1573 WindowState firstImWin = imPos < N 1574 ? windows.get(imPos) : null; 1575 1576 // Figure out the actual input method window that should be 1577 // at the bottom of their stack. 1578 WindowState baseImWin = imWin != null 1579 ? imWin : mInputMethodDialogs.get(0); 1580 if (baseImWin.mChildWindows.size() > 0) { 1581 WindowState cw = baseImWin.mChildWindows.get(0); 1582 if (cw.mSubLayer < 0) baseImWin = cw; 1583 } 1584 1585 if (firstImWin == baseImWin) { 1586 // The windows haven't moved... but are they still contiguous? 1587 // First find the top IM window. 1588 int pos = imPos+1; 1589 while (pos < N) { 1590 if (!(windows.get(pos)).mIsImWindow) { 1591 break; 1592 } 1593 pos++; 1594 } 1595 pos++; 1596 // Now there should be no more input method windows above. 1597 while (pos < N) { 1598 if ((windows.get(pos)).mIsImWindow) { 1599 break; 1600 } 1601 pos++; 1602 } 1603 if (pos >= N) { 1604 // Z order is good. 1605 // The IM target window may be changed, so update the mTargetAppToken. 1606 if (imWin != null) { 1607 imWin.mTargetAppToken = mInputMethodTarget.mAppToken; 1608 } 1609 return false; 1610 } 1611 } 1612 1613 if (imWin != null) { 1614 if (DEBUG_INPUT_METHOD) { 1615 Slog.v(TAG, "Moving IM from " + imPos); 1616 logWindowList(windows, " "); 1617 } 1618 imPos = tmpRemoveWindowLocked(imPos, imWin); 1619 if (DEBUG_INPUT_METHOD) { 1620 Slog.v(TAG, "List after removing with new pos " + imPos + ":"); 1621 logWindowList(windows, " "); 1622 } 1623 imWin.mTargetAppToken = mInputMethodTarget.mAppToken; 1624 reAddWindowLocked(imPos, imWin); 1625 if (DEBUG_INPUT_METHOD) { 1626 Slog.v(TAG, "List after moving IM to " + imPos + ":"); 1627 logWindowList(windows, " "); 1628 } 1629 if (DN > 0) moveInputMethodDialogsLocked(imPos+1); 1630 } else { 1631 moveInputMethodDialogsLocked(imPos); 1632 } 1633 1634 } else { 1635 // In this case, the input method windows go in a fixed layer, 1636 // because they aren't currently associated with a focus window. 1637 1638 if (imWin != null) { 1639 if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos); 1640 tmpRemoveWindowLocked(0, imWin); 1641 imWin.mTargetAppToken = null; 1642 reAddWindowToListInOrderLocked(imWin); 1643 if (DEBUG_INPUT_METHOD) { 1644 Slog.v(TAG, "List with no IM target:"); 1645 logWindowList(windows, " "); 1646 } 1647 if (DN > 0) moveInputMethodDialogsLocked(-1); 1648 } else { 1649 moveInputMethodDialogsLocked(-1); 1650 } 1651 1652 } 1653 1654 if (needAssignLayers) { 1655 assignLayersLocked(windows); 1656 } 1657 1658 return true; 1659 } 1660 1661 final boolean isWallpaperVisible(WindowState wallpaperTarget) { 1662 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured=" 1663 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??") 1664 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null) 1665 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null) 1666 + " upper=" + mUpperWallpaperTarget 1667 + " lower=" + mLowerWallpaperTarget); 1668 return (wallpaperTarget != null 1669 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null 1670 && wallpaperTarget.mAppToken.mAppAnimator.animation != null))) 1671 || mUpperWallpaperTarget != null 1672 || mLowerWallpaperTarget != null; 1673 } 1674 1675 static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1; 1676 static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2; 1677 1678 int adjustWallpaperWindowsLocked() { 1679 mInnerFields.mWallpaperMayChange = false; 1680 boolean targetChanged = false; 1681 1682 // TODO(multidisplay): Wallpapers on main screen only. 1683 final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo(); 1684 final int dw = displayInfo.logicalWidth; 1685 final int dh = displayInfo.logicalHeight; 1686 1687 // First find top-most window that has asked to be on top of the 1688 // wallpaper; all wallpapers go behind it. 1689 final WindowList windows = getDefaultWindowListLocked(); 1690 int N = windows.size(); 1691 WindowState w = null; 1692 WindowState foundW = null; 1693 int foundI = 0; 1694 WindowState topCurW = null; 1695 int topCurI = 0; 1696 int windowDetachedI = -1; 1697 int i = N; 1698 while (i > 0) { 1699 i--; 1700 w = windows.get(i); 1701 if ((w.mAttrs.type == TYPE_WALLPAPER)) { 1702 if (topCurW == null) { 1703 topCurW = w; 1704 topCurI = i; 1705 } 1706 continue; 1707 } 1708 topCurW = null; 1709 if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) { 1710 // If this window's app token is hidden and not animating, 1711 // it is of no interest to us. 1712 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) { 1713 if (DEBUG_WALLPAPER) Slog.v(TAG, 1714 "Skipping hidden and not animating token: " + w); 1715 continue; 1716 } 1717 } 1718 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen=" 1719 + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState); 1720 1721 // If the app is executing an animation because the keyguard is going away, keep the 1722 // wallpaper during the animation so it doesn't flicker out. 1723 final boolean hasWallpaper = (w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 1724 || (w.mAppToken != null 1725 && w.mWinAnimator.keyguardGoingAwayAnimation); 1726 if (hasWallpaper && w.isOnScreen() 1727 && (mWallpaperTarget == w || w.isDrawFinishedLw())) { 1728 if (DEBUG_WALLPAPER) Slog.v(TAG, 1729 "Found wallpaper target: #" + i + "=" + w); 1730 foundW = w; 1731 foundI = i; 1732 if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) { 1733 // The current wallpaper target is animating, so we'll 1734 // look behind it for another possible target and figure 1735 // out what is going on below. 1736 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w 1737 + ": token animating, looking behind."); 1738 continue; 1739 } 1740 break; 1741 } else if (w == mAnimator.mWindowDetachedWallpaper) { 1742 windowDetachedI = i; 1743 } 1744 } 1745 1746 if (foundW == null && windowDetachedI >= 0) { 1747 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, 1748 "Found animating detached wallpaper activity: #" + i + "=" + w); 1749 foundW = w; 1750 foundI = windowDetachedI; 1751 } 1752 1753 if (mWallpaperTarget != foundW 1754 && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) { 1755 if (DEBUG_WALLPAPER_LIGHT) { 1756 Slog.v(TAG, "New wallpaper target: " + foundW 1757 + " oldTarget: " + mWallpaperTarget); 1758 } 1759 1760 mLowerWallpaperTarget = null; 1761 mUpperWallpaperTarget = null; 1762 1763 WindowState oldW = mWallpaperTarget; 1764 mWallpaperTarget = foundW; 1765 targetChanged = true; 1766 1767 // Now what is happening... if the current and new targets are 1768 // animating, then we are in our super special mode! 1769 if (foundW != null && oldW != null) { 1770 boolean oldAnim = oldW.isAnimatingLw(); 1771 boolean foundAnim = foundW.isAnimatingLw(); 1772 if (DEBUG_WALLPAPER_LIGHT) { 1773 Slog.v(TAG, "New animation: " + foundAnim 1774 + " old animation: " + oldAnim); 1775 } 1776 if (foundAnim && oldAnim) { 1777 int oldI = windows.indexOf(oldW); 1778 if (DEBUG_WALLPAPER_LIGHT) { 1779 Slog.v(TAG, "New i: " + foundI + " old i: " + oldI); 1780 } 1781 if (oldI >= 0) { 1782 if (DEBUG_WALLPAPER_LIGHT) { 1783 Slog.v(TAG, "Animating wallpapers: old#" + oldI 1784 + "=" + oldW + "; new#" + foundI 1785 + "=" + foundW); 1786 } 1787 1788 // Set the new target correctly. 1789 if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) { 1790 if (DEBUG_WALLPAPER_LIGHT) { 1791 Slog.v(TAG, "Old wallpaper still the target."); 1792 } 1793 mWallpaperTarget = oldW; 1794 foundW = oldW; 1795 foundI = oldI; 1796 } 1797 // Now set the upper and lower wallpaper targets 1798 // correctly, and make sure that we are positioning 1799 // the wallpaper below the lower. 1800 else if (foundI > oldI) { 1801 // The new target is on top of the old one. 1802 if (DEBUG_WALLPAPER_LIGHT) { 1803 Slog.v(TAG, "Found target above old target."); 1804 } 1805 mUpperWallpaperTarget = foundW; 1806 mLowerWallpaperTarget = oldW; 1807 foundW = oldW; 1808 foundI = oldI; 1809 } else { 1810 // The new target is below the old one. 1811 if (DEBUG_WALLPAPER_LIGHT) { 1812 Slog.v(TAG, "Found target below old target."); 1813 } 1814 mUpperWallpaperTarget = oldW; 1815 mLowerWallpaperTarget = foundW; 1816 } 1817 } 1818 } 1819 } 1820 1821 } else if (mLowerWallpaperTarget != null) { 1822 // Is it time to stop animating? 1823 if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) { 1824 if (DEBUG_WALLPAPER_LIGHT) { 1825 Slog.v(TAG, "No longer animating wallpaper targets!"); 1826 } 1827 mLowerWallpaperTarget = null; 1828 mUpperWallpaperTarget = null; 1829 mWallpaperTarget = foundW; 1830 targetChanged = true; 1831 } 1832 } 1833 1834 boolean visible = foundW != null; 1835 if (visible) { 1836 // The window is visible to the compositor... but is it visible 1837 // to the user? That is what the wallpaper cares about. 1838 visible = isWallpaperVisible(foundW); 1839 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible); 1840 1841 // If the wallpaper target is animating, we may need to copy 1842 // its layer adjustment. Only do this if we are not transfering 1843 // between two wallpaper targets. 1844 mWallpaperAnimLayerAdjustment = 1845 (mLowerWallpaperTarget == null && foundW.mAppToken != null) 1846 ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0; 1847 1848 final int maxLayer = mPolicy.getMaxWallpaperLayer() 1849 * TYPE_LAYER_MULTIPLIER 1850 + TYPE_LAYER_OFFSET; 1851 1852 // Now w is the window we are supposed to be behind... but we 1853 // need to be sure to also be behind any of its attached windows, 1854 // AND any starting window associated with it, AND below the 1855 // maximum layer the policy allows for wallpapers. 1856 while (foundI > 0) { 1857 WindowState wb = windows.get(foundI-1); 1858 if (wb.mBaseLayer < maxLayer && 1859 wb.mAttachedWindow != foundW && 1860 (foundW.mAttachedWindow == null || 1861 wb.mAttachedWindow != foundW.mAttachedWindow) && 1862 (wb.mAttrs.type != TYPE_APPLICATION_STARTING || 1863 foundW.mToken == null || wb.mToken != foundW.mToken)) { 1864 // This window is not related to the previous one in any 1865 // interesting way, so stop here. 1866 break; 1867 } 1868 foundW = wb; 1869 foundI--; 1870 } 1871 } else { 1872 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target"); 1873 } 1874 1875 if (foundW == null && topCurW != null) { 1876 // There is no wallpaper target, so it goes at the bottom. 1877 // We will assume it is the same place as last time, if known. 1878 foundW = topCurW; 1879 foundI = topCurI+1; 1880 } else { 1881 // Okay i is the position immediately above the wallpaper. Look at 1882 // what is below it for later. 1883 foundW = foundI > 0 ? windows.get(foundI-1) : null; 1884 } 1885 1886 if (visible) { 1887 if (mWallpaperTarget.mWallpaperX >= 0) { 1888 mLastWallpaperX = mWallpaperTarget.mWallpaperX; 1889 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep; 1890 } 1891 if (mWallpaperTarget.mWallpaperY >= 0) { 1892 mLastWallpaperY = mWallpaperTarget.mWallpaperY; 1893 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep; 1894 } 1895 } 1896 1897 // Start stepping backwards from here, ensuring that our wallpaper windows 1898 // are correctly placed. 1899 int changed = 0; 1900 int curTokenIndex = mWallpaperTokens.size(); 1901 while (curTokenIndex > 0) { 1902 curTokenIndex--; 1903 WindowToken token = mWallpaperTokens.get(curTokenIndex); 1904 if (token.hidden == visible) { 1905 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, 1906 "Wallpaper token " + token + " hidden=" + !visible); 1907 changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED; 1908 token.hidden = !visible; 1909 // Need to do a layout to ensure the wallpaper now has the 1910 // correct size. 1911 getDefaultDisplayContentLocked().layoutNeeded = true; 1912 } 1913 1914 int curWallpaperIndex = token.windows.size(); 1915 while (curWallpaperIndex > 0) { 1916 curWallpaperIndex--; 1917 WindowState wallpaper = token.windows.get(curWallpaperIndex); 1918 1919 if (visible) { 1920 updateWallpaperOffsetLocked(wallpaper, dw, dh, false); 1921 } 1922 1923 // First, make sure the client has the current visibility 1924 // state. 1925 dispatchWallpaperVisibility(wallpaper, visible); 1926 1927 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment; 1928 if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win " 1929 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer); 1930 1931 // First, if this window is at the current index, then all 1932 // is well. 1933 if (wallpaper == foundW) { 1934 foundI--; 1935 foundW = foundI > 0 1936 ? windows.get(foundI-1) : null; 1937 continue; 1938 } 1939 1940 // The window didn't match... the current wallpaper window, 1941 // wherever it is, is in the wrong place, so make sure it is 1942 // not in the list. 1943 int oldIndex = windows.indexOf(wallpaper); 1944 if (oldIndex >= 0) { 1945 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at " 1946 + oldIndex + ": " + wallpaper); 1947 windows.remove(oldIndex); 1948 mWindowsChanged = true; 1949 if (oldIndex < foundI) { 1950 foundI--; 1951 } 1952 } 1953 1954 // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost 1955 // layer. For keyguard over wallpaper put the wallpaper under the keyguard. 1956 int insertionIndex = 0; 1957 if (visible && foundW != null) { 1958 final int type = foundW.mAttrs.type; 1959 final int privateFlags = foundW.mAttrs.privateFlags; 1960 if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 1961 || type == TYPE_KEYGUARD_SCRIM) { 1962 insertionIndex = windows.indexOf(foundW); 1963 } 1964 } 1965 if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) { 1966 Slog.v(TAG, "Moving wallpaper " + wallpaper 1967 + " from " + oldIndex + " to " + insertionIndex); 1968 } 1969 1970 windows.add(insertionIndex, wallpaper); 1971 mWindowsChanged = true; 1972 changed |= ADJUST_WALLPAPER_LAYERS_CHANGED; 1973 } 1974 } 1975 1976 /* 1977 final TaskStack targetStack = 1978 mWallpaperTarget == null ? null : mWallpaperTarget.getStack(); 1979 if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 && 1980 targetStack != null && !targetStack.isHomeStack()) { 1981 // If the wallpaper target is not on the home stack then make sure that all windows 1982 // from other non-home stacks are above the wallpaper. 1983 for (i = foundI - 1; i >= 0; --i) { 1984 WindowState win = windows.get(i); 1985 if (!win.isVisibleLw()) { 1986 continue; 1987 } 1988 final TaskStack winStack = win.getStack(); 1989 if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) { 1990 windows.remove(i); 1991 windows.add(foundI + 1, win); 1992 } 1993 } 1994 } 1995 */ 1996 1997 if (targetChanged && DEBUG_WALLPAPER_LIGHT) { 1998 Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget 1999 + " lower=" + mLowerWallpaperTarget + " upper=" 2000 + mUpperWallpaperTarget); 2001 } 2002 2003 return changed; 2004 } 2005 2006 void setWallpaperAnimLayerAdjustmentLocked(int adj) { 2007 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, 2008 "Setting wallpaper layer adj to " + adj); 2009 mWallpaperAnimLayerAdjustment = adj; 2010 int curTokenIndex = mWallpaperTokens.size(); 2011 while (curTokenIndex > 0) { 2012 curTokenIndex--; 2013 WindowToken token = mWallpaperTokens.get(curTokenIndex); 2014 int curWallpaperIndex = token.windows.size(); 2015 while (curWallpaperIndex > 0) { 2016 curWallpaperIndex--; 2017 WindowState wallpaper = token.windows.get(curWallpaperIndex); 2018 wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj; 2019 if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win " 2020 + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer); 2021 } 2022 } 2023 } 2024 2025 boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh, 2026 boolean sync) { 2027 boolean changed = false; 2028 boolean rawChanged = false; 2029 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f; 2030 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f; 2031 int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw; 2032 int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0; 2033 changed = wallpaperWin.mXOffset != offset; 2034 if (changed) { 2035 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " 2036 + wallpaperWin + " x: " + offset); 2037 wallpaperWin.mXOffset = offset; 2038 } 2039 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) { 2040 wallpaperWin.mWallpaperX = wpx; 2041 wallpaperWin.mWallpaperXStep = wpxs; 2042 rawChanged = true; 2043 } 2044 2045 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f; 2046 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f; 2047 int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh; 2048 offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0; 2049 if (wallpaperWin.mYOffset != offset) { 2050 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " 2051 + wallpaperWin + " y: " + offset); 2052 changed = true; 2053 wallpaperWin.mYOffset = offset; 2054 } 2055 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) { 2056 wallpaperWin.mWallpaperY = wpy; 2057 wallpaperWin.mWallpaperYStep = wpys; 2058 rawChanged = true; 2059 } 2060 2061 if (rawChanged && (wallpaperWin.mAttrs.privateFlags & 2062 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) { 2063 try { 2064 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset " 2065 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX 2066 + " y=" + wallpaperWin.mWallpaperY); 2067 if (sync) { 2068 mWaitingOnWallpaper = wallpaperWin; 2069 } 2070 wallpaperWin.mClient.dispatchWallpaperOffsets( 2071 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY, 2072 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync); 2073 if (sync) { 2074 if (mWaitingOnWallpaper != null) { 2075 long start = SystemClock.uptimeMillis(); 2076 if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY) 2077 < start) { 2078 try { 2079 if (DEBUG_WALLPAPER) Slog.v(TAG, 2080 "Waiting for offset complete..."); 2081 mWindowMap.wait(WALLPAPER_TIMEOUT); 2082 } catch (InterruptedException e) { 2083 } 2084 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!"); 2085 if ((start+WALLPAPER_TIMEOUT) 2086 < SystemClock.uptimeMillis()) { 2087 Slog.i(TAG, "Timeout waiting for wallpaper to offset: " 2088 + wallpaperWin); 2089 mLastWallpaperTimeoutTime = start; 2090 } 2091 } 2092 mWaitingOnWallpaper = null; 2093 } 2094 } 2095 } catch (RemoteException e) { 2096 } 2097 } 2098 2099 return changed; 2100 } 2101 2102 void wallpaperOffsetsComplete(IBinder window) { 2103 synchronized (mWindowMap) { 2104 if (mWaitingOnWallpaper != null && 2105 mWaitingOnWallpaper.mClient.asBinder() == window) { 2106 mWaitingOnWallpaper = null; 2107 mWindowMap.notifyAll(); 2108 } 2109 } 2110 } 2111 2112 void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { 2113 final DisplayContent displayContent = changingTarget.getDisplayContent(); 2114 if (displayContent == null) { 2115 return; 2116 } 2117 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 2118 final int dw = displayInfo.logicalWidth; 2119 final int dh = displayInfo.logicalHeight; 2120 2121 WindowState target = mWallpaperTarget; 2122 if (target != null) { 2123 if (target.mWallpaperX >= 0) { 2124 mLastWallpaperX = target.mWallpaperX; 2125 } else if (changingTarget.mWallpaperX >= 0) { 2126 mLastWallpaperX = changingTarget.mWallpaperX; 2127 } 2128 if (target.mWallpaperY >= 0) { 2129 mLastWallpaperY = target.mWallpaperY; 2130 } else if (changingTarget.mWallpaperY >= 0) { 2131 mLastWallpaperY = changingTarget.mWallpaperY; 2132 } 2133 } 2134 2135 int curTokenIndex = mWallpaperTokens.size(); 2136 while (curTokenIndex > 0) { 2137 curTokenIndex--; 2138 WindowToken token = mWallpaperTokens.get(curTokenIndex); 2139 int curWallpaperIndex = token.windows.size(); 2140 while (curWallpaperIndex > 0) { 2141 curWallpaperIndex--; 2142 WindowState wallpaper = token.windows.get(curWallpaperIndex); 2143 if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) { 2144 WindowStateAnimator winAnimator = wallpaper.mWinAnimator; 2145 winAnimator.computeShownFrameLocked(); 2146 // No need to lay out the windows - we can just set the wallpaper position 2147 // directly. 2148 winAnimator.setWallpaperOffset(wallpaper.mShownFrame); 2149 // We only want to be synchronous with one wallpaper. 2150 sync = false; 2151 } 2152 } 2153 } 2154 } 2155 2156 /** 2157 * Check wallpaper for visiblity change and notify window if so. 2158 * @param wallpaper The wallpaper to test and notify. 2159 * @param visible Current visibility. 2160 */ 2161 void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) { 2162 if (wallpaper.mWallpaperVisible != visible) { 2163 wallpaper.mWallpaperVisible = visible; 2164 try { 2165 if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, 2166 "Updating vis of wallpaper " + wallpaper 2167 + ": " + visible + " from:\n" + Debug.getCallers(4, " ")); 2168 wallpaper.mClient.dispatchAppVisibility(visible); 2169 } catch (RemoteException e) { 2170 } 2171 } 2172 } 2173 2174 void updateWallpaperVisibilityLocked() { 2175 final boolean visible = isWallpaperVisible(mWallpaperTarget); 2176 final DisplayContent displayContent = mWallpaperTarget.getDisplayContent(); 2177 if (displayContent == null) { 2178 return; 2179 } 2180 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 2181 final int dw = displayInfo.logicalWidth; 2182 final int dh = displayInfo.logicalHeight; 2183 2184 int curTokenIndex = mWallpaperTokens.size(); 2185 while (curTokenIndex > 0) { 2186 curTokenIndex--; 2187 WindowToken token = mWallpaperTokens.get(curTokenIndex); 2188 if (token.hidden == visible) { 2189 token.hidden = !visible; 2190 // Need to do a layout to ensure the wallpaper now has the 2191 // correct size. 2192 getDefaultDisplayContentLocked().layoutNeeded = true; 2193 } 2194 2195 int curWallpaperIndex = token.windows.size(); 2196 while (curWallpaperIndex > 0) { 2197 curWallpaperIndex--; 2198 WindowState wallpaper = token.windows.get(curWallpaperIndex); 2199 if (visible) { 2200 updateWallpaperOffsetLocked(wallpaper, dw, dh, false); 2201 } 2202 2203 dispatchWallpaperVisibility(wallpaper, visible); 2204 } 2205 } 2206 } 2207 2208 public int addWindow(Session session, IWindow client, int seq, 2209 WindowManager.LayoutParams attrs, int viewVisibility, int displayId, 2210 Rect outContentInsets, InputChannel outInputChannel) { 2211 int[] appOp = new int[1]; 2212 int res = mPolicy.checkAddPermission(attrs, appOp); 2213 if (res != WindowManagerGlobal.ADD_OKAY) { 2214 return res; 2215 } 2216 2217 boolean reportNewConfig = false; 2218 WindowState attachedWindow = null; 2219 WindowState win = null; 2220 long origId; 2221 final int type = attrs.type; 2222 2223 synchronized(mWindowMap) { 2224 if (!mDisplayReady) { 2225 throw new IllegalStateException("Display has not been initialialized"); 2226 } 2227 2228 final DisplayContent displayContent = getDisplayContentLocked(displayId); 2229 if (displayContent == null) { 2230 Slog.w(TAG, "Attempted to add window to a display that does not exist: " 2231 + displayId + ". Aborting."); 2232 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 2233 } 2234 if (!displayContent.hasAccess(session.mUid)) { 2235 Slog.w(TAG, "Attempted to add window to a display for which the application " 2236 + "does not have access: " + displayId + ". Aborting."); 2237 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 2238 } 2239 2240 if (mWindowMap.containsKey(client.asBinder())) { 2241 Slog.w(TAG, "Window " + client + " is already added"); 2242 return WindowManagerGlobal.ADD_DUPLICATE_ADD; 2243 } 2244 2245 if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) { 2246 attachedWindow = windowForClientLocked(null, attrs.token, false); 2247 if (attachedWindow == null) { 2248 Slog.w(TAG, "Attempted to add window with token that is not a window: " 2249 + attrs.token + ". Aborting."); 2250 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; 2251 } 2252 if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW 2253 && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) { 2254 Slog.w(TAG, "Attempted to add window with token that is a sub-window: " 2255 + attrs.token + ". Aborting."); 2256 return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN; 2257 } 2258 } 2259 2260 if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) { 2261 Slog.w(TAG, "Attempted to add private presentation window to a non-private display. Aborting."); 2262 return WindowManagerGlobal.ADD_PERMISSION_DENIED; 2263 } 2264 2265 boolean addToken = false; 2266 WindowToken token = mTokenMap.get(attrs.token); 2267 if (token == null) { 2268 if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { 2269 Slog.w(TAG, "Attempted to add application window with unknown token " 2270 + attrs.token + ". Aborting."); 2271 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2272 } 2273 if (type == TYPE_INPUT_METHOD) { 2274 Slog.w(TAG, "Attempted to add input method window with unknown token " 2275 + attrs.token + ". Aborting."); 2276 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2277 } 2278 if (type == TYPE_VOICE_INTERACTION) { 2279 Slog.w(TAG, "Attempted to add voice interaction window with unknown token " 2280 + attrs.token + ". Aborting."); 2281 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2282 } 2283 if (type == TYPE_WALLPAPER) { 2284 Slog.w(TAG, "Attempted to add wallpaper window with unknown token " 2285 + attrs.token + ". Aborting."); 2286 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2287 } 2288 if (type == TYPE_DREAM) { 2289 Slog.w(TAG, "Attempted to add Dream window with unknown token " 2290 + attrs.token + ". Aborting."); 2291 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2292 } 2293 token = new WindowToken(this, attrs.token, -1, false); 2294 addToken = true; 2295 } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { 2296 AppWindowToken atoken = token.appWindowToken; 2297 if (atoken == null) { 2298 Slog.w(TAG, "Attempted to add window with non-application token " 2299 + token + ". Aborting."); 2300 return WindowManagerGlobal.ADD_NOT_APP_TOKEN; 2301 } else if (atoken.removed) { 2302 Slog.w(TAG, "Attempted to add window with exiting application token " 2303 + token + ". Aborting."); 2304 return WindowManagerGlobal.ADD_APP_EXITING; 2305 } 2306 if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) { 2307 // No need for this guy! 2308 if (localLOGV) Slog.v( 2309 TAG, "**** NO NEED TO START: " + attrs.getTitle()); 2310 return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED; 2311 } 2312 } else if (type == TYPE_INPUT_METHOD) { 2313 if (token.windowType != TYPE_INPUT_METHOD) { 2314 Slog.w(TAG, "Attempted to add input method window with bad token " 2315 + attrs.token + ". Aborting."); 2316 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2317 } 2318 } else if (type == TYPE_VOICE_INTERACTION) { 2319 if (token.windowType != TYPE_VOICE_INTERACTION) { 2320 Slog.w(TAG, "Attempted to add voice interaction window with bad token " 2321 + attrs.token + ". Aborting."); 2322 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2323 } 2324 } else if (type == TYPE_WALLPAPER) { 2325 if (token.windowType != TYPE_WALLPAPER) { 2326 Slog.w(TAG, "Attempted to add wallpaper window with bad token " 2327 + attrs.token + ". Aborting."); 2328 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2329 } 2330 } else if (type == TYPE_DREAM) { 2331 if (token.windowType != TYPE_DREAM) { 2332 Slog.w(TAG, "Attempted to add Dream window with bad token " 2333 + attrs.token + ". Aborting."); 2334 return WindowManagerGlobal.ADD_BAD_APP_TOKEN; 2335 } 2336 } else if (token.appWindowToken != null) { 2337 Slog.w(TAG, "Non-null appWindowToken for system window of type=" + type); 2338 // It is not valid to use an app token with other system types; we will 2339 // instead make a new token for it (as if null had been passed in for the token). 2340 attrs.token = null; 2341 token = new WindowToken(this, null, -1, false); 2342 addToken = true; 2343 } 2344 2345 win = new WindowState(this, session, client, token, 2346 attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent); 2347 if (win.mDeathRecipient == null) { 2348 // Client has apparently died, so there is no reason to 2349 // continue. 2350 Slog.w(TAG, "Adding window client " + client.asBinder() 2351 + " that is dead, aborting."); 2352 return WindowManagerGlobal.ADD_APP_EXITING; 2353 } 2354 2355 if (win.getDisplayContent() == null) { 2356 Slog.w(TAG, "Adding window to Display that has been removed."); 2357 return WindowManagerGlobal.ADD_INVALID_DISPLAY; 2358 } 2359 2360 mPolicy.adjustWindowParamsLw(win.mAttrs); 2361 win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs)); 2362 2363 res = mPolicy.prepareAddWindowLw(win, attrs); 2364 if (res != WindowManagerGlobal.ADD_OKAY) { 2365 return res; 2366 } 2367 2368 if (outInputChannel != null && (attrs.inputFeatures 2369 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { 2370 String name = win.makeInputChannelName(); 2371 InputChannel[] inputChannels = InputChannel.openInputChannelPair(name); 2372 win.setInputChannel(inputChannels[0]); 2373 inputChannels[1].transferTo(outInputChannel); 2374 2375 mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle); 2376 } 2377 2378 // From now on, no exceptions or errors allowed! 2379 2380 res = WindowManagerGlobal.ADD_OKAY; 2381 2382 origId = Binder.clearCallingIdentity(); 2383 2384 if (addToken) { 2385 Slog.w("BadTokenDebug", "addWindow: Adding token=" + token + " attrs.token=" + attrs.token); 2386 mTokenMap.put(attrs.token, token); 2387 } 2388 win.attach(); 2389 mWindowMap.put(client.asBinder(), win); 2390 if (win.mAppOp != AppOpsManager.OP_NONE) { 2391 if (mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage()) 2392 != AppOpsManager.MODE_ALLOWED) { 2393 win.setAppOpVisibilityLw(false); 2394 } 2395 } 2396 2397 if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) { 2398 token.appWindowToken.startingWindow = win; 2399 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken 2400 + " startingWindow=" + win); 2401 } 2402 2403 boolean imMayMove = true; 2404 2405 if (type == TYPE_INPUT_METHOD) { 2406 win.mGivenInsetsPending = true; 2407 mInputMethodWindow = win; 2408 addInputMethodWindowToListLocked(win); 2409 imMayMove = false; 2410 } else if (type == TYPE_INPUT_METHOD_DIALOG) { 2411 mInputMethodDialogs.add(win); 2412 addWindowToListInOrderLocked(win, true); 2413 moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true)); 2414 imMayMove = false; 2415 } else { 2416 addWindowToListInOrderLocked(win, true); 2417 if (type == TYPE_WALLPAPER) { 2418 mLastWallpaperTimeoutTime = 0; 2419 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 2420 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) { 2421 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 2422 } else if (mWallpaperTarget != null 2423 && mWallpaperTarget.mLayer >= win.mBaseLayer) { 2424 // If there is currently a wallpaper being shown, and 2425 // the base layer of the new window is below the current 2426 // layer of the target window, then adjust the wallpaper. 2427 // This is to avoid a new window being placed between the 2428 // wallpaper and its target. 2429 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; 2430 } 2431 } 2432 2433 win.mWinAnimator.mEnterAnimationPending = true; 2434 2435 if (displayContent.isDefaultDisplay) { 2436 mPolicy.getContentInsetHintLw(attrs, outContentInsets); 2437 } else { 2438 outContentInsets.setEmpty(); 2439 } 2440 2441 if (mInTouchMode) { 2442 res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE; 2443 } 2444 if (win.mAppToken == null || !win.mAppToken.clientHidden) { 2445 res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE; 2446 } 2447 2448 mInputMonitor.setUpdateInputWindowsNeededLw(); 2449 2450 boolean focusChanged = false; 2451 if (win.canReceiveKeys()) { 2452 focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS, 2453 false /*updateInputWindows*/); 2454 if (focusChanged) { 2455 imMayMove = false; 2456 } 2457 } 2458 2459 if (imMayMove) { 2460 moveInputMethodWindowsIfNeededLocked(false); 2461 } 2462 2463 assignLayersLocked(displayContent.getWindowList()); 2464 // Don't do layout here, the window must call 2465 // relayout to be displayed, so we'll do it there. 2466 2467 if (focusChanged) { 2468 mInputMonitor.setInputFocusLw(mCurrentFocus, false /*updateInputWindows*/); 2469 } 2470 mInputMonitor.updateInputWindowsLw(false /*force*/); 2471 2472 if (localLOGV) Slog.v( 2473 TAG, "New client " + client.asBinder() 2474 + ": window=" + win); 2475 2476 if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) { 2477 reportNewConfig = true; 2478 } 2479 } 2480 2481 if (reportNewConfig) { 2482 sendNewConfiguration(); 2483 } 2484 2485 Binder.restoreCallingIdentity(origId); 2486 2487 return res; 2488 } 2489 2490 /** 2491 * Returns whether screen capture is disabled for all windows of a specific user. 2492 */ 2493 boolean isScreenCaptureDisabledLocked(int userId) { 2494 Boolean disabled = mScreenCaptureDisabled.get(userId); 2495 if (disabled == null) { 2496 return false; 2497 } 2498 return disabled; 2499 } 2500 2501 /** 2502 * Set mScreenCaptureDisabled for specific user 2503 */ 2504 @Override 2505 public void setScreenCaptureDisabled(int userId, boolean disabled) { 2506 int callingUid = Binder.getCallingUid(); 2507 if (callingUid != Process.SYSTEM_UID) { 2508 throw new SecurityException("Only system can call setScreenCaptureDisabled."); 2509 } 2510 2511 synchronized(mWindowMap) { 2512 mScreenCaptureDisabled.put(userId, disabled); 2513 } 2514 } 2515 2516 public void removeWindow(Session session, IWindow client) { 2517 synchronized(mWindowMap) { 2518 WindowState win = windowForClientLocked(session, client, false); 2519 if (win == null) { 2520 return; 2521 } 2522 removeWindowLocked(session, win); 2523 } 2524 } 2525 2526 public void removeWindowLocked(Session session, WindowState win) { 2527 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { 2528 if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win); 2529 } 2530 2531 if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v( 2532 TAG, "Remove " + win + " client=" 2533 + Integer.toHexString(System.identityHashCode(win.mClient.asBinder())) 2534 + ", surface=" + win.mWinAnimator.mSurfaceControl + " Callers=" 2535 + Debug.getCallers(4)); 2536 2537 final long origId = Binder.clearCallingIdentity(); 2538 2539 win.disposeInputChannel(); 2540 2541 if (DEBUG_APP_TRANSITIONS) Slog.v( 2542 TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl 2543 + " mExiting=" + win.mExiting 2544 + " isAnimating=" + win.mWinAnimator.isAnimating() 2545 + " app-animation=" 2546 + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null) 2547 + " inPendingTransaction=" 2548 + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false) 2549 + " mDisplayFrozen=" + mDisplayFrozen); 2550 // Visibility of the removed window. Will be used later to update orientation later on. 2551 boolean wasVisible = false; 2552 // First, see if we need to run an animation. If we do, we have 2553 // to hold off on removing the window until the animation is done. 2554 // If the display is frozen, just remove immediately, since the 2555 // animation wouldn't be seen. 2556 if (win.mHasSurface && okToDisplay()) { 2557 // If we are not currently running the exit animation, we 2558 // need to see about starting one. 2559 wasVisible = win.isWinVisibleLw(); 2560 if (wasVisible) { 2561 2562 int transit = WindowManagerPolicy.TRANSIT_EXIT; 2563 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { 2564 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; 2565 } 2566 // Try starting an animation. 2567 if (win.mWinAnimator.applyAnimationLocked(transit, false)) { 2568 win.mExiting = true; 2569 } 2570 //TODO (multidisplay): Magnification is supported only for the default display. 2571 if (mAccessibilityController != null 2572 && win.getDisplayId() == Display.DEFAULT_DISPLAY) { 2573 mAccessibilityController.onWindowTransitionLocked(win, transit); 2574 } 2575 } 2576 if (win.mExiting || win.mWinAnimator.isAnimating()) { 2577 // The exit animation is running... wait for it! 2578 //Slog.i(TAG, "*** Running exit animation..."); 2579 win.mExiting = true; 2580 win.mRemoveOnExit = true; 2581 final DisplayContent displayContent = win.getDisplayContent(); 2582 if (displayContent != null) { 2583 displayContent.layoutNeeded = true; 2584 } 2585 final boolean focusChanged = updateFocusedWindowLocked( 2586 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); 2587 performLayoutAndPlaceSurfacesLocked(); 2588 if (win.mAppToken != null) { 2589 win.mAppToken.updateReportedVisibilityLocked(); 2590 } 2591 if (focusChanged) { 2592 mInputMonitor.updateInputWindowsLw(false /*force*/); 2593 } 2594 //dump(); 2595 Binder.restoreCallingIdentity(origId); 2596 return; 2597 } 2598 } 2599 2600 removeWindowInnerLocked(session, win); 2601 // Removing a visible window will effect the computed orientation 2602 // So just update orientation if needed. 2603 if (wasVisible && updateOrientationFromAppTokensLocked(false)) { 2604 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 2605 } 2606 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/); 2607 Binder.restoreCallingIdentity(origId); 2608 } 2609 2610 void removeWindowInnerLocked(Session session, WindowState win) { 2611 if (win.mRemoved) { 2612 // Nothing to do. 2613 return; 2614 } 2615 2616 for (int i=win.mChildWindows.size()-1; i>=0; i--) { 2617 WindowState cwin = win.mChildWindows.get(i); 2618 Slog.w(TAG, "Force-removing child win " + cwin + " from container " 2619 + win); 2620 removeWindowInnerLocked(cwin.mSession, cwin); 2621 } 2622 2623 win.mRemoved = true; 2624 2625 if (mInputMethodTarget == win) { 2626 moveInputMethodWindowsIfNeededLocked(false); 2627 } 2628 2629 if (false) { 2630 RuntimeException e = new RuntimeException("here"); 2631 e.fillInStackTrace(); 2632 Slog.w(TAG, "Removing window " + win, e); 2633 } 2634 2635 mPolicy.removeWindowLw(win); 2636 win.removeLocked(); 2637 2638 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win); 2639 mWindowMap.remove(win.mClient.asBinder()); 2640 if (win.mAppOp != AppOpsManager.OP_NONE) { 2641 mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage()); 2642 } 2643 2644 mPendingRemove.remove(win); 2645 mResizingWindows.remove(win); 2646 mWindowsChanged = true; 2647 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win); 2648 2649 if (mInputMethodWindow == win) { 2650 mInputMethodWindow = null; 2651 } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) { 2652 mInputMethodDialogs.remove(win); 2653 } 2654 2655 final WindowToken token = win.mToken; 2656 final AppWindowToken atoken = win.mAppToken; 2657 if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token); 2658 token.windows.remove(win); 2659 if (atoken != null) { 2660 atoken.allAppWindows.remove(win); 2661 } 2662 if (localLOGV) Slog.v( 2663 TAG, "**** Removing window " + win + ": count=" 2664 + token.windows.size()); 2665 if (token.windows.size() == 0) { 2666 if (!token.explicit) { 2667 WindowToken wtoken = mTokenMap.remove(token.token); 2668 Slog.w("BadTokenDebug", "removeWindowInnerLocked: Removing token=" + token + " removed=" + 2669 wtoken + " Callers=" + Debug.getCallers(4)); 2670 } else if (atoken != null) { 2671 atoken.firstWindowDrawn = false; 2672 } 2673 } 2674 2675 if (atoken != null) { 2676 if (atoken.startingWindow == win) { 2677 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win); 2678 atoken.startingWindow = null; 2679 } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) { 2680 // If this is the last window and we had requested a starting 2681 // transition window, well there is no point now. 2682 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow"); 2683 atoken.startingData = null; 2684 } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) { 2685 // If this is the last window except for a starting transition 2686 // window, we need to get rid of the starting transition. 2687 scheduleRemoveStartingWindow(atoken); 2688 } 2689 } 2690 2691 if (win.mAttrs.type == TYPE_WALLPAPER) { 2692 mLastWallpaperTimeoutTime = 0; 2693 getDefaultDisplayContentLocked().pendingLayoutChanges |= 2694 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 2695 } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) { 2696 getDefaultDisplayContentLocked().pendingLayoutChanges |= 2697 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 2698 } 2699 2700 final WindowList windows = win.getWindowList(); 2701 if (windows != null) { 2702 windows.remove(win); 2703 if (!mInLayout) { 2704 assignLayersLocked(windows); 2705 final DisplayContent displayContent = win.getDisplayContent(); 2706 if (displayContent != null) { 2707 displayContent.layoutNeeded = true; 2708 } 2709 performLayoutAndPlaceSurfacesLocked(); 2710 if (win.mAppToken != null) { 2711 win.mAppToken.updateReportedVisibilityLocked(); 2712 } 2713 } 2714 } 2715 2716 mInputMonitor.updateInputWindowsLw(true /*force*/); 2717 } 2718 2719 public void updateAppOpsState() { 2720 synchronized(mWindowMap) { 2721 final int numDisplays = mDisplayContents.size(); 2722 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 2723 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); 2724 final int numWindows = windows.size(); 2725 for (int winNdx = 0; winNdx < numWindows; ++winNdx) { 2726 final WindowState win = windows.get(winNdx); 2727 if (win.mAppOp != AppOpsManager.OP_NONE) { 2728 final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(), 2729 win.getOwningPackage()); 2730 win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED); 2731 } 2732 } 2733 } 2734 } 2735 } 2736 2737 static void logSurface(WindowState w, String msg, RuntimeException where) { 2738 String str = " SURFACE " + msg + ": " + w; 2739 if (where != null) { 2740 Slog.i(TAG, str, where); 2741 } else { 2742 Slog.i(TAG, str); 2743 } 2744 } 2745 2746 static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) { 2747 String str = " SURFACE " + s + ": " + msg + " / " + title; 2748 if (where != null) { 2749 Slog.i(TAG, str, where); 2750 } else { 2751 Slog.i(TAG, str); 2752 } 2753 } 2754 2755 void setTransparentRegionWindow(Session session, IWindow client, Region region) { 2756 long origId = Binder.clearCallingIdentity(); 2757 try { 2758 synchronized (mWindowMap) { 2759 WindowState w = windowForClientLocked(session, client, false); 2760 if ((w != null) && w.mHasSurface) { 2761 w.mWinAnimator.setTransparentRegionHintLocked(region); 2762 } 2763 } 2764 } finally { 2765 Binder.restoreCallingIdentity(origId); 2766 } 2767 } 2768 2769 void setInsetsWindow(Session session, IWindow client, 2770 int touchableInsets, Rect contentInsets, 2771 Rect visibleInsets, Region touchableRegion) { 2772 long origId = Binder.clearCallingIdentity(); 2773 try { 2774 synchronized (mWindowMap) { 2775 WindowState w = windowForClientLocked(session, client, false); 2776 if (w != null) { 2777 w.mGivenInsetsPending = false; 2778 w.mGivenContentInsets.set(contentInsets); 2779 w.mGivenVisibleInsets.set(visibleInsets); 2780 w.mGivenTouchableRegion.set(touchableRegion); 2781 w.mTouchableInsets = touchableInsets; 2782 if (w.mGlobalScale != 1) { 2783 w.mGivenContentInsets.scale(w.mGlobalScale); 2784 w.mGivenVisibleInsets.scale(w.mGlobalScale); 2785 w.mGivenTouchableRegion.scale(w.mGlobalScale); 2786 } 2787 final DisplayContent displayContent = w.getDisplayContent(); 2788 if (displayContent != null) { 2789 displayContent.layoutNeeded = true; 2790 } 2791 performLayoutAndPlaceSurfacesLocked(); 2792 } 2793 } 2794 } finally { 2795 Binder.restoreCallingIdentity(origId); 2796 } 2797 } 2798 2799 public void getWindowDisplayFrame(Session session, IWindow client, 2800 Rect outDisplayFrame) { 2801 synchronized(mWindowMap) { 2802 WindowState win = windowForClientLocked(session, client, false); 2803 if (win == null) { 2804 outDisplayFrame.setEmpty(); 2805 return; 2806 } 2807 outDisplayFrame.set(win.mDisplayFrame); 2808 } 2809 } 2810 2811 public void setWindowWallpaperPositionLocked(WindowState window, float x, float y, 2812 float xStep, float yStep) { 2813 if (window.mWallpaperX != x || window.mWallpaperY != y) { 2814 window.mWallpaperX = x; 2815 window.mWallpaperY = y; 2816 window.mWallpaperXStep = xStep; 2817 window.mWallpaperYStep = yStep; 2818 updateWallpaperOffsetLocked(window, true); 2819 } 2820 } 2821 2822 void wallpaperCommandComplete(IBinder window, Bundle result) { 2823 synchronized (mWindowMap) { 2824 if (mWaitingOnWallpaper != null && 2825 mWaitingOnWallpaper.mClient.asBinder() == window) { 2826 mWaitingOnWallpaper = null; 2827 mWindowMap.notifyAll(); 2828 } 2829 } 2830 } 2831 2832 public Bundle sendWindowWallpaperCommandLocked(WindowState window, 2833 String action, int x, int y, int z, Bundle extras, boolean sync) { 2834 if (window == mWallpaperTarget || window == mLowerWallpaperTarget 2835 || window == mUpperWallpaperTarget) { 2836 boolean doWait = sync; 2837 int curTokenIndex = mWallpaperTokens.size(); 2838 while (curTokenIndex > 0) { 2839 curTokenIndex--; 2840 WindowToken token = mWallpaperTokens.get(curTokenIndex); 2841 int curWallpaperIndex = token.windows.size(); 2842 while (curWallpaperIndex > 0) { 2843 curWallpaperIndex--; 2844 WindowState wallpaper = token.windows.get(curWallpaperIndex); 2845 try { 2846 wallpaper.mClient.dispatchWallpaperCommand(action, 2847 x, y, z, extras, sync); 2848 // We only want to be synchronous with one wallpaper. 2849 sync = false; 2850 } catch (RemoteException e) { 2851 } 2852 } 2853 } 2854 2855 if (doWait) { 2856 // XXX Need to wait for result. 2857 } 2858 } 2859 2860 return null; 2861 } 2862 2863 public void setUniverseTransformLocked(WindowState window, float alpha, 2864 float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) { 2865 Transformation transform = window.mWinAnimator.mUniverseTransform; 2866 transform.setAlpha(alpha); 2867 Matrix matrix = transform.getMatrix(); 2868 matrix.getValues(mTmpFloats); 2869 mTmpFloats[Matrix.MTRANS_X] = offx; 2870 mTmpFloats[Matrix.MTRANS_Y] = offy; 2871 mTmpFloats[Matrix.MSCALE_X] = dsdx; 2872 mTmpFloats[Matrix.MSKEW_Y] = dtdx; 2873 mTmpFloats[Matrix.MSKEW_X] = dsdy; 2874 mTmpFloats[Matrix.MSCALE_Y] = dtdy; 2875 matrix.setValues(mTmpFloats); 2876 final DisplayContent displayContent = window.getDisplayContent(); 2877 if (displayContent == null) { 2878 return; 2879 } 2880 2881 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 2882 final RectF dispRect = new RectF(0, 0, 2883 displayInfo.logicalWidth, displayInfo.logicalHeight); 2884 matrix.mapRect(dispRect); 2885 window.mGivenTouchableRegion.set(0, 0, 2886 displayInfo.logicalWidth, displayInfo.logicalHeight); 2887 window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top, 2888 (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE); 2889 window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; 2890 displayContent.layoutNeeded = true; 2891 performLayoutAndPlaceSurfacesLocked(); 2892 } 2893 2894 public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) { 2895 synchronized (mWindowMap) { 2896 if (mAccessibilityController != null) { 2897 WindowState window = mWindowMap.get(token); 2898 //TODO (multidisplay): Magnification is supported only for the default display. 2899 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) { 2900 mAccessibilityController.onRectangleOnScreenRequestedLocked(rectangle); 2901 } 2902 } 2903 } 2904 } 2905 2906 public IWindowId getWindowId(IBinder token) { 2907 synchronized (mWindowMap) { 2908 WindowState window = mWindowMap.get(token); 2909 return window != null ? window.mWindowId : null; 2910 } 2911 } 2912 2913 public int relayoutWindow(Session session, IWindow client, int seq, 2914 WindowManager.LayoutParams attrs, int requestedWidth, 2915 int requestedHeight, int viewVisibility, int flags, 2916 Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, 2917 Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig, 2918 Surface outSurface) { 2919 boolean toBeDisplayed = false; 2920 boolean inTouchMode; 2921 boolean configChanged; 2922 boolean surfaceChanged = false; 2923 boolean animating; 2924 boolean hasStatusBarPermission = 2925 mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) 2926 == PackageManager.PERMISSION_GRANTED; 2927 2928 long origId = Binder.clearCallingIdentity(); 2929 2930 synchronized(mWindowMap) { 2931 WindowState win = windowForClientLocked(session, client, false); 2932 if (win == null) { 2933 return 0; 2934 } 2935 WindowStateAnimator winAnimator = win.mWinAnimator; 2936 if (win.mRequestedWidth != requestedWidth 2937 || win.mRequestedHeight != requestedHeight) { 2938 win.mLayoutNeeded = true; 2939 win.mRequestedWidth = requestedWidth; 2940 win.mRequestedHeight = requestedHeight; 2941 } 2942 2943 if (attrs != null) { 2944 mPolicy.adjustWindowParamsLw(attrs); 2945 } 2946 2947 // if they don't have the permission, mask out the status bar bits 2948 int systemUiVisibility = 0; 2949 if (attrs != null) { 2950 systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility); 2951 if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) { 2952 if (!hasStatusBarPermission) { 2953 systemUiVisibility &= ~StatusBarManager.DISABLE_MASK; 2954 } 2955 } 2956 } 2957 2958 if (attrs != null && seq == win.mSeq) { 2959 win.mSystemUiVisibility = systemUiVisibility; 2960 } 2961 2962 winAnimator.mSurfaceDestroyDeferred = 2963 (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0; 2964 2965 int attrChanges = 0; 2966 int flagChanges = 0; 2967 if (attrs != null) { 2968 if (win.mAttrs.type != attrs.type) { 2969 throw new IllegalArgumentException( 2970 "Window type can not be changed after the window is added."); 2971 } 2972 flagChanges = win.mAttrs.flags ^= attrs.flags; 2973 attrChanges = win.mAttrs.copyFrom(attrs); 2974 if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED 2975 | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) { 2976 win.mLayoutNeeded = true; 2977 } 2978 } 2979 2980 if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility 2981 + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs); 2982 2983 win.mEnforceSizeCompat = 2984 (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0; 2985 2986 if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) { 2987 winAnimator.mAlpha = attrs.alpha; 2988 } 2989 2990 final boolean scaledWindow = 2991 ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0); 2992 2993 if (scaledWindow) { 2994 // requested{Width|Height} Surface's physical size 2995 // attrs.{width|height} Size on screen 2996 win.mHScale = (attrs.width != requestedWidth) ? 2997 (attrs.width / (float)requestedWidth) : 1.0f; 2998 win.mVScale = (attrs.height != requestedHeight) ? 2999 (attrs.height / (float)requestedHeight) : 1.0f; 3000 } else { 3001 win.mHScale = win.mVScale = 1; 3002 } 3003 3004 boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0; 3005 3006 final boolean isDefaultDisplay = win.isDefaultDisplay(); 3007 boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility 3008 || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0) 3009 || (!win.mRelayoutCalled)); 3010 3011 boolean wallpaperMayMove = win.mViewVisibility != viewVisibility 3012 && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0; 3013 wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0; 3014 3015 win.mRelayoutCalled = true; 3016 final int oldVisibility = win.mViewVisibility; 3017 win.mViewVisibility = viewVisibility; 3018 if (DEBUG_SCREEN_ON) { 3019 RuntimeException stack = new RuntimeException(); 3020 stack.fillInStackTrace(); 3021 Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility 3022 + " newVis=" + viewVisibility, stack); 3023 } 3024 if (viewVisibility == View.VISIBLE && 3025 (win.mAppToken == null || !win.mAppToken.clientHidden)) { 3026 toBeDisplayed = !win.isVisibleLw(); 3027 if (win.mExiting) { 3028 winAnimator.cancelExitAnimationForNextAnimationLocked(); 3029 win.mExiting = false; 3030 } 3031 if (win.mDestroying) { 3032 win.mDestroying = false; 3033 mDestroySurface.remove(win); 3034 } 3035 if (oldVisibility == View.GONE) { 3036 winAnimator.mEnterAnimationPending = true; 3037 } 3038 if (toBeDisplayed) { 3039 if (win.isDrawnLw() && okToDisplay()) { 3040 winAnimator.applyEnterAnimationLocked(); 3041 } 3042 if ((win.mAttrs.flags 3043 & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) { 3044 if (DEBUG_VISIBILITY) Slog.v(TAG, 3045 "Relayout window turning screen on: " + win); 3046 win.mTurnOnScreen = true; 3047 } 3048 if (win.isConfigChanged()) { 3049 if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win 3050 + " visible with new config: " + mCurConfiguration); 3051 outConfig.setTo(mCurConfiguration); 3052 } 3053 } 3054 if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) { 3055 // To change the format, we need to re-build the surface. 3056 winAnimator.destroySurfaceLocked(); 3057 toBeDisplayed = true; 3058 surfaceChanged = true; 3059 } 3060 try { 3061 if (!win.mHasSurface) { 3062 surfaceChanged = true; 3063 } 3064 SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); 3065 if (surfaceControl != null) { 3066 outSurface.copyFrom(surfaceControl); 3067 if (SHOW_TRANSACTIONS) Slog.i(TAG, 3068 " OUT SURFACE " + outSurface + ": copied"); 3069 } else { 3070 // For some reason there isn't a surface. Clear the 3071 // caller's object so they see the same state. 3072 outSurface.release(); 3073 } 3074 } catch (Exception e) { 3075 mInputMonitor.updateInputWindowsLw(true /*force*/); 3076 3077 Slog.w(TAG, "Exception thrown when creating surface for client " 3078 + client + " (" + win.mAttrs.getTitle() + ")", 3079 e); 3080 Binder.restoreCallingIdentity(origId); 3081 return 0; 3082 } 3083 if (toBeDisplayed) { 3084 focusMayChange = isDefaultDisplay; 3085 } 3086 if (win.mAttrs.type == TYPE_INPUT_METHOD 3087 && mInputMethodWindow == null) { 3088 mInputMethodWindow = win; 3089 imMayMove = true; 3090 } 3091 if (win.mAttrs.type == TYPE_BASE_APPLICATION 3092 && win.mAppToken != null 3093 && win.mAppToken.startingWindow != null) { 3094 // Special handling of starting window over the base 3095 // window of the app: propagate lock screen flags to it, 3096 // to provide the correct semantics while starting. 3097 final int mask = 3098 WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 3099 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 3100 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; 3101 WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs; 3102 sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask); 3103 } 3104 } else { 3105 winAnimator.mEnterAnimationPending = false; 3106 if (winAnimator.mSurfaceControl != null) { 3107 if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win 3108 + ": mExiting=" + win.mExiting); 3109 // If we are not currently running the exit animation, we 3110 // need to see about starting one. 3111 if (!win.mExiting) { 3112 surfaceChanged = true; 3113 // Try starting an animation; if there isn't one, we 3114 // can destroy the surface right away. 3115 int transit = WindowManagerPolicy.TRANSIT_EXIT; 3116 if (win.mAttrs.type == TYPE_APPLICATION_STARTING) { 3117 transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE; 3118 } 3119 if (win.isWinVisibleLw() && 3120 winAnimator.applyAnimationLocked(transit, false)) { 3121 focusMayChange = isDefaultDisplay; 3122 win.mExiting = true; 3123 } else if (win.mWinAnimator.isAnimating()) { 3124 // Currently in a hide animation... turn this into 3125 // an exit. 3126 win.mExiting = true; 3127 } else if (win == mWallpaperTarget) { 3128 // If the wallpaper is currently behind this 3129 // window, we need to change both of them inside 3130 // of a transaction to avoid artifacts. 3131 win.mExiting = true; 3132 win.mWinAnimator.mAnimating = true; 3133 } else { 3134 if (mInputMethodWindow == win) { 3135 mInputMethodWindow = null; 3136 } 3137 winAnimator.destroySurfaceLocked(); 3138 } 3139 //TODO (multidisplay): Magnification is supported only for the default 3140 if (mAccessibilityController != null 3141 && win.getDisplayId() == Display.DEFAULT_DISPLAY) { 3142 mAccessibilityController.onWindowTransitionLocked(win, transit); 3143 } 3144 } 3145 } 3146 3147 outSurface.release(); 3148 if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win); 3149 } 3150 3151 if (focusMayChange) { 3152 //System.out.println("Focus may change: " + win.mAttrs.getTitle()); 3153 if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, 3154 false /*updateInputWindows*/)) { 3155 imMayMove = false; 3156 } 3157 //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus); 3158 } 3159 3160 // updateFocusedWindowLocked() already assigned layers so we only need to 3161 // reassign them at this point if the IM window state gets shuffled 3162 if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) { 3163 // Little hack here -- we -should- be able to rely on the 3164 // function to return true if the IME has moved and needs 3165 // its layer recomputed. However, if the IME was hidden 3166 // and isn't actually moved in the list, its layer may be 3167 // out of data so we make sure to recompute it. 3168 assignLayersLocked(win.getWindowList()); 3169 } 3170 3171 if (wallpaperMayMove) { 3172 getDefaultDisplayContentLocked().pendingLayoutChanges |= 3173 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 3174 } 3175 3176 final DisplayContent displayContent = win.getDisplayContent(); 3177 if (displayContent != null) { 3178 displayContent.layoutNeeded = true; 3179 } 3180 win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0; 3181 configChanged = updateOrientationFromAppTokensLocked(false); 3182 performLayoutAndPlaceSurfacesLocked(); 3183 if (toBeDisplayed && win.mIsWallpaper) { 3184 DisplayInfo displayInfo = getDefaultDisplayInfoLocked(); 3185 updateWallpaperOffsetLocked(win, 3186 displayInfo.logicalWidth, displayInfo.logicalHeight, false); 3187 } 3188 if (win.mAppToken != null) { 3189 win.mAppToken.updateReportedVisibilityLocked(); 3190 } 3191 outFrame.set(win.mCompatFrame); 3192 outOverscanInsets.set(win.mOverscanInsets); 3193 outContentInsets.set(win.mContentInsets); 3194 outVisibleInsets.set(win.mVisibleInsets); 3195 outStableInsets.set(win.mStableInsets); 3196 if (localLOGV) Slog.v( 3197 TAG, "Relayout given client " + client.asBinder() 3198 + ", requestedWidth=" + requestedWidth 3199 + ", requestedHeight=" + requestedHeight 3200 + ", viewVisibility=" + viewVisibility 3201 + "\nRelayout returning frame=" + outFrame 3202 + ", surface=" + outSurface); 3203 3204 if (localLOGV || DEBUG_FOCUS) Slog.v( 3205 TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange); 3206 3207 inTouchMode = mInTouchMode; 3208 animating = mAnimator.mAnimating && win.mWinAnimator.isAnimating(); 3209 if (animating && !mRelayoutWhileAnimating.contains(win)) { 3210 mRelayoutWhileAnimating.add(win); 3211 } 3212 3213 mInputMonitor.updateInputWindowsLw(true /*force*/); 3214 3215 if (DEBUG_LAYOUT) { 3216 Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString()); 3217 } 3218 } 3219 3220 if (configChanged) { 3221 sendNewConfiguration(); 3222 } 3223 3224 Binder.restoreCallingIdentity(origId); 3225 3226 return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0) 3227 | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0) 3228 | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0) 3229 | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0); 3230 } 3231 3232 public void performDeferredDestroyWindow(Session session, IWindow client) { 3233 long origId = Binder.clearCallingIdentity(); 3234 3235 try { 3236 synchronized (mWindowMap) { 3237 WindowState win = windowForClientLocked(session, client, false); 3238 if (win == null) { 3239 return; 3240 } 3241 win.mWinAnimator.destroyDeferredSurfaceLocked(); 3242 } 3243 } finally { 3244 Binder.restoreCallingIdentity(origId); 3245 } 3246 } 3247 3248 public boolean outOfMemoryWindow(Session session, IWindow client) { 3249 long origId = Binder.clearCallingIdentity(); 3250 3251 try { 3252 synchronized (mWindowMap) { 3253 WindowState win = windowForClientLocked(session, client, false); 3254 if (win == null) { 3255 return false; 3256 } 3257 return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false); 3258 } 3259 } finally { 3260 Binder.restoreCallingIdentity(origId); 3261 } 3262 } 3263 3264 public void finishDrawingWindow(Session session, IWindow client) { 3265 final long origId = Binder.clearCallingIdentity(); 3266 try { 3267 synchronized (mWindowMap) { 3268 WindowState win = windowForClientLocked(session, client, false); 3269 if (win != null && win.mWinAnimator.finishDrawingLocked()) { 3270 if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { 3271 getDefaultDisplayContentLocked().pendingLayoutChanges |= 3272 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 3273 } 3274 final DisplayContent displayContent = win.getDisplayContent(); 3275 if (displayContent != null) { 3276 displayContent.layoutNeeded = true; 3277 } 3278 requestTraversalLocked(); 3279 } 3280 } 3281 } finally { 3282 Binder.restoreCallingIdentity(origId); 3283 } 3284 } 3285 3286 private boolean applyAnimationLocked(AppWindowToken atoken, 3287 WindowManager.LayoutParams lp, int transit, boolean enter, boolean isVoiceInteraction) { 3288 // Only apply an animation if the display isn't frozen. If it is 3289 // frozen, there is no reason to animate and it can cause strange 3290 // artifacts when we unfreeze the display if some different animation 3291 // is running. 3292 if (okToDisplay()) { 3293 DisplayInfo displayInfo = getDefaultDisplayInfoLocked(); 3294 final int width = displayInfo.appWidth; 3295 final int height = displayInfo.appHeight; 3296 if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken=" 3297 + atoken); 3298 3299 // Determine the visible rect to calculate the thumbnail clip 3300 WindowState win = atoken.findMainWindow(); 3301 Rect containingFrame = new Rect(0, 0, width, height); 3302 Rect contentInsets = new Rect(); 3303 boolean isFullScreen = true; 3304 if (win != null) { 3305 if (win.mContainingFrame != null) { 3306 containingFrame.set(win.mContainingFrame); 3307 } 3308 if (win.mContentInsets != null) { 3309 contentInsets.set(win.mContentInsets); 3310 } 3311 isFullScreen = 3312 ((win.mSystemUiVisibility & SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN) == 3313 SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN); 3314 } 3315 3316 if (atoken.mLaunchTaskBehind) { 3317 // Differentiate the two animations. This one which is briefly on the screen 3318 // gets the !enter animation, and the other activity which remains on the 3319 // screen gets the enter animation. Both appear in the mOpeningApps set. 3320 enter = false; 3321 } 3322 Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height, 3323 mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen, 3324 isVoiceInteraction); 3325 if (a != null) { 3326 if (DEBUG_ANIM) { 3327 RuntimeException e = null; 3328 if (!HIDE_STACK_CRAWLS) { 3329 e = new RuntimeException(); 3330 e.fillInStackTrace(); 3331 } 3332 Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e); 3333 } 3334 atoken.mAppAnimator.setAnimation(a, width, height); 3335 } 3336 } else { 3337 atoken.mAppAnimator.clearAnimation(); 3338 } 3339 3340 return atoken.mAppAnimator.animation != null; 3341 } 3342 3343 // ------------------------------------------------------------- 3344 // Application Window Tokens 3345 // ------------------------------------------------------------- 3346 3347 public void validateAppTokens(int stackId, List<TaskGroup> tasks) { 3348 synchronized (mWindowMap) { 3349 int t = tasks.size() - 1; 3350 if (t < 0) { 3351 Slog.w(TAG, "validateAppTokens: empty task list"); 3352 return; 3353 } 3354 3355 TaskGroup task = tasks.get(0); 3356 int taskId = task.taskId; 3357 Task targetTask = mTaskIdToTask.get(taskId); 3358 DisplayContent displayContent = targetTask.getDisplayContent(); 3359 if (displayContent == null) { 3360 Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId); 3361 return; 3362 } 3363 3364 final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks(); 3365 int taskNdx; 3366 for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) { 3367 AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens; 3368 task = tasks.get(t); 3369 List<IApplicationToken> tokens = task.tokens; 3370 3371 DisplayContent lastDisplayContent = displayContent; 3372 displayContent = mTaskIdToTask.get(taskId).getDisplayContent(); 3373 if (displayContent != lastDisplayContent) { 3374 Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!"); 3375 return; 3376 } 3377 3378 int tokenNdx; 3379 int v; 3380 for (tokenNdx = localTokens.size() - 1, v = task.tokens.size() - 1; 3381 tokenNdx >= 0 && v >= 0; ) { 3382 final AppWindowToken atoken = localTokens.get(tokenNdx); 3383 if (atoken.removed) { 3384 --tokenNdx; 3385 continue; 3386 } 3387 if (tokens.get(v) != atoken.token) { 3388 break; 3389 } 3390 --tokenNdx; 3391 v--; 3392 } 3393 3394 if (tokenNdx >= 0 || v >= 0) { 3395 break; 3396 } 3397 } 3398 3399 if (taskNdx >= 0 || t >= 0) { 3400 Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks); 3401 Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks); 3402 Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4)); 3403 } 3404 } 3405 } 3406 3407 public void validateStackOrder(Integer[] remoteStackIds) { 3408 // TODO: 3409 } 3410 3411 boolean checkCallingPermission(String permission, String func) { 3412 // Quick check: if the calling permission is me, it's all okay. 3413 if (Binder.getCallingPid() == Process.myPid()) { 3414 return true; 3415 } 3416 3417 if (mContext.checkCallingPermission(permission) 3418 == PackageManager.PERMISSION_GRANTED) { 3419 return true; 3420 } 3421 String msg = "Permission Denial: " + func + " from pid=" 3422 + Binder.getCallingPid() 3423 + ", uid=" + Binder.getCallingUid() 3424 + " requires " + permission; 3425 Slog.w(TAG, msg); 3426 return false; 3427 } 3428 3429 boolean okToDisplay() { 3430 return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully(); 3431 } 3432 3433 AppWindowToken findAppWindowToken(IBinder token) { 3434 WindowToken wtoken = mTokenMap.get(token); 3435 if (wtoken == null) { 3436 return null; 3437 } 3438 return wtoken.appWindowToken; 3439 } 3440 3441 @Override 3442 public void addWindowToken(IBinder token, int type) { 3443 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3444 "addWindowToken()")) { 3445 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3446 } 3447 3448 synchronized(mWindowMap) { 3449 WindowToken wtoken = mTokenMap.get(token); 3450 if (wtoken != null) { 3451 Slog.w(TAG, "Attempted to add existing input method token: " + token); 3452 return; 3453 } 3454 wtoken = new WindowToken(this, token, type, true); 3455 Slog.w("BadTokenDebug", "addWindowToken: Adding token=" + token + " wtoken=" + wtoken); 3456 mTokenMap.put(token, wtoken); 3457 if (type == TYPE_WALLPAPER) { 3458 mWallpaperTokens.add(wtoken); 3459 } 3460 } 3461 } 3462 3463 @Override 3464 public void removeWindowToken(IBinder token) { 3465 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3466 "removeWindowToken()")) { 3467 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3468 } 3469 3470 final long origId = Binder.clearCallingIdentity(); 3471 synchronized(mWindowMap) { 3472 DisplayContent displayContent = null; 3473 WindowToken wtoken = mTokenMap.remove(token); 3474 Slog.w("BadTokenDebug", "removeWindowToken: Removing token=" + token + " removed=" + wtoken 3475 + " Callers=" + Debug.getCallers(3)); 3476 if (wtoken != null) { 3477 boolean delayed = false; 3478 if (!wtoken.hidden) { 3479 final int N = wtoken.windows.size(); 3480 boolean changed = false; 3481 3482 for (int i=0; i<N; i++) { 3483 WindowState win = wtoken.windows.get(i); 3484 displayContent = win.getDisplayContent(); 3485 3486 if (win.mWinAnimator.isAnimating()) { 3487 delayed = true; 3488 } 3489 3490 if (win.isVisibleNow()) { 3491 win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, 3492 false); 3493 //TODO (multidisplay): Magnification is supported only for the default 3494 if (mAccessibilityController != null && win.isDefaultDisplay()) { 3495 mAccessibilityController.onWindowTransitionLocked(win, 3496 WindowManagerPolicy.TRANSIT_EXIT); 3497 } 3498 changed = true; 3499 if (displayContent != null) { 3500 displayContent.layoutNeeded = true; 3501 } 3502 } 3503 } 3504 3505 wtoken.hidden = true; 3506 3507 if (changed) { 3508 performLayoutAndPlaceSurfacesLocked(); 3509 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, 3510 false /*updateInputWindows*/); 3511 } 3512 3513 if (delayed) { 3514 if (displayContent != null) { 3515 displayContent.mExitingTokens.add(wtoken); 3516 } 3517 } else if (wtoken.windowType == TYPE_WALLPAPER) { 3518 mWallpaperTokens.remove(wtoken); 3519 } 3520 } 3521 3522 mInputMonitor.updateInputWindowsLw(true /*force*/); 3523 } else { 3524 Slog.w(TAG, "Attempted to remove non-existing token: " + token); 3525 } 3526 } 3527 Binder.restoreCallingIdentity(origId); 3528 } 3529 3530 private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) { 3531 if (DEBUG_STACK) Slog.i(TAG, "createTask: taskId=" + taskId + " stackId=" + stackId 3532 + " atoken=" + atoken); 3533 final TaskStack stack = mStackIdToStack.get(stackId); 3534 if (stack == null) { 3535 throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId); 3536 } 3537 EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId); 3538 Task task = new Task(atoken, stack, userId); 3539 mTaskIdToTask.put(taskId, task); 3540 stack.addTask(task, !atoken.mLaunchTaskBehind /* toTop */); 3541 return task; 3542 } 3543 3544 @Override 3545 public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId, 3546 int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId, 3547 int configChanges, boolean voiceInteraction, boolean launchTaskBehind) { 3548 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3549 "addAppToken()")) { 3550 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3551 } 3552 3553 // Get the dispatching timeout here while we are not holding any locks so that it 3554 // can be cached by the AppWindowToken. The timeout value is used later by the 3555 // input dispatcher in code that does hold locks. If we did not cache the value 3556 // here we would run the chance of introducing a deadlock between the window manager 3557 // (which holds locks while updating the input dispatcher state) and the activity manager 3558 // (which holds locks while querying the application token). 3559 long inputDispatchingTimeoutNanos; 3560 try { 3561 inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L; 3562 } catch (RemoteException ex) { 3563 Slog.w(TAG, "Could not get dispatching timeout.", ex); 3564 inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; 3565 } 3566 3567 synchronized(mWindowMap) { 3568 AppWindowToken atoken = findAppWindowToken(token.asBinder()); 3569 if (atoken != null) { 3570 Slog.w(TAG, "Attempted to add existing app token: " + token); 3571 return; 3572 } 3573 atoken = new AppWindowToken(this, token, voiceInteraction); 3574 atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos; 3575 atoken.groupId = taskId; 3576 atoken.appFullscreen = fullscreen; 3577 atoken.showWhenLocked = showWhenLocked; 3578 atoken.requestedOrientation = requestedOrientation; 3579 atoken.layoutConfigChanges = (configChanges & 3580 (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0; 3581 atoken.mLaunchTaskBehind = launchTaskBehind; 3582 if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken 3583 + " to stack=" + stackId + " task=" + taskId + " at " + addPos); 3584 3585 Task task = mTaskIdToTask.get(taskId); 3586 if (task == null) { 3587 createTask(taskId, stackId, userId, atoken); 3588 } else { 3589 task.addAppToken(addPos, atoken); 3590 } 3591 3592 Slog.w("BadTokenDebug", "addAppToken: Adding token=" + token.asBinder() + " atoken=" + atoken); 3593 mTokenMap.put(token.asBinder(), atoken); 3594 3595 // Application tokens start out hidden. 3596 atoken.hidden = true; 3597 atoken.hiddenRequested = true; 3598 3599 //dump(); 3600 } 3601 } 3602 3603 @Override 3604 public void setAppGroupId(IBinder token, int groupId) { 3605 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3606 "setAppGroupId()")) { 3607 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3608 } 3609 3610 synchronized(mWindowMap) { 3611 final AppWindowToken atoken = findAppWindowToken(token); 3612 if (atoken == null) { 3613 Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token); 3614 return; 3615 } 3616 final Task oldTask = mTaskIdToTask.get(atoken.groupId); 3617 oldTask.removeAppToken(atoken); 3618 3619 atoken.groupId = groupId; 3620 Task newTask = mTaskIdToTask.get(groupId); 3621 if (newTask == null) { 3622 newTask = createTask(groupId, oldTask.mStack.mStackId, oldTask.mUserId, atoken); 3623 } else { 3624 newTask.mAppTokens.add(atoken); 3625 } 3626 } 3627 } 3628 3629 public int getOrientationFromWindowsLocked() { 3630 if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) { 3631 // If the display is frozen, some activities may be in the middle 3632 // of restarting, and thus have removed their old window. If the 3633 // window has the flag to hide the lock screen, then the lock screen 3634 // can re-appear and inflict its own orientation on us. Keep the 3635 // orientation stable until this all settles down. 3636 return mLastWindowForcedOrientation; 3637 } 3638 3639 // TODO(multidisplay): Change to the correct display. 3640 final WindowList windows = getDefaultWindowListLocked(); 3641 int pos = windows.size() - 1; 3642 while (pos >= 0) { 3643 WindowState win = windows.get(pos); 3644 pos--; 3645 if (win.mAppToken != null) { 3646 // We hit an application window. so the orientation will be determined by the 3647 // app window. No point in continuing further. 3648 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 3649 } 3650 if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) { 3651 continue; 3652 } 3653 int req = win.mAttrs.screenOrientation; 3654 if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) || 3655 (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){ 3656 continue; 3657 } 3658 3659 if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req); 3660 return (mLastWindowForcedOrientation=req); 3661 } 3662 return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 3663 } 3664 3665 public int getOrientationFromAppTokensLocked() { 3666 int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3667 boolean findingBehind = false; 3668 boolean lastFullscreen = false; 3669 // TODO: Multi window. 3670 DisplayContent displayContent = getDefaultDisplayContentLocked(); 3671 final ArrayList<Task> tasks = displayContent.getTasks(); 3672 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 3673 AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 3674 final int firstToken = tokens.size() - 1; 3675 for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) { 3676 final AppWindowToken atoken = tokens.get(tokenNdx); 3677 3678 if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken); 3679 3680 // if we're about to tear down this window and not seek for 3681 // the behind activity, don't use it for orientation 3682 if (!findingBehind 3683 && (!atoken.hidden && atoken.hiddenRequested)) { 3684 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken 3685 + " -- going to hide"); 3686 continue; 3687 } 3688 3689 if (tokenNdx == firstToken) { 3690 // If we have hit a new Task, and the bottom 3691 // of the previous group didn't explicitly say to use 3692 // the orientation behind it, and the last app was 3693 // full screen, then we'll stick with the 3694 // user's orientation. 3695 if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND 3696 && lastFullscreen) { 3697 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken 3698 + " -- end of group, return " + lastOrientation); 3699 return lastOrientation; 3700 } 3701 } 3702 3703 // We ignore any hidden applications on the top. 3704 if (atoken.hiddenRequested || atoken.willBeHidden) { 3705 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken 3706 + " -- hidden on top"); 3707 continue; 3708 } 3709 3710 if (tokenNdx == 0) { 3711 // Last token in this task. 3712 lastOrientation = atoken.requestedOrientation; 3713 } 3714 3715 int or = atoken.requestedOrientation; 3716 // If this application is fullscreen, and didn't explicitly say 3717 // to use the orientation behind it, then just take whatever 3718 // orientation it has and ignores whatever is under it. 3719 lastFullscreen = atoken.appFullscreen; 3720 if (lastFullscreen 3721 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) { 3722 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken 3723 + " -- full screen, return " + or); 3724 return or; 3725 } 3726 // If this application has requested an explicit orientation, 3727 // then use it. 3728 if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED 3729 && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) { 3730 if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken 3731 + " -- explicitly set, return " + or); 3732 return or; 3733 } 3734 findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND); 3735 } 3736 } 3737 if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation"); 3738 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3739 } 3740 3741 @Override 3742 public Configuration updateOrientationFromAppTokens( 3743 Configuration currentConfig, IBinder freezeThisOneIfNeeded) { 3744 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3745 "updateOrientationFromAppTokens()")) { 3746 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3747 } 3748 3749 Configuration config = null; 3750 long ident = Binder.clearCallingIdentity(); 3751 3752 synchronized(mWindowMap) { 3753 config = updateOrientationFromAppTokensLocked(currentConfig, 3754 freezeThisOneIfNeeded); 3755 } 3756 3757 Binder.restoreCallingIdentity(ident); 3758 return config; 3759 } 3760 3761 private Configuration updateOrientationFromAppTokensLocked( 3762 Configuration currentConfig, IBinder freezeThisOneIfNeeded) { 3763 Configuration config = null; 3764 3765 if (updateOrientationFromAppTokensLocked(false)) { 3766 if (freezeThisOneIfNeeded != null) { 3767 AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded); 3768 if (atoken != null) { 3769 startAppFreezingScreenLocked(atoken); 3770 } 3771 } 3772 config = computeNewConfigurationLocked(); 3773 3774 } else if (currentConfig != null) { 3775 // No obvious action we need to take, but if our current 3776 // state mismatches the activity manager's, update it, 3777 // disregarding font scale, which should remain set to 3778 // the value of the previous configuration. 3779 mTempConfiguration.setToDefaults(); 3780 mTempConfiguration.fontScale = currentConfig.fontScale; 3781 if (computeScreenConfigurationLocked(mTempConfiguration)) { 3782 if (currentConfig.diff(mTempConfiguration) != 0) { 3783 mWaitingForConfig = true; 3784 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 3785 displayContent.layoutNeeded = true; 3786 int anim[] = new int[2]; 3787 if (displayContent.isDimming()) { 3788 anim[0] = anim[1] = 0; 3789 } else { 3790 mPolicy.selectRotationAnimationLw(anim); 3791 } 3792 startFreezingDisplayLocked(false, anim[0], anim[1]); 3793 config = new Configuration(mTempConfiguration); 3794 } 3795 } 3796 } 3797 3798 return config; 3799 } 3800 3801 /* 3802 * Determine the new desired orientation of the display, returning 3803 * a non-null new Configuration if it has changed from the current 3804 * orientation. IF TRUE IS RETURNED SOMEONE MUST CALL 3805 * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE 3806 * SCREEN. This will typically be done for you if you call 3807 * sendNewConfiguration(). 3808 * 3809 * The orientation is computed from non-application windows first. If none of 3810 * the non-application windows specify orientation, the orientation is computed from 3811 * application tokens. 3812 * @see android.view.IWindowManager#updateOrientationFromAppTokens( 3813 * android.os.IBinder) 3814 */ 3815 boolean updateOrientationFromAppTokensLocked(boolean inTransaction) { 3816 long ident = Binder.clearCallingIdentity(); 3817 try { 3818 int req = getOrientationFromWindowsLocked(); 3819 if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { 3820 req = getOrientationFromAppTokensLocked(); 3821 } 3822 3823 if (req != mForcedAppOrientation) { 3824 mForcedAppOrientation = req; 3825 //send a message to Policy indicating orientation change to take 3826 //action like disabling/enabling sensors etc., 3827 mPolicy.setCurrentOrientationLw(req); 3828 if (updateRotationUncheckedLocked(inTransaction)) { 3829 // changed 3830 return true; 3831 } 3832 } 3833 3834 return false; 3835 } finally { 3836 Binder.restoreCallingIdentity(ident); 3837 } 3838 } 3839 3840 @Override 3841 public void setNewConfiguration(Configuration config) { 3842 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3843 "setNewConfiguration()")) { 3844 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3845 } 3846 3847 synchronized(mWindowMap) { 3848 mCurConfiguration = new Configuration(config); 3849 if (mWaitingForConfig) { 3850 mWaitingForConfig = false; 3851 mLastFinishedFreezeSource = "new-config"; 3852 } 3853 performLayoutAndPlaceSurfacesLocked(); 3854 } 3855 } 3856 3857 @Override 3858 public void setAppOrientation(IApplicationToken token, int requestedOrientation) { 3859 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3860 "setAppOrientation()")) { 3861 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3862 } 3863 3864 synchronized(mWindowMap) { 3865 AppWindowToken atoken = findAppWindowToken(token.asBinder()); 3866 if (atoken == null) { 3867 Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token); 3868 return; 3869 } 3870 3871 atoken.requestedOrientation = requestedOrientation; 3872 } 3873 } 3874 3875 @Override 3876 public int getAppOrientation(IApplicationToken token) { 3877 synchronized(mWindowMap) { 3878 AppWindowToken wtoken = findAppWindowToken(token.asBinder()); 3879 if (wtoken == null) { 3880 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3881 } 3882 3883 return wtoken.requestedOrientation; 3884 } 3885 } 3886 3887 /** Call while in a Surface transaction. */ 3888 void setFocusedStackLayer() { 3889 mFocusedStackLayer = 0; 3890 if (mFocusedApp != null) { 3891 final WindowList windows = mFocusedApp.allAppWindows; 3892 for (int i = windows.size() - 1; i >= 0; --i) { 3893 final WindowState win = windows.get(i); 3894 final int animLayer = win.mWinAnimator.mAnimLayer; 3895 if (win.mAttachedWindow == null && win.isVisibleLw() && 3896 animLayer > mFocusedStackLayer) { 3897 mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK; 3898 } 3899 } 3900 } 3901 if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" + 3902 mFocusedStackLayer); 3903 mFocusedStackFrame.setLayer(mFocusedStackLayer); 3904 } 3905 3906 void setFocusedStackFrame() { 3907 final TaskStack stack; 3908 if (mFocusedApp != null) { 3909 Task task = mTaskIdToTask.get(mFocusedApp.groupId); 3910 stack = task.mStack; 3911 final DisplayContent displayContent = task.getDisplayContent(); 3912 if (displayContent != null) { 3913 displayContent.setTouchExcludeRegion(stack); 3914 } 3915 } else { 3916 stack = null; 3917 } 3918 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame"); 3919 SurfaceControl.openTransaction(); 3920 try { 3921 if (stack == null) { 3922 mFocusedStackFrame.setVisibility(false); 3923 } else { 3924 mFocusedStackFrame.setBounds(stack); 3925 final boolean multipleStacks = !stack.isFullscreen(); 3926 mFocusedStackFrame.setVisibility(multipleStacks); 3927 } 3928 } finally { 3929 SurfaceControl.closeTransaction(); 3930 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame"); 3931 } 3932 } 3933 3934 @Override 3935 public void setFocusedApp(IBinder token, boolean moveFocusNow) { 3936 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3937 "setFocusedApp()")) { 3938 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3939 } 3940 3941 synchronized(mWindowMap) { 3942 final AppWindowToken newFocus; 3943 if (token == null) { 3944 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp); 3945 newFocus = null; 3946 } else { 3947 newFocus = findAppWindowToken(token); 3948 if (newFocus == null) { 3949 Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token); 3950 } 3951 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus 3952 + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow); 3953 } 3954 3955 final boolean changed = mFocusedApp != newFocus; 3956 if (changed) { 3957 mFocusedApp = newFocus; 3958 mInputMonitor.setFocusedAppLw(newFocus); 3959 } 3960 3961 if (moveFocusNow && changed) { 3962 final long origId = Binder.clearCallingIdentity(); 3963 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/); 3964 Binder.restoreCallingIdentity(origId); 3965 } 3966 } 3967 } 3968 3969 @Override 3970 public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) { 3971 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 3972 "prepareAppTransition()")) { 3973 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 3974 } 3975 3976 synchronized(mWindowMap) { 3977 if (DEBUG_APP_TRANSITIONS) Slog.v( 3978 TAG, "Prepare app transition: transit=" + transit 3979 + " " + mAppTransition 3980 + " alwaysKeepCurrent=" + alwaysKeepCurrent 3981 + " Callers=" + Debug.getCallers(3)); 3982 if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) { 3983 mAppTransition.setAppTransition(transit); 3984 } else if (!alwaysKeepCurrent) { 3985 if (transit == AppTransition.TRANSIT_TASK_OPEN 3986 && mAppTransition.isTransitionEqual( 3987 AppTransition.TRANSIT_TASK_CLOSE)) { 3988 // Opening a new task always supersedes a close for the anim. 3989 mAppTransition.setAppTransition(transit); 3990 } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN 3991 && mAppTransition.isTransitionEqual( 3992 AppTransition.TRANSIT_ACTIVITY_CLOSE)) { 3993 // Opening a new activity always supersedes a close for the anim. 3994 mAppTransition.setAppTransition(transit); 3995 } 3996 } 3997 if (okToDisplay()) { 3998 mAppTransition.prepare(); 3999 mStartingIconInTransition = false; 4000 mSkipAppTransitionAnimation = false; 4001 mH.removeMessages(H.APP_TRANSITION_TIMEOUT); 4002 mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000); 4003 } 4004 } 4005 } 4006 4007 @Override 4008 public int getPendingAppTransition() { 4009 return mAppTransition.getAppTransition(); 4010 } 4011 4012 @Override 4013 public void overridePendingAppTransition(String packageName, 4014 int enterAnim, int exitAnim, IRemoteCallback startedCallback) { 4015 synchronized(mWindowMap) { 4016 mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim, 4017 startedCallback); 4018 } 4019 } 4020 4021 @Override 4022 public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, 4023 int startHeight) { 4024 synchronized(mWindowMap) { 4025 mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth, 4026 startHeight); 4027 } 4028 } 4029 4030 @Override 4031 public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, 4032 int startY, IRemoteCallback startedCallback, boolean scaleUp) { 4033 synchronized(mWindowMap) { 4034 mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY, 4035 startedCallback, scaleUp); 4036 } 4037 } 4038 4039 @Override 4040 public void overridePendingAppTransitionAspectScaledThumb(Bitmap srcThumb, int startX, 4041 int startY, IRemoteCallback startedCallback, boolean scaleUp) { 4042 synchronized(mWindowMap) { 4043 mAppTransition.overridePendingAppTransitionAspectScaledThumb(srcThumb, startX, 4044 startY, startedCallback, scaleUp); 4045 } 4046 } 4047 4048 @Override 4049 public void executeAppTransition() { 4050 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4051 "executeAppTransition()")) { 4052 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4053 } 4054 4055 synchronized(mWindowMap) { 4056 if (DEBUG_APP_TRANSITIONS) Slog.w(TAG, "Execute app transition: " + mAppTransition, 4057 new RuntimeException("here").fillInStackTrace()); 4058 if (mAppTransition.isTransitionSet()) { 4059 mAppTransition.setReady(); 4060 final long origId = Binder.clearCallingIdentity(); 4061 try { 4062 performLayoutAndPlaceSurfacesLocked(); 4063 } finally { 4064 Binder.restoreCallingIdentity(origId); 4065 } 4066 } 4067 } 4068 } 4069 4070 @Override 4071 public void setAppStartingWindow(IBinder token, String pkg, 4072 int theme, CompatibilityInfo compatInfo, 4073 CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, 4074 int windowFlags, IBinder transferFrom, boolean createIfNeeded) { 4075 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4076 "setAppStartingWindow()")) { 4077 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4078 } 4079 4080 synchronized(mWindowMap) { 4081 if (DEBUG_STARTING_WINDOW) Slog.v( 4082 TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg 4083 + " transferFrom=" + transferFrom); 4084 4085 AppWindowToken wtoken = findAppWindowToken(token); 4086 if (wtoken == null) { 4087 Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token); 4088 return; 4089 } 4090 4091 // If the display is frozen, we won't do anything until the 4092 // actual window is displayed so there is no reason to put in 4093 // the starting window. 4094 if (!okToDisplay()) { 4095 return; 4096 } 4097 4098 if (wtoken.startingData != null) { 4099 return; 4100 } 4101 4102 if (transferFrom != null) { 4103 AppWindowToken ttoken = findAppWindowToken(transferFrom); 4104 if (ttoken != null) { 4105 WindowState startingWindow = ttoken.startingWindow; 4106 if (startingWindow != null) { 4107 if (mStartingIconInTransition) { 4108 // In this case, the starting icon has already 4109 // been displayed, so start letting windows get 4110 // shown immediately without any more transitions. 4111 mSkipAppTransitionAnimation = true; 4112 } 4113 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, 4114 "Moving existing starting " + startingWindow + " from " + ttoken 4115 + " to " + wtoken); 4116 final long origId = Binder.clearCallingIdentity(); 4117 4118 // Transfer the starting window over to the new 4119 // token. 4120 wtoken.startingData = ttoken.startingData; 4121 wtoken.startingView = ttoken.startingView; 4122 wtoken.startingDisplayed = ttoken.startingDisplayed; 4123 ttoken.startingDisplayed = false; 4124 wtoken.startingWindow = startingWindow; 4125 wtoken.reportedVisible = ttoken.reportedVisible; 4126 ttoken.startingData = null; 4127 ttoken.startingView = null; 4128 ttoken.startingWindow = null; 4129 ttoken.startingMoved = true; 4130 startingWindow.mToken = wtoken; 4131 startingWindow.mRootToken = wtoken; 4132 startingWindow.mAppToken = wtoken; 4133 startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator; 4134 4135 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) { 4136 Slog.v(TAG, "Removing starting window: " + startingWindow); 4137 } 4138 startingWindow.getWindowList().remove(startingWindow); 4139 mWindowsChanged = true; 4140 if (DEBUG_ADD_REMOVE) Slog.v(TAG, 4141 "Removing starting " + startingWindow + " from " + ttoken); 4142 ttoken.windows.remove(startingWindow); 4143 ttoken.allAppWindows.remove(startingWindow); 4144 addWindowToListInOrderLocked(startingWindow, true); 4145 4146 // Propagate other interesting state between the 4147 // tokens. If the old token is displayed, we should 4148 // immediately force the new one to be displayed. If 4149 // it is animating, we need to move that animation to 4150 // the new one. 4151 if (ttoken.allDrawn) { 4152 wtoken.allDrawn = true; 4153 wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn; 4154 } 4155 if (ttoken.firstWindowDrawn) { 4156 wtoken.firstWindowDrawn = true; 4157 } 4158 if (!ttoken.hidden) { 4159 wtoken.hidden = false; 4160 wtoken.hiddenRequested = false; 4161 wtoken.willBeHidden = false; 4162 } 4163 if (wtoken.clientHidden != ttoken.clientHidden) { 4164 wtoken.clientHidden = ttoken.clientHidden; 4165 wtoken.sendAppVisibilityToClients(); 4166 } 4167 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator; 4168 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator; 4169 if (tAppAnimator.animation != null) { 4170 wAppAnimator.animation = tAppAnimator.animation; 4171 wAppAnimator.animating = tAppAnimator.animating; 4172 wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment; 4173 tAppAnimator.animation = null; 4174 tAppAnimator.animLayerAdjustment = 0; 4175 wAppAnimator.updateLayers(); 4176 tAppAnimator.updateLayers(); 4177 } 4178 4179 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, 4180 true /*updateInputWindows*/); 4181 getDefaultDisplayContentLocked().layoutNeeded = true; 4182 performLayoutAndPlaceSurfacesLocked(); 4183 Binder.restoreCallingIdentity(origId); 4184 return; 4185 } else if (ttoken.startingData != null) { 4186 // The previous app was getting ready to show a 4187 // starting window, but hasn't yet done so. Steal it! 4188 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, 4189 "Moving pending starting from " + ttoken 4190 + " to " + wtoken); 4191 wtoken.startingData = ttoken.startingData; 4192 ttoken.startingData = null; 4193 ttoken.startingMoved = true; 4194 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken); 4195 // Note: we really want to do sendMessageAtFrontOfQueue() because we 4196 // want to process the message ASAP, before any other queued 4197 // messages. 4198 mH.sendMessageAtFrontOfQueue(m); 4199 return; 4200 } 4201 final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator; 4202 final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator; 4203 if (tAppAnimator.thumbnail != null) { 4204 // The old token is animating with a thumbnail, transfer 4205 // that to the new token. 4206 if (wAppAnimator.thumbnail != null) { 4207 wAppAnimator.thumbnail.destroy(); 4208 } 4209 wAppAnimator.thumbnail = tAppAnimator.thumbnail; 4210 wAppAnimator.thumbnailX = tAppAnimator.thumbnailX; 4211 wAppAnimator.thumbnailY = tAppAnimator.thumbnailY; 4212 wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer; 4213 wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation; 4214 tAppAnimator.thumbnail = null; 4215 } 4216 } 4217 } 4218 4219 // There is no existing starting window, and the caller doesn't 4220 // want us to create one, so that's it! 4221 if (!createIfNeeded) { 4222 return; 4223 } 4224 4225 // If this is a translucent window, then don't 4226 // show a starting window -- the current effect (a full-screen 4227 // opaque starting window that fades away to the real contents 4228 // when it is ready) does not work for this. 4229 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x" 4230 + Integer.toHexString(theme)); 4231 if (theme != 0) { 4232 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme, 4233 com.android.internal.R.styleable.Window, mCurrentUserId); 4234 if (ent == null) { 4235 // Whoops! App doesn't exist. Um. Okay. We'll just 4236 // pretend like we didn't see that. 4237 return; 4238 } 4239 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent=" 4240 + ent.array.getBoolean( 4241 com.android.internal.R.styleable.Window_windowIsTranslucent, false) 4242 + " Floating=" 4243 + ent.array.getBoolean( 4244 com.android.internal.R.styleable.Window_windowIsFloating, false) 4245 + " ShowWallpaper=" 4246 + ent.array.getBoolean( 4247 com.android.internal.R.styleable.Window_windowShowWallpaper, false)); 4248 if (ent.array.getBoolean( 4249 com.android.internal.R.styleable.Window_windowIsTranslucent, false)) { 4250 return; 4251 } 4252 if (ent.array.getBoolean( 4253 com.android.internal.R.styleable.Window_windowIsFloating, false)) { 4254 return; 4255 } 4256 if (ent.array.getBoolean( 4257 com.android.internal.R.styleable.Window_windowShowWallpaper, false)) { 4258 if (mWallpaperTarget == null) { 4259 // If this theme is requesting a wallpaper, and the wallpaper 4260 // is not curently visible, then this effectively serves as 4261 // an opaque window and our starting window transition animation 4262 // can still work. We just need to make sure the starting window 4263 // is also showing the wallpaper. 4264 windowFlags |= FLAG_SHOW_WALLPAPER; 4265 } else { 4266 return; 4267 } 4268 } 4269 } 4270 4271 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData"); 4272 mStartingIconInTransition = true; 4273 wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel, 4274 labelRes, icon, logo, windowFlags); 4275 Message m = mH.obtainMessage(H.ADD_STARTING, wtoken); 4276 // Note: we really want to do sendMessageAtFrontOfQueue() because we 4277 // want to process the message ASAP, before any other queued 4278 // messages. 4279 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING"); 4280 mH.sendMessageAtFrontOfQueue(m); 4281 } 4282 } 4283 4284 public void removeAppStartingWindow(IBinder token) { 4285 synchronized (mWindowMap) { 4286 AppWindowToken wtoken = mTokenMap.get(token).appWindowToken; 4287 if (wtoken.startingWindow != null) { 4288 scheduleRemoveStartingWindow(wtoken); 4289 } 4290 } 4291 } 4292 4293 @Override 4294 public void setAppWillBeHidden(IBinder token) { 4295 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4296 "setAppWillBeHidden()")) { 4297 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4298 } 4299 4300 AppWindowToken wtoken; 4301 4302 synchronized(mWindowMap) { 4303 wtoken = findAppWindowToken(token); 4304 if (wtoken == null) { 4305 Slog.w(TAG, "Attempted to set will be hidden of non-existing app token: " + token); 4306 return; 4307 } 4308 wtoken.willBeHidden = true; 4309 } 4310 } 4311 4312 public void setAppFullscreen(IBinder token, boolean toOpaque) { 4313 AppWindowToken atoken = findAppWindowToken(token); 4314 if (atoken != null) { 4315 atoken.appFullscreen = toOpaque; 4316 setWindowOpaque(token, toOpaque); 4317 requestTraversal(); 4318 } 4319 } 4320 4321 public void setWindowOpaque(IBinder token, boolean isOpaque) { 4322 AppWindowToken wtoken = findAppWindowToken(token); 4323 if (wtoken != null) { 4324 WindowState win = wtoken.findMainWindow(); 4325 if (win != null) { 4326 win.mWinAnimator.setOpaque(isOpaque); 4327 } 4328 } 4329 } 4330 4331 boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp, 4332 boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) { 4333 boolean delayed = false; 4334 4335 if (wtoken.clientHidden == visible) { 4336 wtoken.clientHidden = !visible; 4337 wtoken.sendAppVisibilityToClients(); 4338 } 4339 4340 wtoken.willBeHidden = false; 4341 if (wtoken.hidden == visible) { 4342 boolean changed = false; 4343 if (DEBUG_APP_TRANSITIONS) Slog.v( 4344 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden 4345 + " performLayout=" + performLayout); 4346 4347 boolean runningAppAnimation = false; 4348 4349 if (transit != AppTransition.TRANSIT_UNSET) { 4350 if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) { 4351 wtoken.mAppAnimator.animation = null; 4352 } 4353 if (applyAnimationLocked(wtoken, lp, transit, visible, isVoiceInteraction)) { 4354 delayed = runningAppAnimation = true; 4355 } 4356 WindowState window = wtoken.findMainWindow(); 4357 //TODO (multidisplay): Magnification is supported only for the default display. 4358 if (window != null && mAccessibilityController != null 4359 && window.getDisplayId() == Display.DEFAULT_DISPLAY) { 4360 mAccessibilityController.onAppWindowTransitionLocked(window, transit); 4361 } 4362 changed = true; 4363 } 4364 4365 final int N = wtoken.allAppWindows.size(); 4366 for (int i=0; i<N; i++) { 4367 WindowState win = wtoken.allAppWindows.get(i); 4368 if (win == wtoken.startingWindow) { 4369 continue; 4370 } 4371 4372 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible()); 4373 //win.dump(" "); 4374 if (visible) { 4375 if (!win.isVisibleNow()) { 4376 if (!runningAppAnimation) { 4377 win.mWinAnimator.applyAnimationLocked( 4378 WindowManagerPolicy.TRANSIT_ENTER, true); 4379 //TODO (multidisplay): Magnification is supported only for the default 4380 if (mAccessibilityController != null 4381 && win.getDisplayId() == Display.DEFAULT_DISPLAY) { 4382 mAccessibilityController.onWindowTransitionLocked(win, 4383 WindowManagerPolicy.TRANSIT_ENTER); 4384 } 4385 } 4386 changed = true; 4387 final DisplayContent displayContent = win.getDisplayContent(); 4388 if (displayContent != null) { 4389 displayContent.layoutNeeded = true; 4390 } 4391 } 4392 } else if (win.isVisibleNow()) { 4393 if (!runningAppAnimation) { 4394 win.mWinAnimator.applyAnimationLocked( 4395 WindowManagerPolicy.TRANSIT_EXIT, false); 4396 //TODO (multidisplay): Magnification is supported only for the default 4397 if (mAccessibilityController != null 4398 && win.getDisplayId() == Display.DEFAULT_DISPLAY) { 4399 mAccessibilityController.onWindowTransitionLocked(win, 4400 WindowManagerPolicy.TRANSIT_EXIT); 4401 } 4402 } 4403 changed = true; 4404 final DisplayContent displayContent = win.getDisplayContent(); 4405 if (displayContent != null) { 4406 displayContent.layoutNeeded = true; 4407 } 4408 } 4409 } 4410 4411 wtoken.hidden = wtoken.hiddenRequested = !visible; 4412 if (!visible) { 4413 unsetAppFreezingScreenLocked(wtoken, true, true); 4414 } else { 4415 // If we are being set visible, and the starting window is 4416 // not yet displayed, then make sure it doesn't get displayed. 4417 WindowState swin = wtoken.startingWindow; 4418 if (swin != null && !swin.isDrawnLw()) { 4419 swin.mPolicyVisibility = false; 4420 swin.mPolicyVisibilityAfterAnim = false; 4421 } 4422 } 4423 4424 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken 4425 + ": hidden=" + wtoken.hidden + " hiddenRequested=" 4426 + wtoken.hiddenRequested); 4427 4428 if (changed) { 4429 mInputMonitor.setUpdateInputWindowsNeededLw(); 4430 if (performLayout) { 4431 updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, 4432 false /*updateInputWindows*/); 4433 performLayoutAndPlaceSurfacesLocked(); 4434 } 4435 mInputMonitor.updateInputWindowsLw(false /*force*/); 4436 } 4437 } 4438 4439 if (wtoken.mAppAnimator.animation != null) { 4440 delayed = true; 4441 } 4442 4443 for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) { 4444 if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) { 4445 delayed = true; 4446 } 4447 } 4448 4449 return delayed; 4450 } 4451 4452 @Override 4453 public void setAppVisibility(IBinder token, boolean visible) { 4454 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4455 "setAppVisibility()")) { 4456 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4457 } 4458 4459 AppWindowToken wtoken; 4460 4461 synchronized(mWindowMap) { 4462 wtoken = findAppWindowToken(token); 4463 if (wtoken == null) { 4464 Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token); 4465 return; 4466 } 4467 4468 if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) Slog.v(TAG, "setAppVisibility(" + 4469 token + ", visible=" + visible + "): " + mAppTransition + 4470 " hidden=" + wtoken.hidden + " hiddenRequested=" + 4471 wtoken.hiddenRequested, HIDE_STACK_CRAWLS ? 4472 null : new RuntimeException("here").fillInStackTrace()); 4473 4474 // If we are preparing an app transition, then delay changing 4475 // the visibility of this token until we execute that transition. 4476 if (okToDisplay() && mAppTransition.isTransitionSet()) { 4477 wtoken.hiddenRequested = !visible; 4478 4479 if (!wtoken.startingDisplayed) { 4480 if (DEBUG_APP_TRANSITIONS) Slog.v( 4481 TAG, "Setting dummy animation on: " + wtoken); 4482 wtoken.mAppAnimator.setDummyAnimation(); 4483 } 4484 mOpeningApps.remove(wtoken); 4485 mClosingApps.remove(wtoken); 4486 wtoken.waitingToShow = wtoken.waitingToHide = false; 4487 wtoken.inPendingTransaction = true; 4488 if (visible) { 4489 mOpeningApps.add(wtoken); 4490 wtoken.startingMoved = false; 4491 wtoken.mEnteringAnimation = true; 4492 4493 // If the token is currently hidden (should be the 4494 // common case), then we need to set up to wait for 4495 // its windows to be ready. 4496 if (wtoken.hidden) { 4497 wtoken.allDrawn = false; 4498 wtoken.deferClearAllDrawn = false; 4499 wtoken.waitingToShow = true; 4500 4501 if (wtoken.clientHidden) { 4502 // In the case where we are making an app visible 4503 // but holding off for a transition, we still need 4504 // to tell the client to make its windows visible so 4505 // they get drawn. Otherwise, we will wait on 4506 // performing the transition until all windows have 4507 // been drawn, they never will be, and we are sad. 4508 wtoken.clientHidden = false; 4509 wtoken.sendAppVisibilityToClients(); 4510 } 4511 } 4512 } else { 4513 mClosingApps.add(wtoken); 4514 wtoken.mEnteringAnimation = false; 4515 4516 // If the token is currently visible (should be the 4517 // common case), then set up to wait for it to be hidden. 4518 if (!wtoken.hidden) { 4519 wtoken.waitingToHide = true; 4520 } 4521 } 4522 if (mAppTransition.getAppTransition() == AppTransition.TRANSIT_TASK_OPEN_BEHIND) { 4523 // We're launchingBehind, add the launching activity to mOpeningApps. 4524 final WindowState win = 4525 findFocusedWindowLocked(getDefaultDisplayContentLocked()); 4526 if (win != null) { 4527 final AppWindowToken focusedToken = win.mAppToken; 4528 if (focusedToken != null) { 4529 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "TRANSIT_TASK_OPEN_BEHIND, " + 4530 " adding " + focusedToken + " to mOpeningApps"); 4531 // Force animation to be loaded. 4532 focusedToken.hidden = true; 4533 mOpeningApps.add(focusedToken); 4534 } 4535 } 4536 } 4537 return; 4538 } 4539 4540 final long origId = Binder.clearCallingIdentity(); 4541 setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET, 4542 true, wtoken.voiceInteraction); 4543 wtoken.updateReportedVisibilityLocked(); 4544 Binder.restoreCallingIdentity(origId); 4545 } 4546 } 4547 4548 void unsetAppFreezingScreenLocked(AppWindowToken wtoken, 4549 boolean unfreezeSurfaceNow, boolean force) { 4550 if (wtoken.mAppAnimator.freezingScreen) { 4551 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken 4552 + " force=" + force); 4553 final int N = wtoken.allAppWindows.size(); 4554 boolean unfrozeWindows = false; 4555 for (int i=0; i<N; i++) { 4556 WindowState w = wtoken.allAppWindows.get(i); 4557 if (w.mAppFreezing) { 4558 w.mAppFreezing = false; 4559 if (w.mHasSurface && !w.mOrientationChanging) { 4560 if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w); 4561 w.mOrientationChanging = true; 4562 mInnerFields.mOrientationChangeComplete = false; 4563 } 4564 w.mLastFreezeDuration = 0; 4565 unfrozeWindows = true; 4566 final DisplayContent displayContent = w.getDisplayContent(); 4567 if (displayContent != null) { 4568 displayContent.layoutNeeded = true; 4569 } 4570 } 4571 } 4572 if (force || unfrozeWindows) { 4573 if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken); 4574 wtoken.mAppAnimator.freezingScreen = false; 4575 wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime() 4576 - mDisplayFreezeTime); 4577 mAppsFreezingScreen--; 4578 mLastFinishedFreezeSource = wtoken; 4579 } 4580 if (unfreezeSurfaceNow) { 4581 if (unfrozeWindows) { 4582 performLayoutAndPlaceSurfacesLocked(); 4583 } 4584 stopFreezingDisplayLocked(); 4585 } 4586 } 4587 } 4588 4589 private void startAppFreezingScreenLocked(AppWindowToken wtoken) { 4590 if (DEBUG_ORIENTATION) { 4591 RuntimeException e = null; 4592 if (!HIDE_STACK_CRAWLS) { 4593 e = new RuntimeException(); 4594 e.fillInStackTrace(); 4595 } 4596 Slog.i(TAG, "Set freezing of " + wtoken.appToken 4597 + ": hidden=" + wtoken.hidden + " freezing=" 4598 + wtoken.mAppAnimator.freezingScreen, e); 4599 } 4600 if (!wtoken.hiddenRequested) { 4601 if (!wtoken.mAppAnimator.freezingScreen) { 4602 wtoken.mAppAnimator.freezingScreen = true; 4603 wtoken.mAppAnimator.lastFreezeDuration = 0; 4604 mAppsFreezingScreen++; 4605 if (mAppsFreezingScreen == 1) { 4606 startFreezingDisplayLocked(false, 0, 0); 4607 mH.removeMessages(H.APP_FREEZE_TIMEOUT); 4608 mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000); 4609 } 4610 } 4611 final int N = wtoken.allAppWindows.size(); 4612 for (int i=0; i<N; i++) { 4613 WindowState w = wtoken.allAppWindows.get(i); 4614 w.mAppFreezing = true; 4615 } 4616 } 4617 } 4618 4619 @Override 4620 public void startAppFreezingScreen(IBinder token, int configChanges) { 4621 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4622 "setAppFreezingScreen()")) { 4623 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4624 } 4625 4626 synchronized(mWindowMap) { 4627 if (configChanges == 0 && okToDisplay()) { 4628 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token); 4629 return; 4630 } 4631 4632 AppWindowToken wtoken = findAppWindowToken(token); 4633 if (wtoken == null || wtoken.appToken == null) { 4634 Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken); 4635 return; 4636 } 4637 final long origId = Binder.clearCallingIdentity(); 4638 startAppFreezingScreenLocked(wtoken); 4639 Binder.restoreCallingIdentity(origId); 4640 } 4641 } 4642 4643 @Override 4644 public void stopAppFreezingScreen(IBinder token, boolean force) { 4645 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4646 "setAppFreezingScreen()")) { 4647 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4648 } 4649 4650 synchronized(mWindowMap) { 4651 AppWindowToken wtoken = findAppWindowToken(token); 4652 if (wtoken == null || wtoken.appToken == null) { 4653 return; 4654 } 4655 final long origId = Binder.clearCallingIdentity(); 4656 if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token 4657 + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen); 4658 unsetAppFreezingScreenLocked(wtoken, true, force); 4659 Binder.restoreCallingIdentity(origId); 4660 } 4661 } 4662 4663 void removeAppFromTaskLocked(AppWindowToken wtoken) { 4664 wtoken.removeAllWindows(); 4665 4666 final Task task = mTaskIdToTask.get(wtoken.groupId); 4667 if (task != null) { 4668 if (!task.removeAppToken(wtoken)) { 4669 Slog.e(TAG, "removeAppFromTaskLocked: token=" + wtoken + " not found."); 4670 } 4671 } 4672 } 4673 4674 @Override 4675 public void removeAppToken(IBinder token) { 4676 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 4677 "removeAppToken()")) { 4678 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 4679 } 4680 4681 AppWindowToken wtoken = null; 4682 AppWindowToken startingToken = null; 4683 boolean delayed = false; 4684 4685 final long origId = Binder.clearCallingIdentity(); 4686 synchronized(mWindowMap) { 4687 WindowToken basewtoken = mTokenMap.remove(token); 4688 Slog.w("BadTokenDebug", "removeAppToke: Removing token=" + token + " removed=" + basewtoken); 4689 if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) { 4690 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken); 4691 delayed = setTokenVisibilityLocked(wtoken, null, false, 4692 AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction); 4693 wtoken.inPendingTransaction = false; 4694 mOpeningApps.remove(wtoken); 4695 wtoken.waitingToShow = false; 4696 if (mClosingApps.contains(wtoken)) { 4697 delayed = true; 4698 } else if (mAppTransition.isTransitionSet()) { 4699 mClosingApps.add(wtoken); 4700 wtoken.waitingToHide = true; 4701 delayed = true; 4702 } 4703 if (DEBUG_APP_TRANSITIONS) Slog.v( 4704 TAG, "Removing app " + wtoken + " delayed=" + delayed 4705 + " animation=" + wtoken.mAppAnimator.animation 4706 + " animating=" + wtoken.mAppAnimator.animating); 4707 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: " 4708 + wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4)); 4709 final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack; 4710 if (delayed) { 4711 // set the token aside because it has an active animation to be finished 4712 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, 4713 "removeAppToken make exiting: " + wtoken); 4714 stack.mExitingAppTokens.add(wtoken); 4715 wtoken.mDeferRemoval = true; 4716 } else { 4717 // Make sure there is no animation running on this token, 4718 // so any windows associated with it will be removed as 4719 // soon as their animations are complete 4720 wtoken.mAppAnimator.clearAnimation(); 4721 wtoken.mAppAnimator.animating = false; 4722 removeAppFromTaskLocked(wtoken); 4723 } 4724 4725 wtoken.removed = true; 4726 if (wtoken.startingData != null) { 4727 startingToken = wtoken; 4728 } 4729 unsetAppFreezingScreenLocked(wtoken, true, true); 4730 if (mFocusedApp == wtoken) { 4731 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Removing focused app token:" + wtoken); 4732 mFocusedApp = null; 4733 updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/); 4734 mInputMonitor.setFocusedAppLw(null); 4735 } 4736 } else { 4737 Slog.w(TAG, "Attempted to remove non-existing app token: " + token); 4738 } 4739 4740 if (!delayed && wtoken != null) { 4741 wtoken.updateReportedVisibilityLocked(); 4742 } 4743 } 4744 Binder.restoreCallingIdentity(origId); 4745 4746 // Will only remove if startingToken non null. 4747 scheduleRemoveStartingWindow(startingToken); 4748 } 4749 4750 void scheduleRemoveStartingWindow(AppWindowToken wtoken) { 4751 if (wtoken != null && wtoken.startingWindow != null) { 4752 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) + 4753 ": Schedule remove starting " + wtoken + (wtoken != null ? 4754 " startingWindow=" + wtoken.startingWindow : "")); 4755 Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken); 4756 mH.sendMessage(m); 4757 } 4758 } 4759 4760 private boolean tmpRemoveAppWindowsLocked(WindowToken token) { 4761 WindowList windows = token.windows; 4762 final int NW = windows.size(); 4763 if (NW > 0) { 4764 mWindowsChanged = true; 4765 } 4766 for (int i = 0; i < NW; i++) { 4767 WindowState win = windows.get(i); 4768 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win); 4769 win.getWindowList().remove(win); 4770 int j = win.mChildWindows.size(); 4771 while (j > 0) { 4772 j--; 4773 WindowState cwin = win.mChildWindows.get(j); 4774 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, 4775 "Tmp removing child window " + cwin); 4776 cwin.getWindowList().remove(cwin); 4777 } 4778 } 4779 return NW > 0; 4780 } 4781 4782 void dumpAppTokensLocked() { 4783 final int numStacks = mStackIdToStack.size(); 4784 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 4785 final TaskStack stack = mStackIdToStack.valueAt(stackNdx); 4786 Slog.v(TAG, " Stack #" + stack.mStackId + " tasks from bottom to top:"); 4787 final ArrayList<Task> tasks = stack.getTasks(); 4788 final int numTasks = tasks.size(); 4789 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { 4790 final Task task = tasks.get(taskNdx); 4791 Slog.v(TAG, " Task #" + task.taskId + " activities from bottom to top:"); 4792 AppTokenList tokens = task.mAppTokens; 4793 final int numTokens = tokens.size(); 4794 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { 4795 Slog.v(TAG, " activity #" + tokenNdx + ": " + tokens.get(tokenNdx).token); 4796 } 4797 } 4798 } 4799 } 4800 4801 void dumpWindowsLocked() { 4802 final int numDisplays = mDisplayContents.size(); 4803 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 4804 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 4805 Slog.v(TAG, " Display #" + displayContent.getDisplayId()); 4806 final WindowList windows = displayContent.getWindowList(); 4807 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { 4808 Slog.v(TAG, " #" + winNdx + ": " + windows.get(winNdx)); 4809 } 4810 } 4811 } 4812 4813 private int findAppWindowInsertionPointLocked(AppWindowToken target) { 4814 final int taskId = target.groupId; 4815 Task targetTask = mTaskIdToTask.get(taskId); 4816 if (targetTask == null) { 4817 Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId=" 4818 + taskId); 4819 return 0; 4820 } 4821 DisplayContent displayContent = targetTask.getDisplayContent(); 4822 if (displayContent == null) { 4823 Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target); 4824 return 0; 4825 } 4826 final WindowList windows = displayContent.getWindowList(); 4827 final int NW = windows.size(); 4828 4829 boolean found = false; 4830 final ArrayList<Task> tasks = displayContent.getTasks(); 4831 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 4832 final Task task = tasks.get(taskNdx); 4833 if (!found && task.taskId != taskId) { 4834 continue; 4835 } 4836 AppTokenList tokens = task.mAppTokens; 4837 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 4838 final AppWindowToken wtoken = tokens.get(tokenNdx); 4839 if (!found && wtoken == target) { 4840 found = true; 4841 } 4842 if (found) { 4843 // Find the first app token below the new position that has 4844 // a window displayed. 4845 if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token); 4846 if (wtoken.sendingToBottom) { 4847 if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom"); 4848 continue; 4849 } 4850 for (int i = wtoken.windows.size() - 1; i >= 0; --i) { 4851 WindowState win = wtoken.windows.get(i); 4852 for (int j = win.mChildWindows.size() - 1; j >= 0; --j) { 4853 WindowState cwin = win.mChildWindows.get(j); 4854 if (cwin.mSubLayer >= 0) { 4855 for (int pos = NW - 1; pos >= 0; pos--) { 4856 if (windows.get(pos) == cwin) { 4857 if (DEBUG_REORDER) Slog.v(TAG, 4858 "Found child win @" + (pos + 1)); 4859 return pos + 1; 4860 } 4861 } 4862 } 4863 } 4864 for (int pos = NW - 1; pos >= 0; pos--) { 4865 if (windows.get(pos) == win) { 4866 if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1)); 4867 return pos + 1; 4868 } 4869 } 4870 } 4871 } 4872 } 4873 } 4874 // Never put an app window underneath wallpaper. 4875 for (int pos = NW - 1; pos >= 0; pos--) { 4876 if (windows.get(pos).mIsWallpaper) { 4877 if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos); 4878 return pos + 1; 4879 } 4880 } 4881 return 0; 4882 } 4883 4884 private final int reAddWindowLocked(int index, WindowState win) { 4885 final WindowList windows = win.getWindowList(); 4886 final int NCW = win.mChildWindows.size(); 4887 boolean added = false; 4888 for (int j=0; j<NCW; j++) { 4889 WindowState cwin = win.mChildWindows.get(j); 4890 if (!added && cwin.mSubLayer >= 0) { 4891 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at " 4892 + index + ": " + cwin); 4893 win.mRebuilding = false; 4894 windows.add(index, win); 4895 index++; 4896 added = true; 4897 } 4898 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at " 4899 + index + ": " + cwin); 4900 cwin.mRebuilding = false; 4901 windows.add(index, cwin); 4902 index++; 4903 } 4904 if (!added) { 4905 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at " 4906 + index + ": " + win); 4907 win.mRebuilding = false; 4908 windows.add(index, win); 4909 index++; 4910 } 4911 mWindowsChanged = true; 4912 return index; 4913 } 4914 4915 private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index, 4916 WindowToken token) { 4917 final int NW = token.windows.size(); 4918 for (int i=0; i<NW; i++) { 4919 final WindowState win = token.windows.get(i); 4920 final DisplayContent winDisplayContent = win.getDisplayContent(); 4921 if (winDisplayContent == displayContent || winDisplayContent == null) { 4922 win.mDisplayContent = displayContent; 4923 index = reAddWindowLocked(index, win); 4924 } 4925 } 4926 return index; 4927 } 4928 4929 void tmpRemoveTaskWindowsLocked(Task task) { 4930 AppTokenList tokens = task.mAppTokens; 4931 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 4932 tmpRemoveAppWindowsLocked(tokens.get(tokenNdx)); 4933 } 4934 } 4935 4936 void moveStackWindowsLocked(DisplayContent displayContent) { 4937 // First remove all of the windows from the list. 4938 final ArrayList<Task> tasks = displayContent.getTasks(); 4939 final int numTasks = tasks.size(); 4940 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { 4941 tmpRemoveTaskWindowsLocked(tasks.get(taskNdx)); 4942 } 4943 4944 // And now add them back at the correct place. 4945 // Where to start adding? 4946 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { 4947 AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 4948 final int numTokens = tokens.size(); 4949 if (numTokens == 0) { 4950 continue; 4951 } 4952 int pos = findAppWindowInsertionPointLocked(tokens.get(0)); 4953 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { 4954 final AppWindowToken wtoken = tokens.get(tokenNdx); 4955 if (wtoken != null) { 4956 final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken); 4957 if (newPos != pos) { 4958 displayContent.layoutNeeded = true; 4959 } 4960 pos = newPos; 4961 } 4962 } 4963 } 4964 4965 if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, 4966 false /*updateInputWindows*/)) { 4967 assignLayersLocked(displayContent.getWindowList()); 4968 } 4969 4970 mInputMonitor.setUpdateInputWindowsNeededLw(); 4971 performLayoutAndPlaceSurfacesLocked(); 4972 mInputMonitor.updateInputWindowsLw(false /*force*/); 4973 4974 //dump(); 4975 } 4976 4977 public void moveTaskToTop(int taskId) { 4978 final long origId = Binder.clearCallingIdentity(); 4979 try { 4980 synchronized(mWindowMap) { 4981 Task task = mTaskIdToTask.get(taskId); 4982 if (task == null) { 4983 // Normal behavior, addAppToken will be called next and task will be created. 4984 return; 4985 } 4986 final TaskStack stack = task.mStack; 4987 final DisplayContent displayContent = task.getDisplayContent(); 4988 displayContent.moveStack(stack, true); 4989 if (displayContent.isDefaultDisplay) { 4990 final TaskStack homeStack = displayContent.getHomeStack(); 4991 if (homeStack != stack) { 4992 // When a non-home stack moves to the top, the home stack moves to the 4993 // bottom. 4994 displayContent.moveStack(homeStack, false); 4995 } 4996 } 4997 stack.moveTaskToTop(task); 4998 } 4999 } finally { 5000 Binder.restoreCallingIdentity(origId); 5001 } 5002 } 5003 5004 public void moveTaskToBottom(int taskId) { 5005 final long origId = Binder.clearCallingIdentity(); 5006 try { 5007 synchronized(mWindowMap) { 5008 Task task = mTaskIdToTask.get(taskId); 5009 if (task == null) { 5010 Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId 5011 + " not found in mTaskIdToTask"); 5012 return; 5013 } 5014 final TaskStack stack = task.mStack; 5015 stack.moveTaskToBottom(task); 5016 moveStackWindowsLocked(stack.getDisplayContent()); 5017 } 5018 } finally { 5019 Binder.restoreCallingIdentity(origId); 5020 } 5021 } 5022 5023 /** 5024 * Create a new TaskStack and place it on a DisplayContent. 5025 * @param stackId The unique identifier of the new stack. 5026 * @param displayId The unique identifier of the DisplayContent. 5027 */ 5028 public void attachStack(int stackId, int displayId) { 5029 final long origId = Binder.clearCallingIdentity(); 5030 try { 5031 synchronized (mWindowMap) { 5032 final DisplayContent displayContent = mDisplayContents.get(displayId); 5033 if (displayContent != null) { 5034 TaskStack stack = mStackIdToStack.get(stackId); 5035 if (stack == null) { 5036 if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId); 5037 stack = new TaskStack(this, stackId); 5038 mStackIdToStack.put(stackId, stack); 5039 } 5040 stack.attachDisplayContent(displayContent); 5041 displayContent.attachStack(stack); 5042 moveStackWindowsLocked(displayContent); 5043 final WindowList windows = displayContent.getWindowList(); 5044 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { 5045 windows.get(winNdx).reportResized(); 5046 } 5047 } 5048 } 5049 } finally { 5050 Binder.restoreCallingIdentity(origId); 5051 } 5052 } 5053 5054 void detachStackLocked(DisplayContent displayContent, TaskStack stack) { 5055 displayContent.detachStack(stack); 5056 stack.detachDisplay(); 5057 } 5058 5059 public void detachStack(int stackId) { 5060 synchronized (mWindowMap) { 5061 TaskStack stack = mStackIdToStack.get(stackId); 5062 if (stack != null) { 5063 final DisplayContent displayContent = stack.getDisplayContent(); 5064 if (displayContent != null) { 5065 if (stack.isAnimating()) { 5066 stack.mDeferDetach = true; 5067 return; 5068 } 5069 detachStackLocked(displayContent, stack); 5070 } 5071 } 5072 } 5073 } 5074 5075 public void removeStack(int stackId) { 5076 mStackIdToStack.remove(stackId); 5077 } 5078 5079 void removeTaskLocked(Task task) { 5080 final int taskId = task.taskId; 5081 final TaskStack stack = task.mStack; 5082 if (stack.isAnimating()) { 5083 if (DEBUG_STACK) Slog.i(TAG, "removeTask: deferring removing taskId=" + taskId); 5084 task.mDeferRemoval = true; 5085 return; 5086 } 5087 if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + taskId); 5088 EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask"); 5089 task.mDeferRemoval = false; 5090 task.mStack.removeTask(task); 5091 mTaskIdToTask.delete(task.taskId); 5092 } 5093 5094 public void removeTask(int taskId) { 5095 synchronized (mWindowMap) { 5096 Task task = mTaskIdToTask.get(taskId); 5097 if (task == null) { 5098 if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId); 5099 return; 5100 } 5101 removeTaskLocked(task); 5102 } 5103 } 5104 5105 public void addTask(int taskId, int stackId, boolean toTop) { 5106 synchronized (mWindowMap) { 5107 if (DEBUG_STACK) Slog.i(TAG, "addTask: adding taskId=" + taskId 5108 + " to " + (toTop ? "top" : "bottom")); 5109 Task task = mTaskIdToTask.get(taskId); 5110 if (task == null) { 5111 return; 5112 } 5113 TaskStack stack = mStackIdToStack.get(stackId); 5114 stack.addTask(task, toTop); 5115 final DisplayContent displayContent = stack.getDisplayContent(); 5116 displayContent.layoutNeeded = true; 5117 performLayoutAndPlaceSurfacesLocked(); 5118 } 5119 } 5120 5121 public void resizeStack(int stackId, Rect bounds) { 5122 synchronized (mWindowMap) { 5123 final TaskStack stack = mStackIdToStack.get(stackId); 5124 if (stack == null) { 5125 throw new IllegalArgumentException("resizeStack: stackId " + stackId 5126 + " not found."); 5127 } 5128 if (stack.setBounds(bounds)) { 5129 stack.resizeWindows(); 5130 stack.getDisplayContent().layoutNeeded = true; 5131 performLayoutAndPlaceSurfacesLocked(); 5132 } 5133 } 5134 } 5135 5136 public void getStackBounds(int stackId, Rect bounds) { 5137 final TaskStack stack = mStackIdToStack.get(stackId); 5138 if (stack != null) { 5139 stack.getBounds(bounds); 5140 return; 5141 } 5142 bounds.setEmpty(); 5143 } 5144 5145 // ------------------------------------------------------------- 5146 // Misc IWindowSession methods 5147 // ------------------------------------------------------------- 5148 5149 @Override 5150 public void startFreezingScreen(int exitAnim, int enterAnim) { 5151 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN, 5152 "startFreezingScreen()")) { 5153 throw new SecurityException("Requires FREEZE_SCREEN permission"); 5154 } 5155 5156 synchronized(mWindowMap) { 5157 if (!mClientFreezingScreen) { 5158 mClientFreezingScreen = true; 5159 final long origId = Binder.clearCallingIdentity(); 5160 try { 5161 startFreezingDisplayLocked(false, exitAnim, enterAnim); 5162 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); 5163 mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000); 5164 } finally { 5165 Binder.restoreCallingIdentity(origId); 5166 } 5167 } 5168 } 5169 } 5170 5171 @Override 5172 public void stopFreezingScreen() { 5173 if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN, 5174 "stopFreezingScreen()")) { 5175 throw new SecurityException("Requires FREEZE_SCREEN permission"); 5176 } 5177 5178 synchronized(mWindowMap) { 5179 if (mClientFreezingScreen) { 5180 mClientFreezingScreen = false; 5181 mLastFinishedFreezeSource = "client"; 5182 final long origId = Binder.clearCallingIdentity(); 5183 try { 5184 stopFreezingDisplayLocked(); 5185 } finally { 5186 Binder.restoreCallingIdentity(origId); 5187 } 5188 } 5189 } 5190 } 5191 5192 @Override 5193 public void disableKeyguard(IBinder token, String tag) { 5194 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 5195 != PackageManager.PERMISSION_GRANTED) { 5196 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 5197 } 5198 5199 if (token == null) { 5200 throw new IllegalArgumentException("token == null"); 5201 } 5202 5203 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage( 5204 KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag))); 5205 } 5206 5207 @Override 5208 public void reenableKeyguard(IBinder token) { 5209 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 5210 != PackageManager.PERMISSION_GRANTED) { 5211 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 5212 } 5213 5214 if (token == null) { 5215 throw new IllegalArgumentException("token == null"); 5216 } 5217 5218 mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage( 5219 KeyguardDisableHandler.KEYGUARD_REENABLE, token)); 5220 } 5221 5222 /** 5223 * @see android.app.KeyguardManager#exitKeyguardSecurely 5224 */ 5225 @Override 5226 public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) { 5227 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 5228 != PackageManager.PERMISSION_GRANTED) { 5229 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 5230 } 5231 5232 if (callback == null) { 5233 throw new IllegalArgumentException("callback == null"); 5234 } 5235 5236 mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() { 5237 @Override 5238 public void onKeyguardExitResult(boolean success) { 5239 try { 5240 callback.onKeyguardExitResult(success); 5241 } catch (RemoteException e) { 5242 // Client has died, we don't care. 5243 } 5244 } 5245 }); 5246 } 5247 5248 @Override 5249 public boolean inKeyguardRestrictedInputMode() { 5250 return mPolicy.inKeyguardRestrictedKeyInputMode(); 5251 } 5252 5253 @Override 5254 public boolean isKeyguardLocked() { 5255 return mPolicy.isKeyguardLocked(); 5256 } 5257 5258 @Override 5259 public boolean isKeyguardSecure() { 5260 return mPolicy.isKeyguardSecure(); 5261 } 5262 5263 @Override 5264 public void dismissKeyguard() { 5265 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 5266 != PackageManager.PERMISSION_GRANTED) { 5267 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 5268 } 5269 synchronized(mWindowMap) { 5270 mPolicy.dismissKeyguardLw(); 5271 } 5272 } 5273 5274 @Override 5275 public void keyguardGoingAway(boolean disableWindowAnimations, 5276 boolean keyguardGoingToNotificationShade) { 5277 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD) 5278 != PackageManager.PERMISSION_GRANTED) { 5279 throw new SecurityException("Requires DISABLE_KEYGUARD permission"); 5280 } 5281 synchronized (mWindowMap) { 5282 mAnimator.mKeyguardGoingAway = true; 5283 mAnimator.mKeyguardGoingAwayToNotificationShade = keyguardGoingToNotificationShade; 5284 mAnimator.mKeyguardGoingAwayDisableWindowAnimations = disableWindowAnimations; 5285 requestTraversalLocked(); 5286 } 5287 } 5288 5289 public void keyguardWaitingForActivityDrawn() { 5290 synchronized (mWindowMap) { 5291 mKeyguardWaitingForActivityDrawn = true; 5292 } 5293 } 5294 5295 public void notifyActivityDrawnForKeyguard() { 5296 synchronized (mWindowMap) { 5297 if (mKeyguardWaitingForActivityDrawn) { 5298 mPolicy.notifyActivityDrawnForKeyguardLw(); 5299 mKeyguardWaitingForActivityDrawn = false; 5300 } 5301 } 5302 } 5303 5304 void showGlobalActions() { 5305 mPolicy.showGlobalActions(); 5306 } 5307 5308 @Override 5309 public void closeSystemDialogs(String reason) { 5310 synchronized(mWindowMap) { 5311 final int numDisplays = mDisplayContents.size(); 5312 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 5313 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); 5314 final int numWindows = windows.size(); 5315 for (int winNdx = 0; winNdx < numWindows; ++winNdx) { 5316 final WindowState w = windows.get(winNdx); 5317 if (w.mHasSurface) { 5318 try { 5319 w.mClient.closeSystemDialogs(reason); 5320 } catch (RemoteException e) { 5321 } 5322 } 5323 } 5324 } 5325 } 5326 } 5327 5328 static float fixScale(float scale) { 5329 if (scale < 0) scale = 0; 5330 else if (scale > 20) scale = 20; 5331 return Math.abs(scale); 5332 } 5333 5334 @Override 5335 public void setAnimationScale(int which, float scale) { 5336 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE, 5337 "setAnimationScale()")) { 5338 throw new SecurityException("Requires SET_ANIMATION_SCALE permission"); 5339 } 5340 5341 scale = fixScale(scale); 5342 switch (which) { 5343 case 0: mWindowAnimationScaleSetting = scale; break; 5344 case 1: mTransitionAnimationScaleSetting = scale; break; 5345 case 2: mAnimatorDurationScaleSetting = scale; break; 5346 } 5347 5348 // Persist setting 5349 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE); 5350 } 5351 5352 @Override 5353 public void setAnimationScales(float[] scales) { 5354 if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE, 5355 "setAnimationScale()")) { 5356 throw new SecurityException("Requires SET_ANIMATION_SCALE permission"); 5357 } 5358 5359 if (scales != null) { 5360 if (scales.length >= 1) { 5361 mWindowAnimationScaleSetting = fixScale(scales[0]); 5362 } 5363 if (scales.length >= 2) { 5364 mTransitionAnimationScaleSetting = fixScale(scales[1]); 5365 } 5366 if (scales.length >= 3) { 5367 mAnimatorDurationScaleSetting = fixScale(scales[2]); 5368 dispatchNewAnimatorScaleLocked(null); 5369 } 5370 } 5371 5372 // Persist setting 5373 mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE); 5374 } 5375 5376 private void setAnimatorDurationScale(float scale) { 5377 mAnimatorDurationScaleSetting = scale; 5378 ValueAnimator.setDurationScale(scale); 5379 } 5380 5381 public float getWindowAnimationScaleLocked() { 5382 return mAnimationsDisabled ? 0 : mWindowAnimationScaleSetting; 5383 } 5384 5385 public float getTransitionAnimationScaleLocked() { 5386 return mAnimationsDisabled ? 0 : mTransitionAnimationScaleSetting; 5387 } 5388 5389 @Override 5390 public float getAnimationScale(int which) { 5391 switch (which) { 5392 case 0: return mWindowAnimationScaleSetting; 5393 case 1: return mTransitionAnimationScaleSetting; 5394 case 2: return mAnimatorDurationScaleSetting; 5395 } 5396 return 0; 5397 } 5398 5399 @Override 5400 public float[] getAnimationScales() { 5401 return new float[] { mWindowAnimationScaleSetting, mTransitionAnimationScaleSetting, 5402 mAnimatorDurationScaleSetting }; 5403 } 5404 5405 @Override 5406 public float getCurrentAnimatorScale() { 5407 synchronized(mWindowMap) { 5408 return mAnimationsDisabled ? 0 : mAnimatorDurationScaleSetting; 5409 } 5410 } 5411 5412 void dispatchNewAnimatorScaleLocked(Session session) { 5413 mH.obtainMessage(H.NEW_ANIMATOR_SCALE, session).sendToTarget(); 5414 } 5415 5416 @Override 5417 public void registerPointerEventListener(PointerEventListener listener) { 5418 mPointerEventDispatcher.registerInputEventListener(listener); 5419 } 5420 5421 @Override 5422 public void unregisterPointerEventListener(PointerEventListener listener) { 5423 mPointerEventDispatcher.unregisterInputEventListener(listener); 5424 } 5425 5426 // Called by window manager policy. Not exposed externally. 5427 @Override 5428 public int getLidState() { 5429 int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, 5430 InputManagerService.SW_LID); 5431 if (sw > 0) { 5432 // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL. 5433 return LID_CLOSED; 5434 } else if (sw == 0) { 5435 // Switch state: AKEY_STATE_UP. 5436 return LID_OPEN; 5437 } else { 5438 // Switch state: AKEY_STATE_UNKNOWN. 5439 return LID_ABSENT; 5440 } 5441 } 5442 5443 // Called by window manager policy. Not exposed externally. 5444 @Override 5445 public void switchKeyboardLayout(int deviceId, int direction) { 5446 mInputManager.switchKeyboardLayout(deviceId, direction); 5447 } 5448 5449 // Called by window manager policy. Not exposed externally. 5450 @Override 5451 public void shutdown(boolean confirm) { 5452 ShutdownThread.shutdown(mContext, confirm); 5453 } 5454 5455 // Called by window manager policy. Not exposed externally. 5456 @Override 5457 public void rebootSafeMode(boolean confirm) { 5458 ShutdownThread.rebootSafeMode(mContext, confirm); 5459 } 5460 5461 public void setCurrentProfileIds(final int[] currentProfileIds) { 5462 synchronized (mWindowMap) { 5463 mCurrentProfileIds = currentProfileIds; 5464 } 5465 } 5466 5467 public void setCurrentUser(final int newUserId, final int[] currentProfileIds) { 5468 synchronized (mWindowMap) { 5469 mCurrentUserId = newUserId; 5470 mCurrentProfileIds = currentProfileIds; 5471 mAppTransition.setCurrentUser(newUserId); 5472 mPolicy.setCurrentUserLw(newUserId); 5473 5474 // Hide windows that should not be seen by the new user. 5475 final int numDisplays = mDisplayContents.size(); 5476 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 5477 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 5478 displayContent.switchUserStacks(newUserId); 5479 rebuildAppWindowListLocked(displayContent); 5480 } 5481 performLayoutAndPlaceSurfacesLocked(); 5482 } 5483 } 5484 5485 /* Called by WindowState */ 5486 boolean isCurrentProfileLocked(int userId) { 5487 if (userId == mCurrentUserId) return true; 5488 for (int i = 0; i < mCurrentProfileIds.length; i++) { 5489 if (mCurrentProfileIds[i] == userId) return true; 5490 } 5491 return false; 5492 } 5493 5494 public void enableScreenAfterBoot() { 5495 synchronized(mWindowMap) { 5496 if (DEBUG_BOOT) { 5497 RuntimeException here = new RuntimeException("here"); 5498 here.fillInStackTrace(); 5499 Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled 5500 + " mForceDisplayEnabled=" + mForceDisplayEnabled 5501 + " mShowingBootMessages=" + mShowingBootMessages 5502 + " mSystemBooted=" + mSystemBooted, here); 5503 } 5504 if (mSystemBooted) { 5505 return; 5506 } 5507 mSystemBooted = true; 5508 hideBootMessagesLocked(); 5509 // If the screen still doesn't come up after 30 seconds, give 5510 // up and turn it on. 5511 mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000); 5512 } 5513 5514 mPolicy.systemBooted(); 5515 5516 performEnableScreen(); 5517 } 5518 5519 @Override 5520 public void enableScreenIfNeeded() { 5521 synchronized (mWindowMap) { 5522 enableScreenIfNeededLocked(); 5523 } 5524 } 5525 5526 void enableScreenIfNeededLocked() { 5527 if (DEBUG_BOOT) { 5528 RuntimeException here = new RuntimeException("here"); 5529 here.fillInStackTrace(); 5530 Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled 5531 + " mForceDisplayEnabled=" + mForceDisplayEnabled 5532 + " mShowingBootMessages=" + mShowingBootMessages 5533 + " mSystemBooted=" + mSystemBooted, here); 5534 } 5535 if (mDisplayEnabled) { 5536 return; 5537 } 5538 if (!mSystemBooted && !mShowingBootMessages) { 5539 return; 5540 } 5541 mH.sendEmptyMessage(H.ENABLE_SCREEN); 5542 } 5543 5544 public void performBootTimeout() { 5545 synchronized(mWindowMap) { 5546 if (mDisplayEnabled) { 5547 return; 5548 } 5549 Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled"); 5550 mForceDisplayEnabled = true; 5551 } 5552 performEnableScreen(); 5553 } 5554 5555 public void performEnableScreen() { 5556 synchronized(mWindowMap) { 5557 if (DEBUG_BOOT) { 5558 RuntimeException here = new RuntimeException("here"); 5559 here.fillInStackTrace(); 5560 Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled 5561 + " mForceDisplayEnabled=" + mForceDisplayEnabled 5562 + " mShowingBootMessages=" + mShowingBootMessages 5563 + " mSystemBooted=" + mSystemBooted 5564 + " mOnlyCore=" + mOnlyCore, here); 5565 } 5566 if (mDisplayEnabled) { 5567 return; 5568 } 5569 if (!mSystemBooted && !mShowingBootMessages) { 5570 return; 5571 } 5572 5573 if (!mForceDisplayEnabled) { 5574 // Don't enable the screen until all existing windows 5575 // have been drawn. 5576 boolean haveBootMsg = false; 5577 boolean haveApp = false; 5578 // if the wallpaper service is disabled on the device, we're never going to have 5579 // wallpaper, don't bother waiting for it 5580 boolean haveWallpaper = false; 5581 boolean wallpaperEnabled = mContext.getResources().getBoolean( 5582 com.android.internal.R.bool.config_enableWallpaperService) 5583 && !mOnlyCore; 5584 boolean haveKeyguard = true; 5585 // TODO(multidisplay): Expand to all displays? 5586 final WindowList windows = getDefaultWindowListLocked(); 5587 final int N = windows.size(); 5588 for (int i=0; i<N; i++) { 5589 WindowState w = windows.get(i); 5590 if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) { 5591 return; 5592 } 5593 if (w.isDrawnLw()) { 5594 if (w.mAttrs.type == TYPE_BOOT_PROGRESS) { 5595 haveBootMsg = true; 5596 } else if (w.mAttrs.type == TYPE_APPLICATION) { 5597 haveApp = true; 5598 } else if (w.mAttrs.type == TYPE_WALLPAPER) { 5599 haveWallpaper = true; 5600 } else if (w.mAttrs.type == TYPE_STATUS_BAR) { 5601 haveKeyguard = mPolicy.isKeyguardDrawnLw(); 5602 } 5603 } 5604 } 5605 5606 if (DEBUG_SCREEN_ON || DEBUG_BOOT) { 5607 Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages 5608 + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp 5609 + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled 5610 + " haveKeyguard=" + haveKeyguard); 5611 } 5612 5613 // If we are turning on the screen to show the boot message, 5614 // don't do it until the boot message is actually displayed. 5615 if (!mSystemBooted && !haveBootMsg) { 5616 return; 5617 } 5618 5619 // If we are turning on the screen after the boot is completed 5620 // normally, don't do so until we have the application and 5621 // wallpaper. 5622 if (mSystemBooted && ((!haveApp && !haveKeyguard) || 5623 (wallpaperEnabled && !haveWallpaper))) { 5624 return; 5625 } 5626 } 5627 5628 mDisplayEnabled = true; 5629 if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!"); 5630 if (false) { 5631 StringWriter sw = new StringWriter(); 5632 PrintWriter pw = new FastPrintWriter(sw, false, 1024); 5633 this.dump(null, pw, null); 5634 pw.flush(); 5635 Slog.i(TAG, sw.toString()); 5636 } 5637 try { 5638 IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); 5639 if (surfaceFlinger != null) { 5640 //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!"); 5641 Parcel data = Parcel.obtain(); 5642 data.writeInterfaceToken("android.ui.ISurfaceComposer"); 5643 surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED 5644 data, null, 0); 5645 data.recycle(); 5646 } 5647 } catch (RemoteException ex) { 5648 Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!"); 5649 } 5650 5651 // Enable input dispatch. 5652 mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled); 5653 } 5654 5655 mPolicy.enableScreenAfterBoot(); 5656 5657 // Make sure the last requested orientation has been applied. 5658 updateRotationUnchecked(false, false); 5659 } 5660 5661 public void showBootMessage(final CharSequence msg, final boolean always) { 5662 boolean first = false; 5663 synchronized(mWindowMap) { 5664 if (DEBUG_BOOT) { 5665 RuntimeException here = new RuntimeException("here"); 5666 here.fillInStackTrace(); 5667 Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always 5668 + " mAllowBootMessages=" + mAllowBootMessages 5669 + " mShowingBootMessages=" + mShowingBootMessages 5670 + " mSystemBooted=" + mSystemBooted, here); 5671 } 5672 if (!mAllowBootMessages) { 5673 return; 5674 } 5675 if (!mShowingBootMessages) { 5676 if (!always) { 5677 return; 5678 } 5679 first = true; 5680 } 5681 if (mSystemBooted) { 5682 return; 5683 } 5684 mShowingBootMessages = true; 5685 mPolicy.showBootMessage(msg, always); 5686 } 5687 if (first) { 5688 performEnableScreen(); 5689 } 5690 } 5691 5692 public void hideBootMessagesLocked() { 5693 if (DEBUG_BOOT) { 5694 RuntimeException here = new RuntimeException("here"); 5695 here.fillInStackTrace(); 5696 Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled 5697 + " mForceDisplayEnabled=" + mForceDisplayEnabled 5698 + " mShowingBootMessages=" + mShowingBootMessages 5699 + " mSystemBooted=" + mSystemBooted, here); 5700 } 5701 if (mShowingBootMessages) { 5702 mShowingBootMessages = false; 5703 mPolicy.hideBootMessages(); 5704 } 5705 } 5706 5707 @Override 5708 public void setInTouchMode(boolean mode) { 5709 synchronized(mWindowMap) { 5710 mInTouchMode = mode; 5711 } 5712 } 5713 5714 public void showCircularDisplayMaskIfNeeded() { 5715 // we're fullscreen and not hosted in an ActivityView 5716 if (mContext.getResources().getBoolean( 5717 com.android.internal.R.bool.config_windowIsRound) 5718 && mContext.getResources().getBoolean( 5719 com.android.internal.R.bool.config_windowShowCircularMask)) { 5720 mH.sendMessage(mH.obtainMessage(H.SHOW_DISPLAY_MASK)); 5721 } 5722 } 5723 5724 public void showCircularMask() { 5725 synchronized(mWindowMap) { 5726 5727 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 5728 ">>> OPEN TRANSACTION showDisplayMask"); 5729 SurfaceControl.openTransaction(); 5730 try { 5731 // TODO(multi-display): support multiple displays 5732 if (mCircularDisplayMask == null) { 5733 int screenOffset = (int) mContext.getResources().getDimensionPixelSize( 5734 com.android.internal.R.dimen.circular_display_mask_offset); 5735 5736 mCircularDisplayMask = new CircularDisplayMask( 5737 getDefaultDisplayContentLocked().getDisplay(), 5738 mFxSession, 5739 mPolicy.windowTypeToLayerLw( 5740 WindowManager.LayoutParams.TYPE_POINTER) 5741 * TYPE_LAYER_MULTIPLIER + 10, screenOffset); 5742 } 5743 mCircularDisplayMask.setVisibility(true); 5744 } finally { 5745 SurfaceControl.closeTransaction(); 5746 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 5747 "<<< CLOSE TRANSACTION showDisplayMask"); 5748 } 5749 } 5750 } 5751 5752 // TODO: more accounting of which pid(s) turned it on, keep count, 5753 // only allow disables from pids which have count on, etc. 5754 @Override 5755 public void showStrictModeViolation(boolean on) { 5756 int pid = Binder.getCallingPid(); 5757 mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid)); 5758 } 5759 5760 private void showStrictModeViolation(int arg, int pid) { 5761 final boolean on = arg != 0; 5762 synchronized(mWindowMap) { 5763 // Ignoring requests to enable the red border from clients 5764 // which aren't on screen. (e.g. Broadcast Receivers in 5765 // the background..) 5766 if (on) { 5767 boolean isVisible = false; 5768 final int numDisplays = mDisplayContents.size(); 5769 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 5770 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); 5771 final int numWindows = windows.size(); 5772 for (int winNdx = 0; winNdx < numWindows; ++winNdx) { 5773 final WindowState ws = windows.get(winNdx); 5774 if (ws.mSession.mPid == pid && ws.isVisibleLw()) { 5775 isVisible = true; 5776 break; 5777 } 5778 } 5779 } 5780 if (!isVisible) { 5781 return; 5782 } 5783 } 5784 5785 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 5786 ">>> OPEN TRANSACTION showStrictModeViolation"); 5787 SurfaceControl.openTransaction(); 5788 try { 5789 // TODO(multi-display): support multiple displays 5790 if (mStrictModeFlash == null) { 5791 mStrictModeFlash = new StrictModeFlash( 5792 getDefaultDisplayContentLocked().getDisplay(), mFxSession); 5793 } 5794 mStrictModeFlash.setVisibility(on); 5795 } finally { 5796 SurfaceControl.closeTransaction(); 5797 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 5798 "<<< CLOSE TRANSACTION showStrictModeViolation"); 5799 } 5800 } 5801 } 5802 5803 @Override 5804 public void setStrictModeVisualIndicatorPreference(String value) { 5805 SystemProperties.set(StrictMode.VISUAL_PROPERTY, value); 5806 } 5807 5808 private static void convertCropForSurfaceFlinger(Rect crop, int rot, int dw, int dh) { 5809 if (rot == Surface.ROTATION_90) { 5810 final int tmp = crop.top; 5811 crop.top = dw - crop.right; 5812 crop.right = crop.bottom; 5813 crop.bottom = dw - crop.left; 5814 crop.left = tmp; 5815 } else if (rot == Surface.ROTATION_180) { 5816 int tmp = crop.top; 5817 crop.top = dh - crop.bottom; 5818 crop.bottom = dh - tmp; 5819 tmp = crop.right; 5820 crop.right = dw - crop.left; 5821 crop.left = dw - tmp; 5822 } else if (rot == Surface.ROTATION_270) { 5823 final int tmp = crop.top; 5824 crop.top = crop.left; 5825 crop.left = dh - crop.bottom; 5826 crop.bottom = crop.right; 5827 crop.right = dh - tmp; 5828 } 5829 } 5830 5831 /** 5832 * Takes a snapshot of the screen. In landscape mode this grabs the whole screen. 5833 * In portrait mode, it grabs the upper region of the screen based on the vertical dimension 5834 * of the target image. 5835 * 5836 * @param displayId the Display to take a screenshot of. 5837 * @param width the width of the target bitmap 5838 * @param height the height of the target bitmap 5839 * @param force565 if true the returned bitmap will be RGB_565, otherwise it 5840 * will be the same config as the surface 5841 */ 5842 @Override 5843 public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, 5844 int height, boolean force565) { 5845 if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 5846 "screenshotApplications()")) { 5847 throw new SecurityException("Requires READ_FRAME_BUFFER permission"); 5848 } 5849 5850 final DisplayContent displayContent = getDisplayContentLocked(displayId); 5851 if (displayContent == null) { 5852 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken 5853 + ": returning null. No Display for displayId=" + displayId); 5854 return null; 5855 } 5856 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 5857 int dw = displayInfo.logicalWidth; 5858 int dh = displayInfo.logicalHeight; 5859 if (dw == 0 || dh == 0) { 5860 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken 5861 + ": returning null. logical widthxheight=" + dw + "x" + dh); 5862 return null; 5863 } 5864 5865 Bitmap rawss = null; 5866 5867 int maxLayer = 0; 5868 final Rect frame = new Rect(); 5869 final Rect stackBounds = new Rect(); 5870 5871 float scale = 0; 5872 int rot = Surface.ROTATION_0; 5873 5874 boolean screenshotReady; 5875 int minLayer; 5876 if (appToken == null) { 5877 screenshotReady = true; 5878 minLayer = 0; 5879 } else { 5880 screenshotReady = false; 5881 minLayer = Integer.MAX_VALUE; 5882 } 5883 5884 int retryCount = 0; 5885 WindowState appWin = null; 5886 5887 final boolean appIsImTarget = mInputMethodTarget != null 5888 && mInputMethodTarget.mAppToken != null 5889 && mInputMethodTarget.mAppToken.appToken != null 5890 && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken; 5891 5892 final int aboveAppLayer = (mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1) 5893 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET; 5894 5895 while (true) { 5896 if (retryCount++ > 0) { 5897 try { 5898 Thread.sleep(100); 5899 } catch (InterruptedException e) { 5900 } 5901 } 5902 synchronized(mWindowMap) { 5903 // Figure out the part of the screen that is actually the app. 5904 appWin = null; 5905 final WindowList windows = displayContent.getWindowList(); 5906 for (int i = windows.size() - 1; i >= 0; i--) { 5907 WindowState ws = windows.get(i); 5908 if (!ws.mHasSurface) { 5909 continue; 5910 } 5911 if (ws.mLayer >= aboveAppLayer) { 5912 continue; 5913 } 5914 if (ws.mIsImWindow) { 5915 if (!appIsImTarget) { 5916 continue; 5917 } 5918 } else if (ws.mIsWallpaper) { 5919 // Fall through. 5920 } else if (appToken != null) { 5921 if (ws.mAppToken == null || ws.mAppToken.token != appToken) { 5922 // This app window is of no interest if it is not associated with the 5923 // screenshot app. 5924 continue; 5925 } 5926 appWin = ws; 5927 } 5928 5929 // Include this window. 5930 5931 final WindowStateAnimator winAnim = ws.mWinAnimator; 5932 if (maxLayer < winAnim.mSurfaceLayer) { 5933 maxLayer = winAnim.mSurfaceLayer; 5934 } 5935 if (minLayer > winAnim.mSurfaceLayer) { 5936 minLayer = winAnim.mSurfaceLayer; 5937 } 5938 5939 // Don't include wallpaper in bounds calculation 5940 if (!ws.mIsWallpaper) { 5941 final Rect wf = ws.mFrame; 5942 final Rect cr = ws.mContentInsets; 5943 int left = wf.left + cr.left; 5944 int top = wf.top + cr.top; 5945 int right = wf.right - cr.right; 5946 int bottom = wf.bottom - cr.bottom; 5947 frame.union(left, top, right, bottom); 5948 ws.getStackBounds(stackBounds); 5949 frame.intersect(stackBounds); 5950 } 5951 5952 if (ws.mAppToken != null && ws.mAppToken.token == appToken && 5953 ws.isDisplayedLw()) { 5954 screenshotReady = true; 5955 } 5956 } 5957 5958 if (appToken != null && appWin == null) { 5959 // Can't find a window to snapshot. 5960 if (DEBUG_SCREENSHOT) Slog.i(TAG, 5961 "Screenshot: Couldn't find a surface matching " + appToken); 5962 return null; 5963 } 5964 5965 if (!screenshotReady) { 5966 if (retryCount > MAX_SCREENSHOT_RETRIES) { 5967 Slog.i(TAG, "Screenshot max retries " + retryCount + " of " + appToken + 5968 " appWin=" + (appWin == null ? "null" : (appWin + " drawState=" + 5969 appWin.mWinAnimator.mDrawState))); 5970 return null; 5971 } 5972 5973 // Delay and hope that window gets drawn. 5974 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken 5975 + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState); 5976 continue; 5977 } 5978 5979 // Screenshot is ready to be taken. Everything from here below will continue 5980 // through the bottom of the loop and return a value. We only stay in the loop 5981 // because we don't want to release the mWindowMap lock until the screenshot is 5982 // taken. 5983 5984 if (maxLayer == 0) { 5985 if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken 5986 + ": returning null maxLayer=" + maxLayer); 5987 return null; 5988 } 5989 5990 // Constrain frame to the screen size. 5991 frame.intersect(0, 0, dw, dh); 5992 5993 // Tell surface flinger what part of the image to crop. Take the top 5994 // right part of the application, and crop the larger dimension to fit. 5995 Rect crop = new Rect(frame); 5996 if (width / (float) frame.width() < height / (float) frame.height()) { 5997 int cropWidth = (int)((float)width / (float)height * frame.height()); 5998 crop.right = crop.left + cropWidth; 5999 } else { 6000 int cropHeight = (int)((float)height / (float)width * frame.width()); 6001 crop.bottom = crop.top + cropHeight; 6002 } 6003 6004 // The screenshot API does not apply the current screen rotation. 6005 rot = getDefaultDisplayContentLocked().getDisplay().getRotation(); 6006 if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { 6007 final int tmp = width; 6008 width = height; 6009 height = tmp; 6010 rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90; 6011 } 6012 6013 // Surfaceflinger is not aware of orientation, so convert our logical 6014 // crop to surfaceflinger's portrait orientation. 6015 convertCropForSurfaceFlinger(crop, rot, dw, dh); 6016 6017 if (DEBUG_SCREENSHOT) { 6018 Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to " 6019 + maxLayer + " appToken=" + appToken); 6020 for (int i = 0; i < windows.size(); i++) { 6021 WindowState win = windows.get(i); 6022 Slog.i(TAG, win + ": " + win.mLayer 6023 + " animLayer=" + win.mWinAnimator.mAnimLayer 6024 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer); 6025 } 6026 } 6027 6028 ScreenRotationAnimation screenRotationAnimation = 6029 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY); 6030 final boolean inRotation = screenRotationAnimation != null && 6031 screenRotationAnimation.isAnimating(); 6032 if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG, 6033 "Taking screenshot while rotating"); 6034 6035 rawss = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer, 6036 inRotation); 6037 if (rawss == null) { 6038 Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh 6039 + ") to layer " + maxLayer); 6040 return null; 6041 } 6042 } 6043 6044 break; 6045 } 6046 6047 Bitmap bm = Bitmap.createBitmap(width, height, force565 ? 6048 Config.RGB_565 : rawss.getConfig()); 6049 if (DEBUG_SCREENSHOT) { 6050 bm.eraseColor(0xFF000000); 6051 } 6052 Matrix matrix = new Matrix(); 6053 ScreenRotationAnimation.createRotationMatrix(rot, width, height, matrix); 6054 Canvas canvas = new Canvas(bm); 6055 canvas.drawBitmap(rawss, matrix, null); 6056 canvas.setBitmap(null); 6057 6058 if (DEBUG_SCREENSHOT) { 6059 // TEST IF IT's ALL BLACK 6060 int[] buffer = new int[bm.getWidth() * bm.getHeight()]; 6061 bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight()); 6062 boolean allBlack = true; 6063 final int firstColor = buffer[0]; 6064 for (int i = 0; i < buffer.length; i++) { 6065 if (buffer[i] != firstColor) { 6066 allBlack = false; 6067 break; 6068 } 6069 } 6070 if (allBlack) { 6071 Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" + 6072 Integer.toHexString(firstColor) + ")! mSurfaceLayer=" + 6073 (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") + 6074 " minLayer=" + minLayer + " maxLayer=" + maxLayer); 6075 } 6076 } 6077 6078 rawss.recycle(); 6079 6080 return bm; 6081 } 6082 6083 /** 6084 * Freeze rotation changes. (Enable "rotation lock".) 6085 * Persists across reboots. 6086 * @param rotation The desired rotation to freeze to, or -1 to use the 6087 * current rotation. 6088 */ 6089 @Override 6090 public void freezeRotation(int rotation) { 6091 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, 6092 "freezeRotation()")) { 6093 throw new SecurityException("Requires SET_ORIENTATION permission"); 6094 } 6095 if (rotation < -1 || rotation > Surface.ROTATION_270) { 6096 throw new IllegalArgumentException("Rotation argument must be -1 or a valid " 6097 + "rotation constant."); 6098 } 6099 6100 if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation); 6101 6102 long origId = Binder.clearCallingIdentity(); 6103 try { 6104 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, 6105 rotation == -1 ? mRotation : rotation); 6106 } finally { 6107 Binder.restoreCallingIdentity(origId); 6108 } 6109 6110 updateRotationUnchecked(false, false); 6111 } 6112 6113 /** 6114 * Thaw rotation changes. (Disable "rotation lock".) 6115 * Persists across reboots. 6116 */ 6117 @Override 6118 public void thawRotation() { 6119 if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, 6120 "thawRotation()")) { 6121 throw new SecurityException("Requires SET_ORIENTATION permission"); 6122 } 6123 6124 if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation); 6125 6126 long origId = Binder.clearCallingIdentity(); 6127 try { 6128 mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 6129 777); // rot not used 6130 } finally { 6131 Binder.restoreCallingIdentity(origId); 6132 } 6133 6134 updateRotationUnchecked(false, false); 6135 } 6136 6137 /** 6138 * Recalculate the current rotation. 6139 * 6140 * Called by the window manager policy whenever the state of the system changes 6141 * such that the current rotation might need to be updated, such as when the 6142 * device is docked or rotated into a new posture. 6143 */ 6144 @Override 6145 public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) { 6146 updateRotationUnchecked(alwaysSendConfiguration, forceRelayout); 6147 } 6148 6149 /** 6150 * Temporarily pauses rotation changes until resumed. 6151 * 6152 * This can be used to prevent rotation changes from occurring while the user is 6153 * performing certain operations, such as drag and drop. 6154 * 6155 * This call nests and must be matched by an equal number of calls to 6156 * {@link #resumeRotationLocked}. 6157 */ 6158 void pauseRotationLocked() { 6159 mDeferredRotationPauseCount += 1; 6160 } 6161 6162 /** 6163 * Resumes normal rotation changes after being paused. 6164 */ 6165 void resumeRotationLocked() { 6166 if (mDeferredRotationPauseCount > 0) { 6167 mDeferredRotationPauseCount -= 1; 6168 if (mDeferredRotationPauseCount == 0) { 6169 boolean changed = updateRotationUncheckedLocked(false); 6170 if (changed) { 6171 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 6172 } 6173 } 6174 } 6175 } 6176 6177 public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) { 6178 if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked(" 6179 + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")"); 6180 6181 long origId = Binder.clearCallingIdentity(); 6182 boolean changed; 6183 synchronized(mWindowMap) { 6184 changed = updateRotationUncheckedLocked(false); 6185 if (!changed || forceRelayout) { 6186 getDefaultDisplayContentLocked().layoutNeeded = true; 6187 performLayoutAndPlaceSurfacesLocked(); 6188 } 6189 } 6190 6191 if (changed || alwaysSendConfiguration) { 6192 sendNewConfiguration(); 6193 } 6194 6195 Binder.restoreCallingIdentity(origId); 6196 } 6197 6198 // TODO(multidisplay): Rotate any display? 6199 /** 6200 * Updates the current rotation. 6201 * 6202 * Returns true if the rotation has been changed. In this case YOU 6203 * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN. 6204 */ 6205 public boolean updateRotationUncheckedLocked(boolean inTransaction) { 6206 if (mDeferredRotationPauseCount > 0) { 6207 // Rotation updates have been paused temporarily. Defer the update until 6208 // updates have been resumed. 6209 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused."); 6210 return false; 6211 } 6212 6213 ScreenRotationAnimation screenRotationAnimation = 6214 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY); 6215 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) { 6216 // Rotation updates cannot be performed while the previous rotation change 6217 // animation is still in progress. Skip this update. We will try updating 6218 // again after the animation is finished and the display is unfrozen. 6219 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress."); 6220 return false; 6221 } 6222 6223 if (!mDisplayEnabled) { 6224 // No point choosing a rotation if the display is not enabled. 6225 if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled."); 6226 return false; 6227 } 6228 6229 // TODO: Implement forced rotation changes. 6230 // Set mAltOrientation to indicate that the application is receiving 6231 // an orientation that has different metrics than it expected. 6232 // eg. Portrait instead of Landscape. 6233 6234 int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation); 6235 boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw( 6236 mForcedAppOrientation, rotation); 6237 6238 if (DEBUG_ORIENTATION) { 6239 Slog.v(TAG, "Application requested orientation " 6240 + mForcedAppOrientation + ", got rotation " + rotation 6241 + " which has " + (altOrientation ? "incompatible" : "compatible") 6242 + " metrics"); 6243 } 6244 6245 if (mRotation == rotation && mAltOrientation == altOrientation) { 6246 // No change. 6247 return false; 6248 } 6249 6250 if (DEBUG_ORIENTATION) { 6251 Slog.v(TAG, 6252 "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "") 6253 + " from " + mRotation + (mAltOrientation ? " (alt)" : "") 6254 + ", forceApp=" + mForcedAppOrientation); 6255 } 6256 6257 mRotation = rotation; 6258 mAltOrientation = altOrientation; 6259 mPolicy.setRotationLw(mRotation); 6260 6261 mWindowsFreezingScreen = true; 6262 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); 6263 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION); 6264 mWaitingForConfig = true; 6265 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 6266 displayContent.layoutNeeded = true; 6267 final int[] anim = new int[2]; 6268 if (displayContent.isDimming()) { 6269 anim[0] = anim[1] = 0; 6270 } else { 6271 mPolicy.selectRotationAnimationLw(anim); 6272 } 6273 startFreezingDisplayLocked(inTransaction, anim[0], anim[1]); 6274 // startFreezingDisplayLocked can reset the ScreenRotationAnimation. 6275 screenRotationAnimation = 6276 mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY); 6277 6278 // We need to update our screen size information to match the new 6279 // rotation. Note that this is redundant with the later call to 6280 // sendNewConfiguration() that must be called after this function 6281 // returns... however we need to do the screen size part of that 6282 // before then so we have the correct size to use when initializing 6283 // the rotation animation for the new rotation. 6284 computeScreenConfigurationLocked(null); 6285 6286 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 6287 if (!inTransaction) { 6288 if (SHOW_TRANSACTIONS) { 6289 Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked"); 6290 } 6291 SurfaceControl.openTransaction(); 6292 } 6293 try { 6294 // NOTE: We disable the rotation in the emulator because 6295 // it doesn't support hardware OpenGL emulation yet. 6296 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null 6297 && screenRotationAnimation.hasScreenshot()) { 6298 if (screenRotationAnimation.setRotationInTransaction( 6299 rotation, mFxSession, 6300 MAX_ANIMATION_DURATION, getTransitionAnimationScaleLocked(), 6301 displayInfo.logicalWidth, displayInfo.logicalHeight)) { 6302 scheduleAnimationLocked(); 6303 } 6304 } 6305 6306 mDisplayManagerInternal.performTraversalInTransactionFromWindowManager(); 6307 } finally { 6308 if (!inTransaction) { 6309 SurfaceControl.closeTransaction(); 6310 if (SHOW_LIGHT_TRANSACTIONS) { 6311 Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked"); 6312 } 6313 } 6314 } 6315 6316 final WindowList windows = displayContent.getWindowList(); 6317 for (int i = windows.size() - 1; i >= 0; i--) { 6318 WindowState w = windows.get(i); 6319 if (w.mHasSurface) { 6320 if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w); 6321 w.mOrientationChanging = true; 6322 mInnerFields.mOrientationChangeComplete = false; 6323 } 6324 w.mLastFreezeDuration = 0; 6325 } 6326 6327 for (int i=mRotationWatchers.size()-1; i>=0; i--) { 6328 try { 6329 mRotationWatchers.get(i).watcher.onRotationChanged(rotation); 6330 } catch (RemoteException e) { 6331 } 6332 } 6333 6334 //TODO (multidisplay): Magnification is supported only for the default display. 6335 if (mAccessibilityController != null 6336 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) { 6337 mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation); 6338 } 6339 6340 return true; 6341 } 6342 6343 @Override 6344 public int getRotation() { 6345 return mRotation; 6346 } 6347 6348 @Override 6349 public boolean isRotationFrozen() { 6350 return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED; 6351 } 6352 6353 @Override 6354 public int watchRotation(IRotationWatcher watcher) { 6355 final IBinder watcherBinder = watcher.asBinder(); 6356 IBinder.DeathRecipient dr = new IBinder.DeathRecipient() { 6357 @Override 6358 public void binderDied() { 6359 synchronized (mWindowMap) { 6360 for (int i=0; i<mRotationWatchers.size(); i++) { 6361 if (watcherBinder == mRotationWatchers.get(i).watcher.asBinder()) { 6362 RotationWatcher removed = mRotationWatchers.remove(i); 6363 IBinder binder = removed.watcher.asBinder(); 6364 if (binder != null) { 6365 binder.unlinkToDeath(this, 0); 6366 } 6367 i--; 6368 } 6369 } 6370 } 6371 } 6372 }; 6373 6374 synchronized (mWindowMap) { 6375 try { 6376 watcher.asBinder().linkToDeath(dr, 0); 6377 mRotationWatchers.add(new RotationWatcher(watcher, dr)); 6378 } catch (RemoteException e) { 6379 // Client died, no cleanup needed. 6380 } 6381 6382 return mRotation; 6383 } 6384 } 6385 6386 @Override 6387 public void removeRotationWatcher(IRotationWatcher watcher) { 6388 final IBinder watcherBinder = watcher.asBinder(); 6389 synchronized (mWindowMap) { 6390 for (int i=0; i<mRotationWatchers.size(); i++) { 6391 RotationWatcher rotationWatcher = mRotationWatchers.get(i); 6392 if (watcherBinder == rotationWatcher.watcher.asBinder()) { 6393 RotationWatcher removed = mRotationWatchers.remove(i); 6394 IBinder binder = removed.watcher.asBinder(); 6395 if (binder != null) { 6396 binder.unlinkToDeath(removed.deathRecipient, 0); 6397 } 6398 i--; 6399 } 6400 } 6401 } 6402 } 6403 6404 /** 6405 * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact 6406 * theme attribute) on devices that feature a physical options menu key attempt to position 6407 * their menu panel window along the edge of the screen nearest the physical menu key. 6408 * This lowers the travel distance between invoking the menu panel and selecting 6409 * a menu option. 6410 * 6411 * This method helps control where that menu is placed. Its current implementation makes 6412 * assumptions about the menu key and its relationship to the screen based on whether 6413 * the device's natural orientation is portrait (width < height) or landscape. 6414 * 6415 * The menu key is assumed to be located along the bottom edge of natural-portrait 6416 * devices and along the right edge of natural-landscape devices. If these assumptions 6417 * do not hold for the target device, this method should be changed to reflect that. 6418 * 6419 * @return A {@link Gravity} value for placing the options menu window 6420 */ 6421 @Override 6422 public int getPreferredOptionsPanelGravity() { 6423 synchronized (mWindowMap) { 6424 final int rotation = getRotation(); 6425 6426 // TODO(multidisplay): Assume that such devices physical keys are on the main screen. 6427 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 6428 if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) { 6429 // On devices with a natural orientation of portrait 6430 switch (rotation) { 6431 default: 6432 case Surface.ROTATION_0: 6433 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 6434 case Surface.ROTATION_90: 6435 return Gravity.RIGHT | Gravity.BOTTOM; 6436 case Surface.ROTATION_180: 6437 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 6438 case Surface.ROTATION_270: 6439 return Gravity.START | Gravity.BOTTOM; 6440 } 6441 } 6442 6443 // On devices with a natural orientation of landscape 6444 switch (rotation) { 6445 default: 6446 case Surface.ROTATION_0: 6447 return Gravity.RIGHT | Gravity.BOTTOM; 6448 case Surface.ROTATION_90: 6449 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 6450 case Surface.ROTATION_180: 6451 return Gravity.START | Gravity.BOTTOM; 6452 case Surface.ROTATION_270: 6453 return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; 6454 } 6455 } 6456 } 6457 6458 /** 6459 * Starts the view server on the specified port. 6460 * 6461 * @param port The port to listener to. 6462 * 6463 * @return True if the server was successfully started, false otherwise. 6464 * 6465 * @see com.android.server.wm.ViewServer 6466 * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT 6467 */ 6468 @Override 6469 public boolean startViewServer(int port) { 6470 if (isSystemSecure()) { 6471 return false; 6472 } 6473 6474 if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) { 6475 return false; 6476 } 6477 6478 if (port < 1024) { 6479 return false; 6480 } 6481 6482 if (mViewServer != null) { 6483 if (!mViewServer.isRunning()) { 6484 try { 6485 return mViewServer.start(); 6486 } catch (IOException e) { 6487 Slog.w(TAG, "View server did not start"); 6488 } 6489 } 6490 return false; 6491 } 6492 6493 try { 6494 mViewServer = new ViewServer(this, port); 6495 return mViewServer.start(); 6496 } catch (IOException e) { 6497 Slog.w(TAG, "View server did not start"); 6498 } 6499 return false; 6500 } 6501 6502 private boolean isSystemSecure() { 6503 return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) && 6504 "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 6505 } 6506 6507 /** 6508 * Stops the view server if it exists. 6509 * 6510 * @return True if the server stopped, false if it wasn't started or 6511 * couldn't be stopped. 6512 * 6513 * @see com.android.server.wm.ViewServer 6514 */ 6515 @Override 6516 public boolean stopViewServer() { 6517 if (isSystemSecure()) { 6518 return false; 6519 } 6520 6521 if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) { 6522 return false; 6523 } 6524 6525 if (mViewServer != null) { 6526 return mViewServer.stop(); 6527 } 6528 return false; 6529 } 6530 6531 /** 6532 * Indicates whether the view server is running. 6533 * 6534 * @return True if the server is running, false otherwise. 6535 * 6536 * @see com.android.server.wm.ViewServer 6537 */ 6538 @Override 6539 public boolean isViewServerRunning() { 6540 if (isSystemSecure()) { 6541 return false; 6542 } 6543 6544 if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) { 6545 return false; 6546 } 6547 6548 return mViewServer != null && mViewServer.isRunning(); 6549 } 6550 6551 /** 6552 * Lists all availble windows in the system. The listing is written in the 6553 * specified Socket's output stream with the following syntax: 6554 * windowHashCodeInHexadecimal windowName 6555 * Each line of the ouput represents a different window. 6556 * 6557 * @param client The remote client to send the listing to. 6558 * @return False if an error occured, true otherwise. 6559 */ 6560 boolean viewServerListWindows(Socket client) { 6561 if (isSystemSecure()) { 6562 return false; 6563 } 6564 6565 boolean result = true; 6566 6567 WindowList windows = new WindowList(); 6568 synchronized (mWindowMap) { 6569 //noinspection unchecked 6570 final int numDisplays = mDisplayContents.size(); 6571 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 6572 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 6573 windows.addAll(displayContent.getWindowList()); 6574 } 6575 } 6576 6577 BufferedWriter out = null; 6578 6579 // Any uncaught exception will crash the system process 6580 try { 6581 OutputStream clientStream = client.getOutputStream(); 6582 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024); 6583 6584 final int count = windows.size(); 6585 for (int i = 0; i < count; i++) { 6586 final WindowState w = windows.get(i); 6587 out.write(Integer.toHexString(System.identityHashCode(w))); 6588 out.write(' '); 6589 out.append(w.mAttrs.getTitle()); 6590 out.write('\n'); 6591 } 6592 6593 out.write("DONE.\n"); 6594 out.flush(); 6595 } catch (Exception e) { 6596 result = false; 6597 } finally { 6598 if (out != null) { 6599 try { 6600 out.close(); 6601 } catch (IOException e) { 6602 result = false; 6603 } 6604 } 6605 } 6606 6607 return result; 6608 } 6609 6610 // TODO(multidisplay): Extend to multiple displays. 6611 /** 6612 * Returns the focused window in the following format: 6613 * windowHashCodeInHexadecimal windowName 6614 * 6615 * @param client The remote client to send the listing to. 6616 * @return False if an error occurred, true otherwise. 6617 */ 6618 boolean viewServerGetFocusedWindow(Socket client) { 6619 if (isSystemSecure()) { 6620 return false; 6621 } 6622 6623 boolean result = true; 6624 6625 WindowState focusedWindow = getFocusedWindow(); 6626 6627 BufferedWriter out = null; 6628 6629 // Any uncaught exception will crash the system process 6630 try { 6631 OutputStream clientStream = client.getOutputStream(); 6632 out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024); 6633 6634 if(focusedWindow != null) { 6635 out.write(Integer.toHexString(System.identityHashCode(focusedWindow))); 6636 out.write(' '); 6637 out.append(focusedWindow.mAttrs.getTitle()); 6638 } 6639 out.write('\n'); 6640 out.flush(); 6641 } catch (Exception e) { 6642 result = false; 6643 } finally { 6644 if (out != null) { 6645 try { 6646 out.close(); 6647 } catch (IOException e) { 6648 result = false; 6649 } 6650 } 6651 } 6652 6653 return result; 6654 } 6655 6656 /** 6657 * Sends a command to a target window. The result of the command, if any, will be 6658 * written in the output stream of the specified socket. 6659 * 6660 * The parameters must follow this syntax: 6661 * windowHashcode extra 6662 * 6663 * Where XX is the length in characeters of the windowTitle. 6664 * 6665 * The first parameter is the target window. The window with the specified hashcode 6666 * will be the target. If no target can be found, nothing happens. The extra parameters 6667 * will be delivered to the target window and as parameters to the command itself. 6668 * 6669 * @param client The remote client to sent the result, if any, to. 6670 * @param command The command to execute. 6671 * @param parameters The command parameters. 6672 * 6673 * @return True if the command was successfully delivered, false otherwise. This does 6674 * not indicate whether the command itself was successful. 6675 */ 6676 boolean viewServerWindowCommand(Socket client, String command, String parameters) { 6677 if (isSystemSecure()) { 6678 return false; 6679 } 6680 6681 boolean success = true; 6682 Parcel data = null; 6683 Parcel reply = null; 6684 6685 BufferedWriter out = null; 6686 6687 // Any uncaught exception will crash the system process 6688 try { 6689 // Find the hashcode of the window 6690 int index = parameters.indexOf(' '); 6691 if (index == -1) { 6692 index = parameters.length(); 6693 } 6694 final String code = parameters.substring(0, index); 6695 int hashCode = (int) Long.parseLong(code, 16); 6696 6697 // Extract the command's parameter after the window description 6698 if (index < parameters.length()) { 6699 parameters = parameters.substring(index + 1); 6700 } else { 6701 parameters = ""; 6702 } 6703 6704 final WindowState window = findWindow(hashCode); 6705 if (window == null) { 6706 return false; 6707 } 6708 6709 data = Parcel.obtain(); 6710 data.writeInterfaceToken("android.view.IWindow"); 6711 data.writeString(command); 6712 data.writeString(parameters); 6713 data.writeInt(1); 6714 ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0); 6715 6716 reply = Parcel.obtain(); 6717 6718 final IBinder binder = window.mClient.asBinder(); 6719 // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER 6720 binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0); 6721 6722 reply.readException(); 6723 6724 if (!client.isOutputShutdown()) { 6725 out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); 6726 out.write("DONE\n"); 6727 out.flush(); 6728 } 6729 6730 } catch (Exception e) { 6731 Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e); 6732 success = false; 6733 } finally { 6734 if (data != null) { 6735 data.recycle(); 6736 } 6737 if (reply != null) { 6738 reply.recycle(); 6739 } 6740 if (out != null) { 6741 try { 6742 out.close(); 6743 } catch (IOException e) { 6744 6745 } 6746 } 6747 } 6748 6749 return success; 6750 } 6751 6752 public void addWindowChangeListener(WindowChangeListener listener) { 6753 synchronized(mWindowMap) { 6754 mWindowChangeListeners.add(listener); 6755 } 6756 } 6757 6758 public void removeWindowChangeListener(WindowChangeListener listener) { 6759 synchronized(mWindowMap) { 6760 mWindowChangeListeners.remove(listener); 6761 } 6762 } 6763 6764 private void notifyWindowsChanged() { 6765 WindowChangeListener[] windowChangeListeners; 6766 synchronized(mWindowMap) { 6767 if(mWindowChangeListeners.isEmpty()) { 6768 return; 6769 } 6770 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()]; 6771 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners); 6772 } 6773 int N = windowChangeListeners.length; 6774 for(int i = 0; i < N; i++) { 6775 windowChangeListeners[i].windowsChanged(); 6776 } 6777 } 6778 6779 private void notifyFocusChanged() { 6780 WindowChangeListener[] windowChangeListeners; 6781 synchronized(mWindowMap) { 6782 if(mWindowChangeListeners.isEmpty()) { 6783 return; 6784 } 6785 windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()]; 6786 windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners); 6787 } 6788 int N = windowChangeListeners.length; 6789 for(int i = 0; i < N; i++) { 6790 windowChangeListeners[i].focusChanged(); 6791 } 6792 } 6793 6794 private WindowState findWindow(int hashCode) { 6795 if (hashCode == -1) { 6796 // TODO(multidisplay): Extend to multiple displays. 6797 return getFocusedWindow(); 6798 } 6799 6800 synchronized (mWindowMap) { 6801 final int numDisplays = mDisplayContents.size(); 6802 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 6803 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); 6804 final int numWindows = windows.size(); 6805 for (int winNdx = 0; winNdx < numWindows; ++winNdx) { 6806 final WindowState w = windows.get(winNdx); 6807 if (System.identityHashCode(w) == hashCode) { 6808 return w; 6809 } 6810 } 6811 } 6812 } 6813 6814 return null; 6815 } 6816 6817 /* 6818 * Instruct the Activity Manager to fetch the current configuration and broadcast 6819 * that to config-changed listeners if appropriate. 6820 */ 6821 void sendNewConfiguration() { 6822 try { 6823 mActivityManager.updateConfiguration(null); 6824 } catch (RemoteException e) { 6825 } 6826 } 6827 6828 public Configuration computeNewConfiguration() { 6829 synchronized (mWindowMap) { 6830 Configuration config = computeNewConfigurationLocked(); 6831 if (config == null && mWaitingForConfig) { 6832 // Nothing changed but we are waiting for something... stop that! 6833 mWaitingForConfig = false; 6834 mLastFinishedFreezeSource = "new-config"; 6835 performLayoutAndPlaceSurfacesLocked(); 6836 } 6837 return config; 6838 } 6839 } 6840 6841 Configuration computeNewConfigurationLocked() { 6842 Configuration config = new Configuration(); 6843 config.fontScale = 0; 6844 if (!computeScreenConfigurationLocked(config)) { 6845 return null; 6846 } 6847 return config; 6848 } 6849 6850 private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) { 6851 // TODO: Multidisplay: for now only use with default display. 6852 final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation); 6853 if (width < displayInfo.smallestNominalAppWidth) { 6854 displayInfo.smallestNominalAppWidth = width; 6855 } 6856 if (width > displayInfo.largestNominalAppWidth) { 6857 displayInfo.largestNominalAppWidth = width; 6858 } 6859 final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation); 6860 if (height < displayInfo.smallestNominalAppHeight) { 6861 displayInfo.smallestNominalAppHeight = height; 6862 } 6863 if (height > displayInfo.largestNominalAppHeight) { 6864 displayInfo.largestNominalAppHeight = height; 6865 } 6866 } 6867 6868 private int reduceConfigLayout(int curLayout, int rotation, float density, 6869 int dw, int dh) { 6870 // TODO: Multidisplay: for now only use with default display. 6871 // Get the app screen size at this rotation. 6872 int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation); 6873 int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation); 6874 6875 // Compute the screen layout size class for this rotation. 6876 int longSize = w; 6877 int shortSize = h; 6878 if (longSize < shortSize) { 6879 int tmp = longSize; 6880 longSize = shortSize; 6881 shortSize = tmp; 6882 } 6883 longSize = (int)(longSize/density); 6884 shortSize = (int)(shortSize/density); 6885 return Configuration.reduceScreenLayout(curLayout, longSize, shortSize); 6886 } 6887 6888 private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated, 6889 int dw, int dh, float density, Configuration outConfig) { 6890 // TODO: Multidisplay: for now only use with default display. 6891 6892 // We need to determine the smallest width that will occur under normal 6893 // operation. To this, start with the base screen size and compute the 6894 // width under the different possible rotations. We need to un-rotate 6895 // the current screen dimensions before doing this. 6896 int unrotDw, unrotDh; 6897 if (rotated) { 6898 unrotDw = dh; 6899 unrotDh = dw; 6900 } else { 6901 unrotDw = dw; 6902 unrotDh = dh; 6903 } 6904 displayInfo.smallestNominalAppWidth = 1<<30; 6905 displayInfo.smallestNominalAppHeight = 1<<30; 6906 displayInfo.largestNominalAppWidth = 0; 6907 displayInfo.largestNominalAppHeight = 0; 6908 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh); 6909 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw); 6910 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh); 6911 adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw); 6912 int sl = Configuration.resetScreenLayout(outConfig.screenLayout); 6913 sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh); 6914 sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw); 6915 sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh); 6916 sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw); 6917 outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density); 6918 outConfig.screenLayout = sl; 6919 } 6920 6921 private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm, 6922 int dw, int dh) { 6923 // TODO: Multidisplay: for now only use with default display. 6924 dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation); 6925 dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation); 6926 float scale = CompatibilityInfo.computeCompatibleScaling(dm, null); 6927 int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f); 6928 if (curSize == 0 || size < curSize) { 6929 curSize = size; 6930 } 6931 return curSize; 6932 } 6933 6934 private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) { 6935 // TODO: Multidisplay: for now only use with default display. 6936 mTmpDisplayMetrics.setTo(dm); 6937 final DisplayMetrics tmpDm = mTmpDisplayMetrics; 6938 final int unrotDw, unrotDh; 6939 if (rotated) { 6940 unrotDw = dh; 6941 unrotDh = dw; 6942 } else { 6943 unrotDw = dw; 6944 unrotDh = dh; 6945 } 6946 int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh); 6947 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw); 6948 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh); 6949 sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw); 6950 return sw; 6951 } 6952 6953 boolean computeScreenConfigurationLocked(Configuration config) { 6954 if (!mDisplayReady) { 6955 return false; 6956 } 6957 6958 // TODO(multidisplay): For now, apply Configuration to main screen only. 6959 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 6960 6961 // Use the effective "visual" dimensions based on current rotation 6962 final boolean rotated = (mRotation == Surface.ROTATION_90 6963 || mRotation == Surface.ROTATION_270); 6964 final int realdw = rotated ? 6965 displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth; 6966 final int realdh = rotated ? 6967 displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight; 6968 int dw = realdw; 6969 int dh = realdh; 6970 6971 if (mAltOrientation) { 6972 if (realdw > realdh) { 6973 // Turn landscape into portrait. 6974 int maxw = (int)(realdh/1.3f); 6975 if (maxw < realdw) { 6976 dw = maxw; 6977 } 6978 } else { 6979 // Turn portrait into landscape. 6980 int maxh = (int)(realdw/1.3f); 6981 if (maxh < realdh) { 6982 dh = maxh; 6983 } 6984 } 6985 } 6986 6987 if (config != null) { 6988 config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT : 6989 Configuration.ORIENTATION_LANDSCAPE; 6990 } 6991 6992 // Update application display metrics. 6993 final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation); 6994 final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation); 6995 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 6996 synchronized(displayContent.mDisplaySizeLock) { 6997 displayInfo.rotation = mRotation; 6998 displayInfo.logicalWidth = dw; 6999 displayInfo.logicalHeight = dh; 7000 displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity; 7001 displayInfo.appWidth = appWidth; 7002 displayInfo.appHeight = appHeight; 7003 displayInfo.getLogicalMetrics(mRealDisplayMetrics, 7004 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 7005 displayInfo.getAppMetrics(mDisplayMetrics); 7006 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager( 7007 displayContent.getDisplayId(), displayInfo); 7008 } 7009 if (false) { 7010 Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight); 7011 } 7012 7013 final DisplayMetrics dm = mDisplayMetrics; 7014 mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm, 7015 mCompatDisplayMetrics); 7016 7017 if (config != null) { 7018 config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation) 7019 / dm.density); 7020 config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation) 7021 / dm.density); 7022 computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config); 7023 7024 config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale); 7025 config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); 7026 config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh); 7027 config.densityDpi = displayContent.mBaseDisplayDensity; 7028 7029 // Update the configuration based on available input devices, lid switch, 7030 // and platform configuration. 7031 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH; 7032 config.keyboard = Configuration.KEYBOARD_NOKEYS; 7033 config.navigation = Configuration.NAVIGATION_NONAV; 7034 7035 int keyboardPresence = 0; 7036 int navigationPresence = 0; 7037 final InputDevice[] devices = mInputManager.getInputDevices(); 7038 final int len = devices.length; 7039 for (int i = 0; i < len; i++) { 7040 InputDevice device = devices[i]; 7041 if (!device.isVirtual()) { 7042 final int sources = device.getSources(); 7043 final int presenceFlag = device.isExternal() ? 7044 WindowManagerPolicy.PRESENCE_EXTERNAL : 7045 WindowManagerPolicy.PRESENCE_INTERNAL; 7046 7047 if (mIsTouchDevice) { 7048 if ((sources & InputDevice.SOURCE_TOUCHSCREEN) == 7049 InputDevice.SOURCE_TOUCHSCREEN) { 7050 config.touchscreen = Configuration.TOUCHSCREEN_FINGER; 7051 } 7052 } else { 7053 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH; 7054 } 7055 7056 if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) { 7057 config.navigation = Configuration.NAVIGATION_TRACKBALL; 7058 navigationPresence |= presenceFlag; 7059 } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD 7060 && config.navigation == Configuration.NAVIGATION_NONAV) { 7061 config.navigation = Configuration.NAVIGATION_DPAD; 7062 navigationPresence |= presenceFlag; 7063 } 7064 7065 if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) { 7066 config.keyboard = Configuration.KEYBOARD_QWERTY; 7067 keyboardPresence |= presenceFlag; 7068 } 7069 } 7070 } 7071 7072 // Determine whether a hard keyboard is available and enabled. 7073 boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS; 7074 if (hardKeyboardAvailable != mHardKeyboardAvailable) { 7075 mHardKeyboardAvailable = hardKeyboardAvailable; 7076 mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); 7077 mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); 7078 } 7079 if (mShowImeWithHardKeyboard) { 7080 config.keyboard = Configuration.KEYBOARD_NOKEYS; 7081 } 7082 7083 // Let the policy update hidden states. 7084 config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO; 7085 config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO; 7086 config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO; 7087 mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence); 7088 } 7089 7090 return true; 7091 } 7092 7093 public boolean isHardKeyboardAvailable() { 7094 synchronized (mWindowMap) { 7095 return mHardKeyboardAvailable; 7096 } 7097 } 7098 7099 public void updateShowImeWithHardKeyboard() { 7100 boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser( 7101 mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0, 7102 mCurrentUserId) == 1; 7103 synchronized (mWindowMap) { 7104 mShowImeWithHardKeyboard = showImeWithHardKeyboard; 7105 } 7106 } 7107 7108 public void setOnHardKeyboardStatusChangeListener( 7109 OnHardKeyboardStatusChangeListener listener) { 7110 synchronized (mWindowMap) { 7111 mHardKeyboardStatusChangeListener = listener; 7112 } 7113 } 7114 7115 void notifyHardKeyboardStatusChange() { 7116 final boolean available; 7117 final OnHardKeyboardStatusChangeListener listener; 7118 synchronized (mWindowMap) { 7119 listener = mHardKeyboardStatusChangeListener; 7120 available = mHardKeyboardAvailable; 7121 } 7122 if (listener != null) { 7123 listener.onHardKeyboardStatusChange(available); 7124 } 7125 } 7126 7127 // ------------------------------------------------------------- 7128 // Drag and drop 7129 // ------------------------------------------------------------- 7130 7131 IBinder prepareDragSurface(IWindow window, SurfaceSession session, 7132 int flags, int width, int height, Surface outSurface) { 7133 if (DEBUG_DRAG) { 7134 Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height 7135 + " flags=" + Integer.toHexString(flags) + " win=" + window 7136 + " asbinder=" + window.asBinder()); 7137 } 7138 7139 final int callerPid = Binder.getCallingPid(); 7140 final long origId = Binder.clearCallingIdentity(); 7141 IBinder token = null; 7142 7143 try { 7144 synchronized (mWindowMap) { 7145 try { 7146 if (mDragState == null) { 7147 // TODO(multi-display): support other displays 7148 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 7149 final Display display = displayContent.getDisplay(); 7150 SurfaceControl surface = new SurfaceControl(session, "drag surface", 7151 width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); 7152 surface.setLayerStack(display.getLayerStack()); 7153 if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG " 7154 + surface + ": CREATE"); 7155 outSurface.copyFrom(surface); 7156 final IBinder winBinder = window.asBinder(); 7157 token = new Binder(); 7158 mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder); 7159 token = mDragState.mToken = new Binder(); 7160 7161 // 5 second timeout for this window to actually begin the drag 7162 mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder); 7163 Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder); 7164 mH.sendMessageDelayed(msg, 5000); 7165 } else { 7166 Slog.w(TAG, "Drag already in progress"); 7167 } 7168 } catch (OutOfResourcesException e) { 7169 Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e); 7170 if (mDragState != null) { 7171 mDragState.reset(); 7172 mDragState = null; 7173 } 7174 } 7175 } 7176 } finally { 7177 Binder.restoreCallingIdentity(origId); 7178 } 7179 7180 return token; 7181 } 7182 7183 // ------------------------------------------------------------- 7184 // Input Events and Focus Management 7185 // ------------------------------------------------------------- 7186 7187 final InputMonitor mInputMonitor = new InputMonitor(this); 7188 private boolean mEventDispatchingEnabled; 7189 7190 @Override 7191 public void pauseKeyDispatching(IBinder _token) { 7192 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 7193 "pauseKeyDispatching()")) { 7194 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 7195 } 7196 7197 synchronized (mWindowMap) { 7198 WindowToken token = mTokenMap.get(_token); 7199 if (token != null) { 7200 mInputMonitor.pauseDispatchingLw(token); 7201 } 7202 } 7203 } 7204 7205 @Override 7206 public void resumeKeyDispatching(IBinder _token) { 7207 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 7208 "resumeKeyDispatching()")) { 7209 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 7210 } 7211 7212 synchronized (mWindowMap) { 7213 WindowToken token = mTokenMap.get(_token); 7214 if (token != null) { 7215 mInputMonitor.resumeDispatchingLw(token); 7216 } 7217 } 7218 } 7219 7220 @Override 7221 public void setEventDispatching(boolean enabled) { 7222 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, 7223 "setEventDispatching()")) { 7224 throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); 7225 } 7226 7227 synchronized (mWindowMap) { 7228 mEventDispatchingEnabled = enabled; 7229 if (mDisplayEnabled) { 7230 mInputMonitor.setEventDispatchingLw(enabled); 7231 } 7232 } 7233 } 7234 7235 private WindowState getFocusedWindow() { 7236 synchronized (mWindowMap) { 7237 return getFocusedWindowLocked(); 7238 } 7239 } 7240 7241 private WindowState getFocusedWindowLocked() { 7242 return mCurrentFocus; 7243 } 7244 7245 public boolean detectSafeMode() { 7246 if (!mInputMonitor.waitForInputDevicesReady( 7247 INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) { 7248 Slog.w(TAG, "Devices still not ready after waiting " 7249 + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS 7250 + " milliseconds before attempting to detect safe mode."); 7251 } 7252 7253 int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, 7254 KeyEvent.KEYCODE_MENU); 7255 int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S); 7256 int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, 7257 KeyEvent.KEYCODE_DPAD_CENTER); 7258 int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, 7259 InputManagerService.BTN_MOUSE); 7260 int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, 7261 KeyEvent.KEYCODE_VOLUME_DOWN); 7262 mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0 7263 || volumeDownState > 0; 7264 try { 7265 if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) { 7266 mSafeMode = true; 7267 SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, ""); 7268 } 7269 } catch (IllegalArgumentException e) { 7270 } 7271 if (mSafeMode) { 7272 Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState 7273 + " dpad=" + dpadState + " trackball=" + trackballState + ")"); 7274 } else { 7275 Log.i(TAG, "SAFE MODE not enabled"); 7276 } 7277 mPolicy.setSafeMode(mSafeMode); 7278 return mSafeMode; 7279 } 7280 7281 public void displayReady() { 7282 displayReady(Display.DEFAULT_DISPLAY); 7283 7284 synchronized(mWindowMap) { 7285 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 7286 readForcedDisplaySizeAndDensityLocked(displayContent); 7287 mDisplayReady = true; 7288 } 7289 7290 try { 7291 mActivityManager.updateConfiguration(null); 7292 } catch (RemoteException e) { 7293 } 7294 7295 synchronized(mWindowMap) { 7296 mIsTouchDevice = mContext.getPackageManager().hasSystemFeature( 7297 PackageManager.FEATURE_TOUCHSCREEN); 7298 configureDisplayPolicyLocked(getDefaultDisplayContentLocked()); 7299 } 7300 7301 try { 7302 mActivityManager.updateConfiguration(null); 7303 } catch (RemoteException e) { 7304 } 7305 } 7306 7307 private void displayReady(int displayId) { 7308 synchronized(mWindowMap) { 7309 final DisplayContent displayContent = getDisplayContentLocked(displayId); 7310 if (displayContent != null) { 7311 mAnimator.addDisplayLocked(displayId); 7312 synchronized(displayContent.mDisplaySizeLock) { 7313 // Bootstrap the default logical display from the display manager. 7314 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 7315 DisplayInfo newDisplayInfo = mDisplayManagerInternal.getDisplayInfo(displayId); 7316 if (newDisplayInfo != null) { 7317 displayInfo.copyFrom(newDisplayInfo); 7318 } 7319 displayContent.mInitialDisplayWidth = displayInfo.logicalWidth; 7320 displayContent.mInitialDisplayHeight = displayInfo.logicalHeight; 7321 displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi; 7322 displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth; 7323 displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight; 7324 displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity; 7325 displayContent.mBaseDisplayRect.set(0, 0, 7326 displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight); 7327 } 7328 } 7329 } 7330 } 7331 7332 public void systemReady() { 7333 mPolicy.systemReady(); 7334 } 7335 7336 // ------------------------------------------------------------- 7337 // Async Handler 7338 // ------------------------------------------------------------- 7339 7340 final class H extends Handler { 7341 public static final int REPORT_FOCUS_CHANGE = 2; 7342 public static final int REPORT_LOSING_FOCUS = 3; 7343 public static final int DO_TRAVERSAL = 4; 7344 public static final int ADD_STARTING = 5; 7345 public static final int REMOVE_STARTING = 6; 7346 public static final int FINISHED_STARTING = 7; 7347 public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8; 7348 public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9; 7349 public static final int WINDOW_FREEZE_TIMEOUT = 11; 7350 7351 public static final int APP_TRANSITION_TIMEOUT = 13; 7352 public static final int PERSIST_ANIMATION_SCALE = 14; 7353 public static final int FORCE_GC = 15; 7354 public static final int ENABLE_SCREEN = 16; 7355 public static final int APP_FREEZE_TIMEOUT = 17; 7356 public static final int SEND_NEW_CONFIGURATION = 18; 7357 public static final int REPORT_WINDOWS_CHANGE = 19; 7358 public static final int DRAG_START_TIMEOUT = 20; 7359 public static final int DRAG_END_TIMEOUT = 21; 7360 public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22; 7361 public static final int BOOT_TIMEOUT = 23; 7362 public static final int WAITING_FOR_DRAWN_TIMEOUT = 24; 7363 public static final int SHOW_STRICT_MODE_VIOLATION = 25; 7364 public static final int DO_ANIMATION_CALLBACK = 26; 7365 7366 public static final int DO_DISPLAY_ADDED = 27; 7367 public static final int DO_DISPLAY_REMOVED = 28; 7368 public static final int DO_DISPLAY_CHANGED = 29; 7369 7370 public static final int CLIENT_FREEZE_TIMEOUT = 30; 7371 public static final int TAP_OUTSIDE_STACK = 31; 7372 public static final int NOTIFY_ACTIVITY_DRAWN = 32; 7373 7374 public static final int ALL_WINDOWS_DRAWN = 33; 7375 7376 public static final int NEW_ANIMATOR_SCALE = 34; 7377 7378 public static final int SHOW_DISPLAY_MASK = 35; 7379 7380 @Override 7381 public void handleMessage(Message msg) { 7382 if (DEBUG_WINDOW_TRACE) { 7383 Slog.v(TAG, "handleMessage: entry what=" + msg.what); 7384 } 7385 switch (msg.what) { 7386 case REPORT_FOCUS_CHANGE: { 7387 WindowState lastFocus; 7388 WindowState newFocus; 7389 7390 synchronized(mWindowMap) { 7391 lastFocus = mLastFocus; 7392 newFocus = mCurrentFocus; 7393 if (lastFocus == newFocus) { 7394 // Focus is not changing, so nothing to do. 7395 return; 7396 } 7397 mLastFocus = newFocus; 7398 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Focus moving from " + lastFocus + 7399 " to " + newFocus); 7400 if (newFocus != null && lastFocus != null 7401 && !newFocus.isDisplayedLw()) { 7402 //Slog.i(TAG, "Delaying loss of focus..."); 7403 mLosingFocus.add(lastFocus); 7404 lastFocus = null; 7405 } 7406 } 7407 7408 //System.out.println("Changing focus from " + lastFocus 7409 // + " to " + newFocus); 7410 if (newFocus != null) { 7411 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Gaining focus: " + newFocus); 7412 newFocus.reportFocusChangedSerialized(true, mInTouchMode); 7413 notifyFocusChanged(); 7414 } 7415 7416 if (lastFocus != null) { 7417 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing focus: " + lastFocus); 7418 lastFocus.reportFocusChangedSerialized(false, mInTouchMode); 7419 } 7420 } break; 7421 7422 case REPORT_LOSING_FOCUS: { 7423 ArrayList<WindowState> losers; 7424 7425 synchronized(mWindowMap) { 7426 losers = mLosingFocus; 7427 mLosingFocus = new ArrayList<WindowState>(); 7428 } 7429 7430 final int N = losers.size(); 7431 for (int i=0; i<N; i++) { 7432 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing delayed focus: " + 7433 losers.get(i)); 7434 losers.get(i).reportFocusChangedSerialized(false, mInTouchMode); 7435 } 7436 } break; 7437 7438 case DO_TRAVERSAL: { 7439 synchronized(mWindowMap) { 7440 mTraversalScheduled = false; 7441 performLayoutAndPlaceSurfacesLocked(); 7442 } 7443 } break; 7444 7445 case ADD_STARTING: { 7446 final AppWindowToken wtoken = (AppWindowToken)msg.obj; 7447 final StartingData sd = wtoken.startingData; 7448 7449 if (sd == null) { 7450 // Animation has been canceled... do nothing. 7451 return; 7452 } 7453 7454 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting " 7455 + wtoken + ": pkg=" + sd.pkg); 7456 7457 View view = null; 7458 try { 7459 view = mPolicy.addStartingWindow( 7460 wtoken.token, sd.pkg, sd.theme, sd.compatInfo, 7461 sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags); 7462 } catch (Exception e) { 7463 Slog.w(TAG, "Exception when adding starting window", e); 7464 } 7465 7466 if (view != null) { 7467 boolean abort = false; 7468 7469 synchronized(mWindowMap) { 7470 if (wtoken.removed || wtoken.startingData == null) { 7471 // If the window was successfully added, then 7472 // we need to remove it. 7473 if (wtoken.startingWindow != null) { 7474 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, 7475 "Aborted starting " + wtoken 7476 + ": removed=" + wtoken.removed 7477 + " startingData=" + wtoken.startingData); 7478 wtoken.startingWindow = null; 7479 wtoken.startingData = null; 7480 abort = true; 7481 } 7482 } else { 7483 wtoken.startingView = view; 7484 } 7485 if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG, 7486 "Added starting " + wtoken 7487 + ": startingWindow=" 7488 + wtoken.startingWindow + " startingView=" 7489 + wtoken.startingView); 7490 } 7491 7492 if (abort) { 7493 try { 7494 mPolicy.removeStartingWindow(wtoken.token, view); 7495 } catch (Exception e) { 7496 Slog.w(TAG, "Exception when removing starting window", e); 7497 } 7498 } 7499 } 7500 } break; 7501 7502 case REMOVE_STARTING: { 7503 final AppWindowToken wtoken = (AppWindowToken)msg.obj; 7504 IBinder token = null; 7505 View view = null; 7506 synchronized (mWindowMap) { 7507 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting " 7508 + wtoken + ": startingWindow=" 7509 + wtoken.startingWindow + " startingView=" 7510 + wtoken.startingView); 7511 if (wtoken.startingWindow != null) { 7512 view = wtoken.startingView; 7513 token = wtoken.token; 7514 wtoken.startingData = null; 7515 wtoken.startingView = null; 7516 wtoken.startingWindow = null; 7517 wtoken.startingDisplayed = false; 7518 } 7519 } 7520 if (view != null) { 7521 try { 7522 mPolicy.removeStartingWindow(token, view); 7523 } catch (Exception e) { 7524 Slog.w(TAG, "Exception when removing starting window", e); 7525 } 7526 } 7527 } break; 7528 7529 case FINISHED_STARTING: { 7530 IBinder token = null; 7531 View view = null; 7532 while (true) { 7533 synchronized (mWindowMap) { 7534 final int N = mFinishedStarting.size(); 7535 if (N <= 0) { 7536 break; 7537 } 7538 AppWindowToken wtoken = mFinishedStarting.remove(N-1); 7539 7540 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, 7541 "Finished starting " + wtoken 7542 + ": startingWindow=" + wtoken.startingWindow 7543 + " startingView=" + wtoken.startingView); 7544 7545 if (wtoken.startingWindow == null) { 7546 continue; 7547 } 7548 7549 view = wtoken.startingView; 7550 token = wtoken.token; 7551 wtoken.startingData = null; 7552 wtoken.startingView = null; 7553 wtoken.startingWindow = null; 7554 wtoken.startingDisplayed = false; 7555 } 7556 7557 try { 7558 mPolicy.removeStartingWindow(token, view); 7559 } catch (Exception e) { 7560 Slog.w(TAG, "Exception when removing starting window", e); 7561 } 7562 } 7563 } break; 7564 7565 case REPORT_APPLICATION_TOKEN_DRAWN: { 7566 final AppWindowToken wtoken = (AppWindowToken)msg.obj; 7567 7568 try { 7569 if (DEBUG_VISIBILITY) Slog.v( 7570 TAG, "Reporting drawn in " + wtoken); 7571 wtoken.appToken.windowsDrawn(); 7572 } catch (RemoteException ex) { 7573 } 7574 } break; 7575 7576 case REPORT_APPLICATION_TOKEN_WINDOWS: { 7577 final AppWindowToken wtoken = (AppWindowToken)msg.obj; 7578 7579 boolean nowVisible = msg.arg1 != 0; 7580 boolean nowGone = msg.arg2 != 0; 7581 7582 try { 7583 if (DEBUG_VISIBILITY) Slog.v( 7584 TAG, "Reporting visible in " + wtoken 7585 + " visible=" + nowVisible 7586 + " gone=" + nowGone); 7587 if (nowVisible) { 7588 wtoken.appToken.windowsVisible(); 7589 } else { 7590 wtoken.appToken.windowsGone(); 7591 } 7592 } catch (RemoteException ex) { 7593 } 7594 } break; 7595 7596 case WINDOW_FREEZE_TIMEOUT: { 7597 // TODO(multidisplay): Can non-default displays rotate? 7598 synchronized (mWindowMap) { 7599 Slog.w(TAG, "Window freeze timeout expired."); 7600 final WindowList windows = getDefaultWindowListLocked(); 7601 int i = windows.size(); 7602 while (i > 0) { 7603 i--; 7604 WindowState w = windows.get(i); 7605 if (w.mOrientationChanging) { 7606 w.mOrientationChanging = false; 7607 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() 7608 - mDisplayFreezeTime); 7609 Slog.w(TAG, "Force clearing orientation change: " + w); 7610 } 7611 } 7612 performLayoutAndPlaceSurfacesLocked(); 7613 } 7614 break; 7615 } 7616 7617 case APP_TRANSITION_TIMEOUT: { 7618 synchronized (mWindowMap) { 7619 if (mAppTransition.isTransitionSet()) { 7620 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT"); 7621 mAppTransition.setTimeout(); 7622 performLayoutAndPlaceSurfacesLocked(); 7623 } 7624 } 7625 break; 7626 } 7627 7628 case PERSIST_ANIMATION_SCALE: { 7629 Settings.Global.putFloat(mContext.getContentResolver(), 7630 Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting); 7631 Settings.Global.putFloat(mContext.getContentResolver(), 7632 Settings.Global.TRANSITION_ANIMATION_SCALE, 7633 mTransitionAnimationScaleSetting); 7634 Settings.Global.putFloat(mContext.getContentResolver(), 7635 Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting); 7636 break; 7637 } 7638 7639 case FORCE_GC: { 7640 synchronized (mWindowMap) { 7641 // Since we're holding both mWindowMap and mAnimator we don't need to 7642 // hold mAnimator.mLayoutToAnim. 7643 if (mAnimator.mAnimating || mAnimationScheduled) { 7644 // If we are animating, don't do the gc now but 7645 // delay a bit so we don't interrupt the animation. 7646 sendEmptyMessageDelayed(H.FORCE_GC, 2000); 7647 return; 7648 } 7649 // If we are currently rotating the display, it will 7650 // schedule a new message when done. 7651 if (mDisplayFrozen) { 7652 return; 7653 } 7654 } 7655 Runtime.getRuntime().gc(); 7656 break; 7657 } 7658 7659 case ENABLE_SCREEN: { 7660 performEnableScreen(); 7661 break; 7662 } 7663 7664 case APP_FREEZE_TIMEOUT: { 7665 synchronized (mWindowMap) { 7666 Slog.w(TAG, "App freeze timeout expired."); 7667 final int numStacks = mStackIdToStack.size(); 7668 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 7669 final TaskStack stack = mStackIdToStack.valueAt(stackNdx); 7670 final ArrayList<Task> tasks = stack.getTasks(); 7671 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 7672 AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 7673 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 7674 AppWindowToken tok = tokens.get(tokenNdx); 7675 if (tok.mAppAnimator.freezingScreen) { 7676 Slog.w(TAG, "Force clearing freeze: " + tok); 7677 unsetAppFreezingScreenLocked(tok, true, true); 7678 } 7679 } 7680 } 7681 } 7682 } 7683 break; 7684 } 7685 7686 case CLIENT_FREEZE_TIMEOUT: { 7687 synchronized (mWindowMap) { 7688 if (mClientFreezingScreen) { 7689 mClientFreezingScreen = false; 7690 mLastFinishedFreezeSource = "client-timeout"; 7691 stopFreezingDisplayLocked(); 7692 } 7693 } 7694 break; 7695 } 7696 7697 case SEND_NEW_CONFIGURATION: { 7698 removeMessages(SEND_NEW_CONFIGURATION); 7699 sendNewConfiguration(); 7700 break; 7701 } 7702 7703 case REPORT_WINDOWS_CHANGE: { 7704 if (mWindowsChanged) { 7705 synchronized (mWindowMap) { 7706 mWindowsChanged = false; 7707 } 7708 notifyWindowsChanged(); 7709 } 7710 break; 7711 } 7712 7713 case DRAG_START_TIMEOUT: { 7714 IBinder win = (IBinder)msg.obj; 7715 if (DEBUG_DRAG) { 7716 Slog.w(TAG, "Timeout starting drag by win " + win); 7717 } 7718 synchronized (mWindowMap) { 7719 // !!! TODO: ANR the app that has failed to start the drag in time 7720 if (mDragState != null) { 7721 mDragState.unregister(); 7722 mInputMonitor.updateInputWindowsLw(true /*force*/); 7723 mDragState.reset(); 7724 mDragState = null; 7725 } 7726 } 7727 break; 7728 } 7729 7730 case DRAG_END_TIMEOUT: { 7731 IBinder win = (IBinder)msg.obj; 7732 if (DEBUG_DRAG) { 7733 Slog.w(TAG, "Timeout ending drag to win " + win); 7734 } 7735 synchronized (mWindowMap) { 7736 // !!! TODO: ANR the drag-receiving app 7737 if (mDragState != null) { 7738 mDragState.mDragResult = false; 7739 mDragState.endDragLw(); 7740 } 7741 } 7742 break; 7743 } 7744 7745 case REPORT_HARD_KEYBOARD_STATUS_CHANGE: { 7746 notifyHardKeyboardStatusChange(); 7747 break; 7748 } 7749 7750 case BOOT_TIMEOUT: { 7751 performBootTimeout(); 7752 break; 7753 } 7754 7755 case WAITING_FOR_DRAWN_TIMEOUT: { 7756 Runnable callback = null; 7757 synchronized (mWindowMap) { 7758 Slog.w(TAG, "Timeout waiting for drawn: undrawn=" + mWaitingForDrawn); 7759 mWaitingForDrawn.clear(); 7760 callback = mWaitingForDrawnCallback; 7761 mWaitingForDrawnCallback = null; 7762 } 7763 if (callback != null) { 7764 callback.run(); 7765 } 7766 break; 7767 } 7768 7769 case SHOW_STRICT_MODE_VIOLATION: { 7770 showStrictModeViolation(msg.arg1, msg.arg2); 7771 break; 7772 } 7773 7774 case SHOW_DISPLAY_MASK: { 7775 showCircularMask(); 7776 break; 7777 } 7778 7779 case DO_ANIMATION_CALLBACK: { 7780 try { 7781 ((IRemoteCallback)msg.obj).sendResult(null); 7782 } catch (RemoteException e) { 7783 } 7784 break; 7785 } 7786 7787 case DO_DISPLAY_ADDED: 7788 handleDisplayAdded(msg.arg1); 7789 break; 7790 7791 case DO_DISPLAY_REMOVED: 7792 synchronized (mWindowMap) { 7793 handleDisplayRemovedLocked(msg.arg1); 7794 } 7795 break; 7796 7797 case DO_DISPLAY_CHANGED: 7798 synchronized (mWindowMap) { 7799 handleDisplayChangedLocked(msg.arg1); 7800 } 7801 break; 7802 7803 case TAP_OUTSIDE_STACK: { 7804 int stackId; 7805 synchronized (mWindowMap) { 7806 stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2); 7807 } 7808 if (stackId >= 0) { 7809 try { 7810 mActivityManager.setFocusedStack(stackId); 7811 } catch (RemoteException e) { 7812 } 7813 } 7814 } 7815 break; 7816 case NOTIFY_ACTIVITY_DRAWN: 7817 try { 7818 mActivityManager.notifyActivityDrawn((IBinder) msg.obj); 7819 } catch (RemoteException e) { 7820 } 7821 break; 7822 case ALL_WINDOWS_DRAWN: { 7823 Runnable callback; 7824 synchronized (mWindowMap) { 7825 callback = mWaitingForDrawnCallback; 7826 mWaitingForDrawnCallback = null; 7827 } 7828 if (callback != null) { 7829 callback.run(); 7830 } 7831 } 7832 case NEW_ANIMATOR_SCALE: { 7833 float scale = getCurrentAnimatorScale(); 7834 ValueAnimator.setDurationScale(scale); 7835 Session session = (Session)msg.obj; 7836 if (session != null) { 7837 try { 7838 session.mCallback.onAnimatorScaleChanged(scale); 7839 } catch (RemoteException e) { 7840 } 7841 } else { 7842 ArrayList<IWindowSessionCallback> callbacks 7843 = new ArrayList<IWindowSessionCallback>(); 7844 synchronized (mWindowMap) { 7845 for (int i=0; i<mSessions.size(); i++) { 7846 callbacks.add(mSessions.valueAt(i).mCallback); 7847 } 7848 7849 } 7850 for (int i=0; i<callbacks.size(); i++) { 7851 try { 7852 callbacks.get(i).onAnimatorScaleChanged(scale); 7853 } catch (RemoteException e) { 7854 } 7855 } 7856 } 7857 } 7858 break; 7859 } 7860 if (DEBUG_WINDOW_TRACE) { 7861 Slog.v(TAG, "handleMessage: exit"); 7862 } 7863 } 7864 } 7865 7866 // ------------------------------------------------------------- 7867 // IWindowManager API 7868 // ------------------------------------------------------------- 7869 7870 @Override 7871 public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, 7872 IInputContext inputContext) { 7873 if (client == null) throw new IllegalArgumentException("null client"); 7874 if (inputContext == null) throw new IllegalArgumentException("null inputContext"); 7875 Session session = new Session(this, callback, client, inputContext); 7876 return session; 7877 } 7878 7879 @Override 7880 public boolean inputMethodClientHasFocus(IInputMethodClient client) { 7881 synchronized (mWindowMap) { 7882 // The focus for the client is the window immediately below 7883 // where we would place the input method window. 7884 int idx = findDesiredInputMethodWindowIndexLocked(false); 7885 if (idx > 0) { 7886 // TODO(multidisplay): IMEs are only supported on the default display. 7887 WindowState imFocus = getDefaultWindowListLocked().get(idx-1); 7888 if (DEBUG_INPUT_METHOD) { 7889 Slog.i(TAG, "Desired input method target: " + imFocus); 7890 Slog.i(TAG, "Current focus: " + mCurrentFocus); 7891 Slog.i(TAG, "Last focus: " + mLastFocus); 7892 } 7893 if (imFocus != null) { 7894 // This may be a starting window, in which case we still want 7895 // to count it as okay. 7896 if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING 7897 && imFocus.mAppToken != null) { 7898 // The client has definitely started, so it really should 7899 // have a window in this app token. Let's look for it. 7900 for (int i=0; i<imFocus.mAppToken.windows.size(); i++) { 7901 WindowState w = imFocus.mAppToken.windows.get(i); 7902 if (w != imFocus) { 7903 Log.i(TAG, "Switching to real app window: " + w); 7904 imFocus = w; 7905 break; 7906 } 7907 } 7908 } 7909 if (DEBUG_INPUT_METHOD) { 7910 Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient); 7911 if (imFocus.mSession.mClient != null) { 7912 Slog.i(TAG, "IM target client binder: " 7913 + imFocus.mSession.mClient.asBinder()); 7914 Slog.i(TAG, "Requesting client binder: " + client.asBinder()); 7915 } 7916 } 7917 if (imFocus.mSession.mClient != null && 7918 imFocus.mSession.mClient.asBinder() == client.asBinder()) { 7919 return true; 7920 } 7921 } 7922 } 7923 7924 // Okay, how about this... what is the current focus? 7925 // It seems in some cases we may not have moved the IM 7926 // target window, such as when it was in a pop-up window, 7927 // so let's also look at the current focus. (An example: 7928 // go to Gmail, start searching so the keyboard goes up, 7929 // press home. Sometimes the IME won't go down.) 7930 // Would be nice to fix this more correctly, but it's 7931 // way at the end of a release, and this should be good enough. 7932 if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null 7933 && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) { 7934 return true; 7935 } 7936 } 7937 return false; 7938 } 7939 7940 @Override 7941 public void getInitialDisplaySize(int displayId, Point size) { 7942 synchronized (mWindowMap) { 7943 final DisplayContent displayContent = getDisplayContentLocked(displayId); 7944 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 7945 synchronized(displayContent.mDisplaySizeLock) { 7946 size.x = displayContent.mInitialDisplayWidth; 7947 size.y = displayContent.mInitialDisplayHeight; 7948 } 7949 } 7950 } 7951 } 7952 7953 @Override 7954 public void getBaseDisplaySize(int displayId, Point size) { 7955 synchronized (mWindowMap) { 7956 final DisplayContent displayContent = getDisplayContentLocked(displayId); 7957 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 7958 synchronized(displayContent.mDisplaySizeLock) { 7959 size.x = displayContent.mBaseDisplayWidth; 7960 size.y = displayContent.mBaseDisplayHeight; 7961 } 7962 } 7963 } 7964 } 7965 7966 @Override 7967 public void setForcedDisplaySize(int displayId, int width, int height) { 7968 if (mContext.checkCallingOrSelfPermission( 7969 android.Manifest.permission.WRITE_SECURE_SETTINGS) != 7970 PackageManager.PERMISSION_GRANTED) { 7971 throw new SecurityException("Must hold permission " + 7972 android.Manifest.permission.WRITE_SECURE_SETTINGS); 7973 } 7974 if (displayId != Display.DEFAULT_DISPLAY) { 7975 throw new IllegalArgumentException("Can only set the default display"); 7976 } 7977 final long ident = Binder.clearCallingIdentity(); 7978 try { 7979 synchronized(mWindowMap) { 7980 // Set some sort of reasonable bounds on the size of the display that we 7981 // will try to emulate. 7982 final int MIN_WIDTH = 200; 7983 final int MIN_HEIGHT = 200; 7984 final int MAX_SCALE = 2; 7985 final DisplayContent displayContent = getDisplayContentLocked(displayId); 7986 if (displayContent != null) { 7987 width = Math.min(Math.max(width, MIN_WIDTH), 7988 displayContent.mInitialDisplayWidth * MAX_SCALE); 7989 height = Math.min(Math.max(height, MIN_HEIGHT), 7990 displayContent.mInitialDisplayHeight * MAX_SCALE); 7991 setForcedDisplaySizeLocked(displayContent, width, height); 7992 Settings.Global.putString(mContext.getContentResolver(), 7993 Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height); 7994 } 7995 } 7996 } finally { 7997 Binder.restoreCallingIdentity(ident); 7998 } 7999 } 8000 8001 private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) { 8002 String sizeStr = Settings.Global.getString(mContext.getContentResolver(), 8003 Settings.Global.DISPLAY_SIZE_FORCED); 8004 if (sizeStr == null || sizeStr.length() == 0) { 8005 sizeStr = SystemProperties.get(SIZE_OVERRIDE, null); 8006 } 8007 if (sizeStr != null && sizeStr.length() > 0) { 8008 final int pos = sizeStr.indexOf(','); 8009 if (pos > 0 && sizeStr.lastIndexOf(',') == pos) { 8010 int width, height; 8011 try { 8012 width = Integer.parseInt(sizeStr.substring(0, pos)); 8013 height = Integer.parseInt(sizeStr.substring(pos+1)); 8014 synchronized(displayContent.mDisplaySizeLock) { 8015 if (displayContent.mBaseDisplayWidth != width 8016 || displayContent.mBaseDisplayHeight != height) { 8017 Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height); 8018 displayContent.mBaseDisplayWidth = width; 8019 displayContent.mBaseDisplayHeight = height; 8020 } 8021 } 8022 } catch (NumberFormatException ex) { 8023 } 8024 } 8025 } 8026 String densityStr = Settings.Global.getString(mContext.getContentResolver(), 8027 Settings.Global.DISPLAY_DENSITY_FORCED); 8028 if (densityStr == null || densityStr.length() == 0) { 8029 densityStr = SystemProperties.get(DENSITY_OVERRIDE, null); 8030 } 8031 if (densityStr != null && densityStr.length() > 0) { 8032 int density; 8033 try { 8034 density = Integer.parseInt(densityStr); 8035 synchronized(displayContent.mDisplaySizeLock) { 8036 if (displayContent.mBaseDisplayDensity != density) { 8037 Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density); 8038 displayContent.mBaseDisplayDensity = density; 8039 } 8040 } 8041 } catch (NumberFormatException ex) { 8042 } 8043 } 8044 } 8045 8046 // displayContent must not be null 8047 private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) { 8048 Slog.i(TAG, "Using new display size: " + width + "x" + height); 8049 8050 synchronized(displayContent.mDisplaySizeLock) { 8051 displayContent.mBaseDisplayWidth = width; 8052 displayContent.mBaseDisplayHeight = height; 8053 } 8054 reconfigureDisplayLocked(displayContent); 8055 } 8056 8057 @Override 8058 public void clearForcedDisplaySize(int displayId) { 8059 if (mContext.checkCallingOrSelfPermission( 8060 android.Manifest.permission.WRITE_SECURE_SETTINGS) != 8061 PackageManager.PERMISSION_GRANTED) { 8062 throw new SecurityException("Must hold permission " + 8063 android.Manifest.permission.WRITE_SECURE_SETTINGS); 8064 } 8065 if (displayId != Display.DEFAULT_DISPLAY) { 8066 throw new IllegalArgumentException("Can only set the default display"); 8067 } 8068 final long ident = Binder.clearCallingIdentity(); 8069 try { 8070 synchronized(mWindowMap) { 8071 final DisplayContent displayContent = getDisplayContentLocked(displayId); 8072 if (displayContent != null) { 8073 setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth, 8074 displayContent.mInitialDisplayHeight); 8075 Settings.Global.putString(mContext.getContentResolver(), 8076 Settings.Global.DISPLAY_SIZE_FORCED, ""); 8077 } 8078 } 8079 } finally { 8080 Binder.restoreCallingIdentity(ident); 8081 } 8082 } 8083 8084 @Override 8085 public int getInitialDisplayDensity(int displayId) { 8086 synchronized (mWindowMap) { 8087 final DisplayContent displayContent = getDisplayContentLocked(displayId); 8088 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 8089 synchronized(displayContent.mDisplaySizeLock) { 8090 return displayContent.mInitialDisplayDensity; 8091 } 8092 } 8093 } 8094 return -1; 8095 } 8096 8097 @Override 8098 public int getBaseDisplayDensity(int displayId) { 8099 synchronized (mWindowMap) { 8100 final DisplayContent displayContent = getDisplayContentLocked(displayId); 8101 if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) { 8102 synchronized(displayContent.mDisplaySizeLock) { 8103 return displayContent.mBaseDisplayDensity; 8104 } 8105 } 8106 } 8107 return -1; 8108 } 8109 8110 @Override 8111 public void setForcedDisplayDensity(int displayId, int density) { 8112 if (mContext.checkCallingOrSelfPermission( 8113 android.Manifest.permission.WRITE_SECURE_SETTINGS) != 8114 PackageManager.PERMISSION_GRANTED) { 8115 throw new SecurityException("Must hold permission " + 8116 android.Manifest.permission.WRITE_SECURE_SETTINGS); 8117 } 8118 if (displayId != Display.DEFAULT_DISPLAY) { 8119 throw new IllegalArgumentException("Can only set the default display"); 8120 } 8121 final long ident = Binder.clearCallingIdentity(); 8122 try { 8123 synchronized(mWindowMap) { 8124 final DisplayContent displayContent = getDisplayContentLocked(displayId); 8125 if (displayContent != null) { 8126 setForcedDisplayDensityLocked(displayContent, density); 8127 Settings.Global.putString(mContext.getContentResolver(), 8128 Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density)); 8129 } 8130 } 8131 } finally { 8132 Binder.restoreCallingIdentity(ident); 8133 } 8134 } 8135 8136 // displayContent must not be null 8137 private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) { 8138 Slog.i(TAG, "Using new display density: " + density); 8139 8140 synchronized(displayContent.mDisplaySizeLock) { 8141 displayContent.mBaseDisplayDensity = density; 8142 } 8143 reconfigureDisplayLocked(displayContent); 8144 } 8145 8146 @Override 8147 public void clearForcedDisplayDensity(int displayId) { 8148 if (mContext.checkCallingOrSelfPermission( 8149 android.Manifest.permission.WRITE_SECURE_SETTINGS) != 8150 PackageManager.PERMISSION_GRANTED) { 8151 throw new SecurityException("Must hold permission " + 8152 android.Manifest.permission.WRITE_SECURE_SETTINGS); 8153 } 8154 if (displayId != Display.DEFAULT_DISPLAY) { 8155 throw new IllegalArgumentException("Can only set the default display"); 8156 } 8157 final long ident = Binder.clearCallingIdentity(); 8158 try { 8159 synchronized(mWindowMap) { 8160 final DisplayContent displayContent = getDisplayContentLocked(displayId); 8161 if (displayContent != null) { 8162 setForcedDisplayDensityLocked(displayContent, 8163 displayContent.mInitialDisplayDensity); 8164 Settings.Global.putString(mContext.getContentResolver(), 8165 Settings.Global.DISPLAY_DENSITY_FORCED, ""); 8166 } 8167 } 8168 } finally { 8169 Binder.restoreCallingIdentity(ident); 8170 } 8171 } 8172 8173 // displayContent must not be null 8174 private void reconfigureDisplayLocked(DisplayContent displayContent) { 8175 // TODO: Multidisplay: for now only use with default display. 8176 configureDisplayPolicyLocked(displayContent); 8177 displayContent.layoutNeeded = true; 8178 8179 boolean configChanged = updateOrientationFromAppTokensLocked(false); 8180 mTempConfiguration.setToDefaults(); 8181 mTempConfiguration.fontScale = mCurConfiguration.fontScale; 8182 if (computeScreenConfigurationLocked(mTempConfiguration)) { 8183 if (mCurConfiguration.diff(mTempConfiguration) != 0) { 8184 configChanged = true; 8185 } 8186 } 8187 8188 if (configChanged) { 8189 mWaitingForConfig = true; 8190 startFreezingDisplayLocked(false, 0, 0); 8191 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 8192 } 8193 8194 performLayoutAndPlaceSurfacesLocked(); 8195 } 8196 8197 private void configureDisplayPolicyLocked(DisplayContent displayContent) { 8198 mPolicy.setInitialDisplaySize(displayContent.getDisplay(), 8199 displayContent.mBaseDisplayWidth, 8200 displayContent.mBaseDisplayHeight, 8201 displayContent.mBaseDisplayDensity); 8202 8203 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 8204 mPolicy.setDisplayOverscan(displayContent.getDisplay(), 8205 displayInfo.overscanLeft, displayInfo.overscanTop, 8206 displayInfo.overscanRight, displayInfo.overscanBottom); 8207 } 8208 8209 @Override 8210 public void setOverscan(int displayId, int left, int top, int right, int bottom) { 8211 if (mContext.checkCallingOrSelfPermission( 8212 android.Manifest.permission.WRITE_SECURE_SETTINGS) != 8213 PackageManager.PERMISSION_GRANTED) { 8214 throw new SecurityException("Must hold permission " + 8215 android.Manifest.permission.WRITE_SECURE_SETTINGS); 8216 } 8217 final long ident = Binder.clearCallingIdentity(); 8218 try { 8219 synchronized(mWindowMap) { 8220 DisplayContent displayContent = getDisplayContentLocked(displayId); 8221 if (displayContent != null) { 8222 setOverscanLocked(displayContent, left, top, right, bottom); 8223 } 8224 } 8225 } finally { 8226 Binder.restoreCallingIdentity(ident); 8227 } 8228 } 8229 8230 private void setOverscanLocked(DisplayContent displayContent, 8231 int left, int top, int right, int bottom) { 8232 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 8233 synchronized (displayContent.mDisplaySizeLock) { 8234 displayInfo.overscanLeft = left; 8235 displayInfo.overscanTop = top; 8236 displayInfo.overscanRight = right; 8237 displayInfo.overscanBottom = bottom; 8238 } 8239 8240 mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom); 8241 mDisplaySettings.writeSettingsLocked(); 8242 8243 reconfigureDisplayLocked(displayContent); 8244 } 8245 8246 // ------------------------------------------------------------- 8247 // Internals 8248 // ------------------------------------------------------------- 8249 8250 final WindowState windowForClientLocked(Session session, IWindow client, 8251 boolean throwOnError) { 8252 return windowForClientLocked(session, client.asBinder(), throwOnError); 8253 } 8254 8255 final WindowState windowForClientLocked(Session session, IBinder client, 8256 boolean throwOnError) { 8257 WindowState win = mWindowMap.get(client); 8258 if (localLOGV) Slog.v( 8259 TAG, "Looking up client " + client + ": " + win); 8260 if (win == null) { 8261 RuntimeException ex = new IllegalArgumentException( 8262 "Requested window " + client + " does not exist"); 8263 if (throwOnError) { 8264 throw ex; 8265 } 8266 Slog.w(TAG, "Failed looking up window", ex); 8267 return null; 8268 } 8269 if (session != null && win.mSession != session) { 8270 RuntimeException ex = new IllegalArgumentException( 8271 "Requested window " + client + " is in session " + 8272 win.mSession + ", not " + session); 8273 if (throwOnError) { 8274 throw ex; 8275 } 8276 Slog.w(TAG, "Failed looking up window", ex); 8277 return null; 8278 } 8279 8280 return win; 8281 } 8282 8283 final void rebuildAppWindowListLocked() { 8284 rebuildAppWindowListLocked(getDefaultDisplayContentLocked()); 8285 } 8286 8287 private void rebuildAppWindowListLocked(final DisplayContent displayContent) { 8288 final WindowList windows = displayContent.getWindowList(); 8289 int NW = windows.size(); 8290 int i; 8291 int lastBelow = -1; 8292 int numRemoved = 0; 8293 8294 if (mRebuildTmp.length < NW) { 8295 mRebuildTmp = new WindowState[NW+10]; 8296 } 8297 8298 // First remove all existing app windows. 8299 i=0; 8300 while (i < NW) { 8301 WindowState w = windows.get(i); 8302 if (w.mAppToken != null) { 8303 WindowState win = windows.remove(i); 8304 win.mRebuilding = true; 8305 mRebuildTmp[numRemoved] = win; 8306 mWindowsChanged = true; 8307 if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win); 8308 NW--; 8309 numRemoved++; 8310 continue; 8311 } else if (lastBelow == i-1) { 8312 if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) { 8313 lastBelow = i; 8314 } 8315 } 8316 i++; 8317 } 8318 8319 // Keep whatever windows were below the app windows still below, 8320 // by skipping them. 8321 lastBelow++; 8322 i = lastBelow; 8323 8324 // First add all of the exiting app tokens... these are no longer 8325 // in the main app list, but still have windows shown. We put them 8326 // in the back because now that the animation is over we no longer 8327 // will care about them. 8328 final ArrayList<TaskStack> stacks = displayContent.getStacks(); 8329 final int numStacks = stacks.size(); 8330 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 8331 AppTokenList exitingAppTokens = stacks.get(stackNdx).mExitingAppTokens; 8332 int NT = exitingAppTokens.size(); 8333 for (int j = 0; j < NT; j++) { 8334 i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j)); 8335 } 8336 } 8337 8338 // And add in the still active app tokens in Z order. 8339 for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { 8340 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks(); 8341 final int numTasks = tasks.size(); 8342 for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { 8343 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 8344 final int numTokens = tokens.size(); 8345 for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { 8346 final AppWindowToken wtoken = tokens.get(tokenNdx); 8347 if (wtoken.mDeferRemoval) { 8348 continue; 8349 } 8350 i = reAddAppWindowsLocked(displayContent, i, wtoken); 8351 } 8352 } 8353 } 8354 8355 i -= lastBelow; 8356 if (i != numRemoved) { 8357 Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " + 8358 numRemoved + " windows but added " + i, 8359 new RuntimeException("here").fillInStackTrace()); 8360 for (i=0; i<numRemoved; i++) { 8361 WindowState ws = mRebuildTmp[i]; 8362 if (ws.mRebuilding) { 8363 StringWriter sw = new StringWriter(); 8364 PrintWriter pw = new FastPrintWriter(sw, false, 1024); 8365 ws.dump(pw, "", true); 8366 pw.flush(); 8367 Slog.w(TAG, "This window was lost: " + ws); 8368 Slog.w(TAG, sw.toString()); 8369 ws.mWinAnimator.destroySurfaceLocked(); 8370 } 8371 } 8372 Slog.w(TAG, "Current app token list:"); 8373 dumpAppTokensLocked(); 8374 Slog.w(TAG, "Final window list:"); 8375 dumpWindowsLocked(); 8376 } 8377 } 8378 8379 private final void assignLayersLocked(WindowList windows) { 8380 int N = windows.size(); 8381 int curBaseLayer = 0; 8382 int curLayer = 0; 8383 int i; 8384 8385 if (DEBUG_LAYERS) Slog.v(TAG, "Assigning layers based on windows=" + windows, 8386 new RuntimeException("here").fillInStackTrace()); 8387 8388 boolean anyLayerChanged = false; 8389 8390 for (i=0; i<N; i++) { 8391 final WindowState w = windows.get(i); 8392 final WindowStateAnimator winAnimator = w.mWinAnimator; 8393 boolean layerChanged = false; 8394 int oldLayer = w.mLayer; 8395 if (w.mBaseLayer == curBaseLayer || w.mIsImWindow 8396 || (i > 0 && w.mIsWallpaper)) { 8397 curLayer += WINDOW_LAYER_MULTIPLIER; 8398 w.mLayer = curLayer; 8399 } else { 8400 curBaseLayer = curLayer = w.mBaseLayer; 8401 w.mLayer = curLayer; 8402 } 8403 if (w.mLayer != oldLayer) { 8404 layerChanged = true; 8405 anyLayerChanged = true; 8406 } 8407 final AppWindowToken wtoken = w.mAppToken; 8408 oldLayer = winAnimator.mAnimLayer; 8409 if (w.mTargetAppToken != null) { 8410 winAnimator.mAnimLayer = 8411 w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment; 8412 } else if (wtoken != null) { 8413 winAnimator.mAnimLayer = 8414 w.mLayer + wtoken.mAppAnimator.animLayerAdjustment; 8415 } else { 8416 winAnimator.mAnimLayer = w.mLayer; 8417 } 8418 if (w.mIsImWindow) { 8419 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment; 8420 } else if (w.mIsWallpaper) { 8421 winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment; 8422 } 8423 if (winAnimator.mAnimLayer != oldLayer) { 8424 layerChanged = true; 8425 anyLayerChanged = true; 8426 } 8427 if (layerChanged && w.getStack().isDimming(winAnimator)) { 8428 // Force an animation pass just to update the mDimLayer layer. 8429 scheduleAnimationLocked(); 8430 } 8431 if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": " 8432 + "mBase=" + w.mBaseLayer 8433 + " mLayer=" + w.mLayer 8434 + (wtoken == null ? 8435 "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment) 8436 + " =mAnimLayer=" + winAnimator.mAnimLayer); 8437 //System.out.println( 8438 // "Assigned layer " + curLayer + " to " + w.mClient.asBinder()); 8439 } 8440 8441 //TODO (multidisplay): Magnification is supported only for the default display. 8442 if (mAccessibilityController != null && anyLayerChanged 8443 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) { 8444 mAccessibilityController.onWindowLayersChangedLocked(); 8445 } 8446 } 8447 8448 private final void performLayoutAndPlaceSurfacesLocked() { 8449 int loopCount = 6; 8450 do { 8451 mTraversalScheduled = false; 8452 performLayoutAndPlaceSurfacesLockedLoop(); 8453 mH.removeMessages(H.DO_TRAVERSAL); 8454 loopCount--; 8455 } while (mTraversalScheduled && loopCount > 0); 8456 mInnerFields.mWallpaperActionPending = false; 8457 } 8458 8459 private boolean mInLayout = false; 8460 private final void performLayoutAndPlaceSurfacesLockedLoop() { 8461 if (mInLayout) { 8462 if (DEBUG) { 8463 throw new RuntimeException("Recursive call!"); 8464 } 8465 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers=" 8466 + Debug.getCallers(3)); 8467 return; 8468 } 8469 8470 if (mWaitingForConfig) { 8471 // Our configuration has changed (most likely rotation), but we 8472 // don't yet have the complete configuration to report to 8473 // applications. Don't do any window layout until we have it. 8474 return; 8475 } 8476 8477 if (!mDisplayReady) { 8478 // Not yet initialized, nothing to do. 8479 return; 8480 } 8481 8482 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout"); 8483 mInLayout = true; 8484 boolean recoveringMemory = false; 8485 8486 try { 8487 if (mForceRemoves != null) { 8488 recoveringMemory = true; 8489 // Wait a little bit for things to settle down, and off we go. 8490 for (int i=0; i<mForceRemoves.size(); i++) { 8491 WindowState ws = mForceRemoves.get(i); 8492 Slog.i(TAG, "Force removing: " + ws); 8493 removeWindowInnerLocked(ws.mSession, ws); 8494 } 8495 mForceRemoves = null; 8496 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout"); 8497 Object tmp = new Object(); 8498 synchronized (tmp) { 8499 try { 8500 tmp.wait(250); 8501 } catch (InterruptedException e) { 8502 } 8503 } 8504 } 8505 } catch (RuntimeException e) { 8506 Log.wtf(TAG, "Unhandled exception while force removing for memory", e); 8507 } 8508 8509 try { 8510 performLayoutAndPlaceSurfacesLockedInner(recoveringMemory); 8511 8512 mInLayout = false; 8513 8514 if (needsLayout()) { 8515 if (++mLayoutRepeatCount < 6) { 8516 requestTraversalLocked(); 8517 } else { 8518 Slog.e(TAG, "Performed 6 layouts in a row. Skipping"); 8519 mLayoutRepeatCount = 0; 8520 } 8521 } else { 8522 mLayoutRepeatCount = 0; 8523 } 8524 8525 if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) { 8526 mH.removeMessages(H.REPORT_WINDOWS_CHANGE); 8527 mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE); 8528 } 8529 } catch (RuntimeException e) { 8530 mInLayout = false; 8531 Log.wtf(TAG, "Unhandled exception while laying out windows", e); 8532 } 8533 8534 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 8535 } 8536 8537 private final void performLayoutLockedInner(final DisplayContent displayContent, 8538 boolean initial, boolean updateInputWindows) { 8539 if (!displayContent.layoutNeeded) { 8540 return; 8541 } 8542 displayContent.layoutNeeded = false; 8543 WindowList windows = displayContent.getWindowList(); 8544 boolean isDefaultDisplay = displayContent.isDefaultDisplay; 8545 8546 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 8547 final int dw = displayInfo.logicalWidth; 8548 final int dh = displayInfo.logicalHeight; 8549 8550 final int NFW = mFakeWindows.size(); 8551 for (int i=0; i<NFW; i++) { 8552 mFakeWindows.get(i).layout(dw, dh); 8553 } 8554 8555 final int N = windows.size(); 8556 int i; 8557 8558 if (DEBUG_LAYOUT) { 8559 Slog.v(TAG, "-------------------------------------"); 8560 Slog.v(TAG, "performLayout: needed=" 8561 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh); 8562 } 8563 8564 WindowStateAnimator universeBackground = null; 8565 8566 mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation); 8567 if (isDefaultDisplay) { 8568 // Not needed on non-default displays. 8569 mSystemDecorLayer = mPolicy.getSystemDecorLayerLw(); 8570 mScreenRect.set(0, 0, dw, dh); 8571 } 8572 8573 mPolicy.getContentRectLw(mTmpContentRect); 8574 displayContent.resize(mTmpContentRect); 8575 8576 int seq = mLayoutSeq+1; 8577 if (seq < 0) seq = 0; 8578 mLayoutSeq = seq; 8579 8580 boolean behindDream = false; 8581 8582 // First perform layout of any root windows (not attached 8583 // to another window). 8584 int topAttached = -1; 8585 for (i = N-1; i >= 0; i--) { 8586 final WindowState win = windows.get(i); 8587 8588 // Don't do layout of a window if it is not visible, or 8589 // soon won't be visible, to avoid wasting time and funky 8590 // changes while a window is animating away. 8591 final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) 8592 || win.isGoneForLayoutLw(); 8593 8594 if (DEBUG_LAYOUT && !win.mLayoutAttached) { 8595 Slog.v(TAG, "1ST PASS " + win 8596 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame 8597 + " mLayoutAttached=" + win.mLayoutAttached 8598 + " screen changed=" + win.isConfigChanged()); 8599 final AppWindowToken atoken = win.mAppToken; 8600 if (gone) Slog.v(TAG, " GONE: mViewVisibility=" 8601 + win.mViewVisibility + " mRelayoutCalled=" 8602 + win.mRelayoutCalled + " hidden=" 8603 + win.mRootToken.hidden + " hiddenRequested=" 8604 + (atoken != null && atoken.hiddenRequested) 8605 + " mAttachedHidden=" + win.mAttachedHidden); 8606 else Slog.v(TAG, " VIS: mViewVisibility=" 8607 + win.mViewVisibility + " mRelayoutCalled=" 8608 + win.mRelayoutCalled + " hidden=" 8609 + win.mRootToken.hidden + " hiddenRequested=" 8610 + (atoken != null && atoken.hiddenRequested) 8611 + " mAttachedHidden=" + win.mAttachedHidden); 8612 } 8613 8614 // If this view is GONE, then skip it -- keep the current 8615 // frame, and let the caller know so they can ignore it 8616 // if they want. (We do the normal layout for INVISIBLE 8617 // windows, since that means "perform layout as normal, 8618 // just don't display"). 8619 if (!gone || !win.mHaveFrame || win.mLayoutNeeded 8620 || ((win.isConfigChanged() || win.setInsetsChanged()) && 8621 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 || 8622 win.mAppToken != null && win.mAppToken.layoutConfigChanges)) 8623 || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) { 8624 if (!win.mLayoutAttached) { 8625 if (initial) { 8626 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); 8627 win.mContentChanged = false; 8628 } 8629 if (win.mAttrs.type == TYPE_DREAM) { 8630 // Don't layout windows behind a dream, so that if it 8631 // does stuff like hide the status bar we won't get a 8632 // bad transition when it goes away. 8633 behindDream = true; 8634 } 8635 win.mLayoutNeeded = false; 8636 win.prelayout(); 8637 mPolicy.layoutWindowLw(win, null); 8638 win.mLayoutSeq = seq; 8639 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" 8640 + win.mFrame + " mContainingFrame=" 8641 + win.mContainingFrame + " mDisplayFrame=" 8642 + win.mDisplayFrame); 8643 } else { 8644 if (topAttached < 0) topAttached = i; 8645 } 8646 } 8647 if (win.mViewVisibility == View.VISIBLE 8648 && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND 8649 && universeBackground == null) { 8650 universeBackground = win.mWinAnimator; 8651 } 8652 } 8653 8654 if (mAnimator.mUniverseBackground != universeBackground) { 8655 mFocusMayChange = true; 8656 mAnimator.mUniverseBackground = universeBackground; 8657 } 8658 8659 boolean attachedBehindDream = false; 8660 8661 // Now perform layout of attached windows, which usually 8662 // depend on the position of the window they are attached to. 8663 // XXX does not deal with windows that are attached to windows 8664 // that are themselves attached. 8665 for (i = topAttached; i >= 0; i--) { 8666 final WindowState win = windows.get(i); 8667 8668 if (win.mLayoutAttached) { 8669 if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win 8670 + " mHaveFrame=" + win.mHaveFrame 8671 + " mViewVisibility=" + win.mViewVisibility 8672 + " mRelayoutCalled=" + win.mRelayoutCalled); 8673 // If this view is GONE, then skip it -- keep the current 8674 // frame, and let the caller know so they can ignore it 8675 // if they want. (We do the normal layout for INVISIBLE 8676 // windows, since that means "perform layout as normal, 8677 // just don't display"). 8678 if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) { 8679 continue; 8680 } 8681 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled) 8682 || !win.mHaveFrame || win.mLayoutNeeded) { 8683 if (initial) { 8684 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial"); 8685 win.mContentChanged = false; 8686 } 8687 win.mLayoutNeeded = false; 8688 win.prelayout(); 8689 mPolicy.layoutWindowLw(win, win.mAttachedWindow); 8690 win.mLayoutSeq = seq; 8691 if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" 8692 + win.mFrame + " mContainingFrame=" 8693 + win.mContainingFrame + " mDisplayFrame=" 8694 + win.mDisplayFrame); 8695 } 8696 } else if (win.mAttrs.type == TYPE_DREAM) { 8697 // Don't layout windows behind a dream, so that if it 8698 // does stuff like hide the status bar we won't get a 8699 // bad transition when it goes away. 8700 attachedBehindDream = behindDream; 8701 } 8702 } 8703 8704 // Window frames may have changed. Tell the input dispatcher about it. 8705 mInputMonitor.setUpdateInputWindowsNeededLw(); 8706 if (updateInputWindows) { 8707 mInputMonitor.updateInputWindowsLw(false /*force*/); 8708 } 8709 8710 mPolicy.finishLayoutLw(); 8711 } 8712 8713 void makeWindowFreezingScreenIfNeededLocked(WindowState w) { 8714 // If the screen is currently frozen or off, then keep 8715 // it frozen/off until this window draws at its new 8716 // orientation. 8717 if (!okToDisplay()) { 8718 if (DEBUG_ORIENTATION) Slog.v(TAG, "Changing surface while display frozen: " + w); 8719 w.mOrientationChanging = true; 8720 w.mLastFreezeDuration = 0; 8721 mInnerFields.mOrientationChangeComplete = false; 8722 if (!mWindowsFreezingScreen) { 8723 mWindowsFreezingScreen = true; 8724 // XXX should probably keep timeout from 8725 // when we first froze the display. 8726 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); 8727 mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, 8728 WINDOW_FREEZE_TIMEOUT_DURATION); 8729 } 8730 } 8731 } 8732 8733 /** 8734 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. 8735 * @param windows List of windows on default display. 8736 * @return bitmap indicating if another pass through layout must be made. 8737 */ 8738 public int handleAppTransitionReadyLocked(WindowList windows) { 8739 int changes = 0; 8740 int i; 8741 int NN = mOpeningApps.size(); 8742 boolean goodToGo = true; 8743 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, 8744 "Checking " + NN + " opening apps (frozen=" 8745 + mDisplayFrozen + " timeout=" 8746 + mAppTransition.isTimeout() + ")..."); 8747 if (!mDisplayFrozen && !mAppTransition.isTimeout()) { 8748 // If the display isn't frozen, wait to do anything until 8749 // all of the apps are ready. Otherwise just go because 8750 // we'll unfreeze the display when everyone is ready. 8751 for (i=0; i<NN && goodToGo; i++) { 8752 AppWindowToken wtoken = mOpeningApps.valueAt(i); 8753 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, 8754 "Check opening app=" + wtoken + ": allDrawn=" 8755 + wtoken.allDrawn + " startingDisplayed=" 8756 + wtoken.startingDisplayed + " startingMoved=" 8757 + wtoken.startingMoved); 8758 if (!wtoken.allDrawn && !wtoken.startingDisplayed 8759 && !wtoken.startingMoved) { 8760 goodToGo = false; 8761 } 8762 } 8763 } 8764 if (goodToGo) { 8765 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO"); 8766 int transit = mAppTransition.getAppTransition(); 8767 if (mSkipAppTransitionAnimation) { 8768 transit = AppTransition.TRANSIT_UNSET; 8769 } 8770 mAppTransition.goodToGo(); 8771 mStartingIconInTransition = false; 8772 mSkipAppTransitionAnimation = false; 8773 8774 mH.removeMessages(H.APP_TRANSITION_TIMEOUT); 8775 8776 rebuildAppWindowListLocked(); 8777 8778 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper 8779 WindowState oldWallpaper = 8780 mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating() 8781 && !mWallpaperTarget.mWinAnimator.isDummyAnimation() 8782 ? null : mWallpaperTarget; 8783 8784 mInnerFields.mWallpaperMayChange = false; 8785 8786 // The top-most window will supply the layout params, 8787 // and we will determine it below. 8788 LayoutParams animLp = null; 8789 int bestAnimLayer = -1; 8790 boolean fullscreenAnim = false; 8791 boolean voiceInteraction = false; 8792 8793 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, 8794 "New wallpaper target=" + mWallpaperTarget 8795 + ", oldWallpaper=" + oldWallpaper 8796 + ", lower target=" + mLowerWallpaperTarget 8797 + ", upper target=" + mUpperWallpaperTarget); 8798 8799 boolean openingAppHasWallpaper = false; 8800 boolean closingAppHasWallpaper = false; 8801 final AppWindowToken lowerWallpaperAppToken; 8802 final AppWindowToken upperWallpaperAppToken; 8803 if (mLowerWallpaperTarget == null) { 8804 lowerWallpaperAppToken = upperWallpaperAppToken = null; 8805 } else { 8806 lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken; 8807 upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken; 8808 } 8809 8810 // Do a first pass through the tokens for two 8811 // things: 8812 // (1) Determine if both the closing and opening 8813 // app token sets are wallpaper targets, in which 8814 // case special animations are needed 8815 // (since the wallpaper needs to stay static 8816 // behind them). 8817 // (2) Find the layout params of the top-most 8818 // application window in the tokens, which is 8819 // what will control the animation theme. 8820 final int NC = mClosingApps.size(); 8821 NN = NC + mOpeningApps.size(); 8822 for (i=0; i<NN; i++) { 8823 final AppWindowToken wtoken; 8824 if (i < NC) { 8825 wtoken = mClosingApps.valueAt(i); 8826 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) { 8827 closingAppHasWallpaper = true; 8828 } 8829 } else { 8830 wtoken = mOpeningApps.valueAt(i - NC); 8831 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) { 8832 openingAppHasWallpaper = true; 8833 } 8834 } 8835 8836 voiceInteraction |= wtoken.voiceInteraction; 8837 8838 if (wtoken.appFullscreen) { 8839 WindowState ws = wtoken.findMainWindow(); 8840 if (ws != null) { 8841 animLp = ws.mAttrs; 8842 bestAnimLayer = ws.mLayer; 8843 fullscreenAnim = true; 8844 } 8845 } else if (!fullscreenAnim) { 8846 WindowState ws = wtoken.findMainWindow(); 8847 if (ws != null) { 8848 if (ws.mLayer > bestAnimLayer) { 8849 animLp = ws.mAttrs; 8850 bestAnimLayer = ws.mLayer; 8851 } 8852 } 8853 } 8854 } 8855 8856 mAnimateWallpaperWithTarget = false; 8857 if (closingAppHasWallpaper && openingAppHasWallpaper) { 8858 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!"); 8859 switch (transit) { 8860 case AppTransition.TRANSIT_ACTIVITY_OPEN: 8861 case AppTransition.TRANSIT_TASK_OPEN: 8862 case AppTransition.TRANSIT_TASK_TO_FRONT: 8863 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN; 8864 break; 8865 case AppTransition.TRANSIT_ACTIVITY_CLOSE: 8866 case AppTransition.TRANSIT_TASK_CLOSE: 8867 case AppTransition.TRANSIT_TASK_TO_BACK: 8868 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE; 8869 break; 8870 } 8871 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit); 8872 } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty() 8873 && !mOpeningApps.contains(oldWallpaper.mAppToken)) { 8874 // We are transitioning from an activity with 8875 // a wallpaper to one without. 8876 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE; 8877 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, 8878 "New transit away from wallpaper: " + transit); 8879 } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) { 8880 // We are transitioning from an activity without 8881 // a wallpaper to now showing the wallpaper 8882 transit = AppTransition.TRANSIT_WALLPAPER_OPEN; 8883 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, 8884 "New transit into wallpaper: " + transit); 8885 } else { 8886 mAnimateWallpaperWithTarget = true; 8887 } 8888 8889 // If all closing windows are obscured, then there is 8890 // no need to do an animation. This is the case, for 8891 // example, when this transition is being done behind 8892 // the lock screen. 8893 if (!mPolicy.allowAppAnimationsLw()) { 8894 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, 8895 "Animations disallowed by keyguard or dream."); 8896 animLp = null; 8897 } 8898 8899 AppWindowToken topOpeningApp = null; 8900 AppWindowToken topClosingApp = null; 8901 int topOpeningLayer = 0; 8902 int topClosingLayer = 0; 8903 8904 NN = mOpeningApps.size(); 8905 for (i=0; i<NN; i++) { 8906 AppWindowToken wtoken = mOpeningApps.valueAt(i); 8907 final AppWindowAnimator appAnimator = wtoken.mAppAnimator; 8908 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken); 8909 appAnimator.clearThumbnail(); 8910 appAnimator.animation = null; 8911 wtoken.inPendingTransaction = false; 8912 setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction); 8913 wtoken.updateReportedVisibilityLocked(); 8914 wtoken.waitingToShow = false; 8915 8916 appAnimator.mAllAppWinAnimators.clear(); 8917 final int N = wtoken.allAppWindows.size(); 8918 for (int j = 0; j < N; j++) { 8919 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator); 8920 } 8921 mAnimator.mAnimating |= appAnimator.showAllWindowsLocked(); 8922 8923 if (animLp != null) { 8924 int layer = -1; 8925 for (int j=0; j<wtoken.windows.size(); j++) { 8926 WindowState win = wtoken.windows.get(j); 8927 if (win.mWinAnimator.mAnimLayer > layer) { 8928 layer = win.mWinAnimator.mAnimLayer; 8929 } 8930 } 8931 if (topOpeningApp == null || layer > topOpeningLayer) { 8932 topOpeningApp = wtoken; 8933 topOpeningLayer = layer; 8934 } 8935 } 8936 } 8937 NN = mClosingApps.size(); 8938 for (i=0; i<NN; i++) { 8939 AppWindowToken wtoken = mClosingApps.valueAt(i); 8940 final AppWindowAnimator appAnimator = wtoken.mAppAnimator; 8941 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken); 8942 appAnimator.clearThumbnail(); 8943 appAnimator.animation = null; 8944 wtoken.inPendingTransaction = false; 8945 setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction); 8946 wtoken.updateReportedVisibilityLocked(); 8947 wtoken.waitingToHide = false; 8948 // Force the allDrawn flag, because we want to start 8949 // this guy's animations regardless of whether it's 8950 // gotten drawn. 8951 wtoken.allDrawn = true; 8952 wtoken.deferClearAllDrawn = false; 8953 8954 if (animLp != null) { 8955 int layer = -1; 8956 for (int j=0; j<wtoken.windows.size(); j++) { 8957 WindowState win = wtoken.windows.get(j); 8958 if (win.mWinAnimator.mAnimLayer > layer) { 8959 layer = win.mWinAnimator.mAnimLayer; 8960 } 8961 } 8962 if (topClosingApp == null || layer > topClosingLayer) { 8963 topClosingApp = wtoken; 8964 topClosingLayer = layer; 8965 } 8966 } 8967 } 8968 8969 AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null : 8970 topOpeningApp.mAppAnimator; 8971 AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null : 8972 topClosingApp.mAppAnimator; 8973 Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail(); 8974 if (nextAppTransitionThumbnail != null 8975 && openingAppAnimator != null && openingAppAnimator.animation != null && 8976 nextAppTransitionThumbnail.getConfig() != Config.ALPHA_8) { 8977 // This thumbnail animation is very special, we need to have 8978 // an extra surface with the thumbnail included with the animation. 8979 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(), 8980 nextAppTransitionThumbnail.getHeight()); 8981 try { 8982 // TODO(multi-display): support other displays 8983 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 8984 final Display display = displayContent.getDisplay(); 8985 final DisplayInfo displayInfo = displayContent.getDisplayInfo(); 8986 8987 // Create a new surface for the thumbnail 8988 SurfaceControl surfaceControl = new SurfaceControl(mFxSession, 8989 "thumbnail anim", dirty.width(), dirty.height(), 8990 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); 8991 surfaceControl.setLayerStack(display.getLayerStack()); 8992 if (SHOW_TRANSACTIONS) { 8993 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE"); 8994 } 8995 8996 // Draw the thumbnail onto the surface 8997 Surface drawSurface = new Surface(); 8998 drawSurface.copyFrom(surfaceControl); 8999 Canvas c = drawSurface.lockCanvas(dirty); 9000 c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null); 9001 drawSurface.unlockCanvasAndPost(c); 9002 drawSurface.release(); 9003 9004 // Get the thumbnail animation 9005 Animation anim; 9006 if (mAppTransition.isNextThumbnailTransitionAspectScaled()) { 9007 // For the new aspect-scaled transition, we want it to always show 9008 // above the animating opening/closing window, and we want to 9009 // synchronize its thumbnail surface with the surface for the 9010 // open/close animation (only on the way down) 9011 anim = mAppTransition.createThumbnailAspectScaleAnimationLocked( 9012 displayInfo.appWidth, displayInfo.appHeight, 9013 displayInfo.logicalWidth, transit); 9014 openingAppAnimator.thumbnailForceAboveLayer = Math.max(topOpeningLayer, 9015 topClosingLayer); 9016 openingAppAnimator.deferThumbnailDestruction = 9017 !mAppTransition.isNextThumbnailTransitionScaleUp(); 9018 if (openingAppAnimator.deferThumbnailDestruction) { 9019 if (closingAppAnimator != null && 9020 closingAppAnimator.animation != null) { 9021 closingAppAnimator.deferredThumbnail = surfaceControl; 9022 } 9023 } 9024 } else { 9025 anim = mAppTransition.createThumbnailScaleAnimationLocked( 9026 displayInfo.appWidth, displayInfo.appHeight, transit); 9027 } 9028 anim.restrictDuration(MAX_ANIMATION_DURATION); 9029 anim.scaleCurrentDuration(getTransitionAnimationScaleLocked()); 9030 9031 openingAppAnimator.thumbnail = surfaceControl; 9032 openingAppAnimator.thumbnailLayer = topOpeningLayer; 9033 openingAppAnimator.thumbnailAnimation = anim; 9034 openingAppAnimator.thumbnailX = mAppTransition.getStartingX(); 9035 openingAppAnimator.thumbnailY = mAppTransition.getStartingY(); 9036 } catch (OutOfResourcesException e) { 9037 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width() 9038 + " h=" + dirty.height(), e); 9039 openingAppAnimator.clearThumbnail(); 9040 } 9041 } 9042 9043 mAppTransition.postAnimationCallback(); 9044 mAppTransition.clear(); 9045 9046 mOpeningApps.clear(); 9047 mClosingApps.clear(); 9048 9049 // This has changed the visibility of windows, so perform 9050 // a new layout to get them all up-to-date. 9051 changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT 9052 | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; 9053 getDefaultDisplayContentLocked().layoutNeeded = true; 9054 9055 // TODO(multidisplay): IMEs are only supported on the default display. 9056 if (windows == getDefaultWindowListLocked() 9057 && !moveInputMethodWindowsIfNeededLocked(true)) { 9058 assignLayersLocked(windows); 9059 } 9060 updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, true /*updateInputWindows*/); 9061 mFocusMayChange = false; 9062 } 9063 9064 return changes; 9065 } 9066 9067 /** 9068 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. 9069 * @return bitmap indicating if another pass through layout must be made. 9070 */ 9071 private int handleAnimatingStoppedAndTransitionLocked() { 9072 int changes = 0; 9073 9074 mAppTransition.setIdle(); 9075 // Restore window app tokens to the ActivityManager views 9076 ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks(); 9077 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 9078 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks(); 9079 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 9080 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 9081 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 9082 tokens.get(tokenNdx).sendingToBottom = false; 9083 } 9084 } 9085 } 9086 rebuildAppWindowListLocked(); 9087 9088 changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; 9089 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, 9090 "Wallpaper layer changed: assigning layers + relayout"); 9091 moveInputMethodWindowsIfNeededLocked(true); 9092 mInnerFields.mWallpaperMayChange = true; 9093 // Since the window list has been rebuilt, focus might 9094 // have to be recomputed since the actual order of windows 9095 // might have changed again. 9096 mFocusMayChange = true; 9097 9098 return changes; 9099 } 9100 9101 private void updateResizingWindows(final WindowState w) { 9102 final WindowStateAnimator winAnimator = w.mWinAnimator; 9103 if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) { 9104 w.setInsetsChanged(); 9105 boolean configChanged = w.isConfigChanged(); 9106 if (DEBUG_CONFIGURATION && configChanged) { 9107 Slog.v(TAG, "Win " + w + " config changed: " 9108 + mCurConfiguration); 9109 } 9110 if (localLOGV) Slog.v(TAG, "Resizing " + w 9111 + ": configChanged=" + configChanged 9112 + " last=" + w.mLastFrame + " frame=" + w.mFrame); 9113 w.mLastFrame.set(w.mFrame); 9114 if (w.mContentInsetsChanged 9115 || w.mVisibleInsetsChanged 9116 || winAnimator.mSurfaceResized 9117 || configChanged) { 9118 if (DEBUG_RESIZE || DEBUG_ORIENTATION) { 9119 Slog.v(TAG, "Resize reasons for w=" + w + ": " 9120 + " contentInsetsChanged=" + w.mContentInsetsChanged 9121 + " " + w.mContentInsets.toShortString() 9122 + " visibleInsetsChanged=" + w.mVisibleInsetsChanged 9123 + " " + w.mVisibleInsets.toShortString() 9124 + " stableInsetsChanged=" + w.mStableInsetsChanged 9125 + " " + w.mStableInsets.toShortString() 9126 + " surfaceResized=" + winAnimator.mSurfaceResized 9127 + " configChanged=" + configChanged); 9128 } 9129 9130 w.mLastOverscanInsets.set(w.mOverscanInsets); 9131 w.mLastContentInsets.set(w.mContentInsets); 9132 w.mLastVisibleInsets.set(w.mVisibleInsets); 9133 w.mLastStableInsets.set(w.mStableInsets); 9134 makeWindowFreezingScreenIfNeededLocked(w); 9135 // If the orientation is changing, then we need to 9136 // hold off on unfreezing the display until this 9137 // window has been redrawn; to do that, we need 9138 // to go through the process of getting informed 9139 // by the application when it has finished drawing. 9140 if (w.mOrientationChanging) { 9141 if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG, 9142 "Orientation start waiting for draw mDrawState=DRAW_PENDING in " 9143 + w + ", surface " + winAnimator.mSurfaceControl); 9144 winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING; 9145 if (w.mAppToken != null) { 9146 w.mAppToken.allDrawn = false; 9147 w.mAppToken.deferClearAllDrawn = false; 9148 } 9149 } 9150 if (!mResizingWindows.contains(w)) { 9151 if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, 9152 "Resizing window " + w + " to " + winAnimator.mSurfaceW 9153 + "x" + winAnimator.mSurfaceH); 9154 mResizingWindows.add(w); 9155 } 9156 } else if (w.mOrientationChanging) { 9157 if (w.isDrawnLw()) { 9158 if (DEBUG_ORIENTATION) Slog.v(TAG, 9159 "Orientation not waiting for draw in " 9160 + w + ", surface " + winAnimator.mSurfaceControl); 9161 w.mOrientationChanging = false; 9162 w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() 9163 - mDisplayFreezeTime); 9164 } 9165 } 9166 } 9167 } 9168 9169 /** 9170 * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method. 9171 * 9172 * @param w WindowState this method is applied to. 9173 * @param currentTime The time which animations use for calculating transitions. 9174 * @param innerDw Width of app window. 9175 * @param innerDh Height of app window. 9176 */ 9177 private void handleNotObscuredLocked(final WindowState w, final long currentTime, 9178 final int innerDw, final int innerDh) { 9179 final WindowManager.LayoutParams attrs = w.mAttrs; 9180 final int attrFlags = attrs.flags; 9181 final boolean canBeSeen = w.isDisplayedLw(); 9182 final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn(); 9183 9184 if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) { 9185 // This window completely covers everything behind it, 9186 // so we want to leave all of them as undimmed (for 9187 // performance reasons). 9188 mInnerFields.mObscured = true; 9189 } 9190 9191 if (w.mHasSurface) { 9192 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) { 9193 mInnerFields.mHoldScreen = w.mSession; 9194 } 9195 if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0 9196 && mInnerFields.mScreenBrightness < 0) { 9197 mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness; 9198 } 9199 if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0 9200 && mInnerFields.mButtonBrightness < 0) { 9201 mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness; 9202 } 9203 if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0 9204 && mInnerFields.mUserActivityTimeout < 0) { 9205 mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout; 9206 } 9207 9208 final int type = attrs.type; 9209 if (canBeSeen 9210 && (type == TYPE_SYSTEM_DIALOG 9211 || type == TYPE_RECENTS_OVERLAY 9212 || type == TYPE_SYSTEM_ERROR 9213 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) { 9214 mInnerFields.mSyswin = true; 9215 } 9216 9217 if (canBeSeen) { 9218 // This function assumes that the contents of the default display are 9219 // processed first before secondary displays. 9220 final DisplayContent displayContent = w.getDisplayContent(); 9221 if (displayContent != null && displayContent.isDefaultDisplay) { 9222 // While a dream or keyguard is showing, obscure ordinary application 9223 // content on secondary displays (by forcibly enabling mirroring unless 9224 // there is other content we want to show) but still allow opaque 9225 // keyguard dialogs to be shown. 9226 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) { 9227 mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true; 9228 } 9229 mInnerFields.mDisplayHasContent = true; 9230 } else if (displayContent != null && 9231 (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays 9232 || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) { 9233 // Allow full screen keyguard presentation dialogs to be seen. 9234 mInnerFields.mDisplayHasContent = true; 9235 } 9236 if (mInnerFields.mPreferredRefreshRate == 0 9237 && w.mAttrs.preferredRefreshRate != 0) { 9238 mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate; 9239 } 9240 } 9241 } 9242 } 9243 9244 private void handleFlagDimBehind(WindowState w) { 9245 final WindowManager.LayoutParams attrs = w.mAttrs; 9246 if ((attrs.flags & FLAG_DIM_BEHIND) != 0 9247 && w.isDisplayedLw() 9248 && !w.mExiting) { 9249 final WindowStateAnimator winAnimator = w.mWinAnimator; 9250 final TaskStack stack = w.getStack(); 9251 stack.setDimmingTag(); 9252 if (!stack.isDimming(winAnimator)) { 9253 if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming."); 9254 stack.startDimmingIfNeeded(winAnimator); 9255 } 9256 } 9257 } 9258 9259 private void updateAllDrawnLocked(DisplayContent displayContent) { 9260 // See if any windows have been drawn, so they (and others 9261 // associated with them) can now be shown. 9262 ArrayList<TaskStack> stacks = displayContent.getStacks(); 9263 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { 9264 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks(); 9265 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 9266 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 9267 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 9268 final AppWindowToken wtoken = tokens.get(tokenNdx); 9269 if (!wtoken.allDrawn) { 9270 int numInteresting = wtoken.numInterestingWindows; 9271 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { 9272 if (DEBUG_VISIBILITY) Slog.v(TAG, 9273 "allDrawn: " + wtoken 9274 + " interesting=" + numInteresting 9275 + " drawn=" + wtoken.numDrawnWindows); 9276 wtoken.allDrawn = true; 9277 mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget(); 9278 } 9279 } 9280 } 9281 } 9282 } 9283 } 9284 9285 // "Something has changed! Let's make it correct now." 9286 private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) { 9287 if (DEBUG_WINDOW_TRACE) { 9288 Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by " 9289 + Debug.getCallers(3)); 9290 } 9291 9292 final long currentTime = SystemClock.uptimeMillis(); 9293 9294 int i; 9295 boolean updateInputWindowsNeeded = false; 9296 9297 if (mFocusMayChange) { 9298 mFocusMayChange = false; 9299 updateInputWindowsNeeded = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, 9300 false /*updateInputWindows*/); 9301 } 9302 9303 // Initialize state of exiting tokens. 9304 final int numDisplays = mDisplayContents.size(); 9305 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 9306 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 9307 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) { 9308 displayContent.mExitingTokens.get(i).hasVisible = false; 9309 } 9310 } 9311 9312 for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) { 9313 // Initialize state of exiting applications. 9314 final AppTokenList exitingAppTokens = 9315 mStackIdToStack.valueAt(stackNdx).mExitingAppTokens; 9316 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) { 9317 exitingAppTokens.get(tokenNdx).hasVisible = false; 9318 } 9319 } 9320 9321 mInnerFields.mHoldScreen = null; 9322 mInnerFields.mScreenBrightness = -1; 9323 mInnerFields.mButtonBrightness = -1; 9324 mInnerFields.mUserActivityTimeout = -1; 9325 mInnerFields.mObscureApplicationContentOnSecondaryDisplays = false; 9326 9327 mTransactionSequence++; 9328 9329 final DisplayContent defaultDisplay = getDefaultDisplayContentLocked(); 9330 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo(); 9331 final int defaultDw = defaultInfo.logicalWidth; 9332 final int defaultDh = defaultInfo.logicalHeight; 9333 9334 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 9335 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); 9336 SurfaceControl.openTransaction(); 9337 try { 9338 9339 if (mWatermark != null) { 9340 mWatermark.positionSurface(defaultDw, defaultDh); 9341 } 9342 if (mStrictModeFlash != null) { 9343 mStrictModeFlash.positionSurface(defaultDw, defaultDh); 9344 } 9345 if (mCircularDisplayMask != null) { 9346 mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mRotation); 9347 } 9348 9349 boolean focusDisplayed = false; 9350 9351 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 9352 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 9353 boolean updateAllDrawn = false; 9354 WindowList windows = displayContent.getWindowList(); 9355 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 9356 final int displayId = displayContent.getDisplayId(); 9357 final int dw = displayInfo.logicalWidth; 9358 final int dh = displayInfo.logicalHeight; 9359 final int innerDw = displayInfo.appWidth; 9360 final int innerDh = displayInfo.appHeight; 9361 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); 9362 9363 // Reset for each display. 9364 mInnerFields.mDisplayHasContent = false; 9365 mInnerFields.mPreferredRefreshRate = 0; 9366 9367 int repeats = 0; 9368 do { 9369 repeats++; 9370 if (repeats > 6) { 9371 Slog.w(TAG, "Animation repeat aborted after too many iterations"); 9372 displayContent.layoutNeeded = false; 9373 break; 9374 } 9375 9376 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner", 9377 displayContent.pendingLayoutChanges); 9378 9379 if ((displayContent.pendingLayoutChanges & 9380 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 && 9381 (adjustWallpaperWindowsLocked() & 9382 ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) { 9383 assignLayersLocked(windows); 9384 displayContent.layoutNeeded = true; 9385 } 9386 9387 if (isDefaultDisplay && (displayContent.pendingLayoutChanges 9388 & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) { 9389 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); 9390 if (updateOrientationFromAppTokensLocked(true)) { 9391 displayContent.layoutNeeded = true; 9392 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 9393 } 9394 } 9395 9396 if ((displayContent.pendingLayoutChanges 9397 & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) { 9398 displayContent.layoutNeeded = true; 9399 } 9400 9401 // FIRST LOOP: Perform a layout, if needed. 9402 if (repeats < 4) { 9403 performLayoutLockedInner(displayContent, repeats == 1, 9404 false /*updateInputWindows*/); 9405 } else { 9406 Slog.w(TAG, "Layout repeat skipped after too many iterations"); 9407 } 9408 9409 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think 9410 // it is animating. 9411 displayContent.pendingLayoutChanges = 0; 9412 9413 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number " 9414 + mLayoutRepeatCount, displayContent.pendingLayoutChanges); 9415 9416 if (isDefaultDisplay) { 9417 mPolicy.beginPostLayoutPolicyLw(dw, dh); 9418 for (i = windows.size() - 1; i >= 0; i--) { 9419 WindowState w = windows.get(i); 9420 if (w.mHasSurface) { 9421 mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs); 9422 } 9423 } 9424 displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw(); 9425 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats( 9426 "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges); 9427 } 9428 } while (displayContent.pendingLayoutChanges != 0); 9429 9430 mInnerFields.mObscured = false; 9431 mInnerFields.mSyswin = false; 9432 displayContent.resetDimming(); 9433 9434 // Only used if default window 9435 final boolean someoneLosingFocus = !mLosingFocus.isEmpty(); 9436 9437 final int N = windows.size(); 9438 for (i=N-1; i>=0; i--) { 9439 WindowState w = windows.get(i); 9440 final TaskStack stack = w.getStack(); 9441 if (stack == null) { 9442 continue; 9443 } 9444 9445 final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured; 9446 9447 // Update effect. 9448 w.mObscured = mInnerFields.mObscured; 9449 if (!mInnerFields.mObscured) { 9450 handleNotObscuredLocked(w, currentTime, innerDw, innerDh); 9451 } 9452 9453 if (!stack.testDimmingTag()) { 9454 handleFlagDimBehind(w); 9455 } 9456 9457 if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w) 9458 && w.isVisibleLw()) { 9459 // This is the wallpaper target and its obscured state 9460 // changed... make sure the current wallaper's visibility 9461 // has been updated accordingly. 9462 updateWallpaperVisibilityLocked(); 9463 } 9464 9465 final WindowStateAnimator winAnimator = w.mWinAnimator; 9466 9467 // If the window has moved due to its containing 9468 // content frame changing, then we'd like to animate 9469 // it. 9470 if (w.mHasSurface && w.shouldAnimateMove()) { 9471 // Frame has moved, containing content frame 9472 // has also moved, and we're not currently animating... 9473 // let's do something. 9474 Animation a = AnimationUtils.loadAnimation(mContext, 9475 com.android.internal.R.anim.window_move_from_decor); 9476 winAnimator.setAnimation(a); 9477 winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left; 9478 winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top; 9479 9480 //TODO (multidisplay): Accessibility supported only for the default display. 9481 if (mAccessibilityController != null 9482 && displayId == Display.DEFAULT_DISPLAY) { 9483 mAccessibilityController.onSomeWindowResizedOrMovedLocked(); 9484 } 9485 9486 try { 9487 w.mClient.moved(w.mFrame.left, w.mFrame.top); 9488 } catch (RemoteException e) { 9489 } 9490 } 9491 9492 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing"); 9493 w.mContentChanged = false; 9494 9495 // Moved from updateWindowsAndWallpaperLocked(). 9496 if (w.mHasSurface) { 9497 // Take care of the window being ready to display. 9498 final boolean committed = 9499 winAnimator.commitFinishDrawingLocked(currentTime); 9500 if (isDefaultDisplay && committed) { 9501 if (w.mAttrs.type == TYPE_DREAM) { 9502 // HACK: When a dream is shown, it may at that 9503 // point hide the lock screen. So we need to 9504 // redo the layout to let the phone window manager 9505 // make this happen. 9506 displayContent.pendingLayoutChanges |= 9507 WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; 9508 if (DEBUG_LAYOUT_REPEATS) { 9509 debugLayoutRepeats( 9510 "dream and commitFinishDrawingLocked true", 9511 displayContent.pendingLayoutChanges); 9512 } 9513 } 9514 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) { 9515 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, 9516 "First draw done in potential wallpaper target " + w); 9517 mInnerFields.mWallpaperMayChange = true; 9518 displayContent.pendingLayoutChanges |= 9519 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 9520 if (DEBUG_LAYOUT_REPEATS) { 9521 debugLayoutRepeats( 9522 "wallpaper and commitFinishDrawingLocked true", 9523 displayContent.pendingLayoutChanges); 9524 } 9525 } 9526 } 9527 9528 winAnimator.setSurfaceBoundariesLocked(recoveringMemory); 9529 9530 final AppWindowToken atoken = w.mAppToken; 9531 if (DEBUG_STARTING_WINDOW && atoken != null 9532 && w == atoken.startingWindow) { 9533 Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" 9534 + w.isOnScreen() + " allDrawn=" + atoken.allDrawn 9535 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen); 9536 } 9537 if (atoken != null 9538 && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) { 9539 if (atoken.lastTransactionSequence != mTransactionSequence) { 9540 atoken.lastTransactionSequence = mTransactionSequence; 9541 atoken.numInterestingWindows = atoken.numDrawnWindows = 0; 9542 atoken.startingDisplayed = false; 9543 } 9544 if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION) 9545 && !w.mExiting && !w.mDestroying) { 9546 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) { 9547 Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw() 9548 + ", isAnimating=" + winAnimator.isAnimating()); 9549 if (!w.isDrawnLw()) { 9550 Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl 9551 + " pv=" + w.mPolicyVisibility 9552 + " mDrawState=" + winAnimator.mDrawState 9553 + " ah=" + w.mAttachedHidden 9554 + " th=" + atoken.hiddenRequested 9555 + " a=" + winAnimator.mAnimating); 9556 } 9557 } 9558 if (w != atoken.startingWindow) { 9559 if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) { 9560 atoken.numInterestingWindows++; 9561 if (w.isDrawnLw()) { 9562 atoken.numDrawnWindows++; 9563 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, 9564 "tokenMayBeDrawn: " + atoken 9565 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen 9566 + " mAppFreezing=" + w.mAppFreezing); 9567 updateAllDrawn = true; 9568 } 9569 } 9570 } else if (w.isDrawnLw()) { 9571 atoken.startingDisplayed = true; 9572 } 9573 } 9574 } 9575 } 9576 9577 if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus) 9578 && w.isDisplayedLw()) { 9579 focusDisplayed = true; 9580 } 9581 9582 updateResizingWindows(w); 9583 } 9584 9585 mDisplayManagerInternal.setDisplayProperties(displayId, 9586 mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate, 9587 true /* inTraversal, must call performTraversalInTrans... below */); 9588 9589 getDisplayContentLocked(displayId).stopDimmingIfNeeded(); 9590 9591 if (updateAllDrawn) { 9592 updateAllDrawnLocked(displayContent); 9593 } 9594 } 9595 9596 if (focusDisplayed) { 9597 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS); 9598 } 9599 9600 // Give the display manager a chance to adjust properties 9601 // like display rotation if it needs to. 9602 mDisplayManagerInternal.performTraversalInTransactionFromWindowManager(); 9603 9604 } catch (RuntimeException e) { 9605 Log.wtf(TAG, "Unhandled exception in Window Manager", e); 9606 } finally { 9607 SurfaceControl.closeTransaction(); 9608 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, 9609 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); 9610 } 9611 9612 final WindowList defaultWindows = defaultDisplay.getWindowList(); 9613 9614 // If we are ready to perform an app transition, check through 9615 // all of the app tokens to be shown and see if they are ready 9616 // to go. 9617 if (mAppTransition.isReady()) { 9618 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows); 9619 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked", 9620 defaultDisplay.pendingLayoutChanges); 9621 } 9622 9623 if (!mAnimator.mAnimating && mAppTransition.isRunning()) { 9624 // We have finished the animation of an app transition. To do 9625 // this, we have delayed a lot of operations like showing and 9626 // hiding apps, moving apps in Z-order, etc. The app token list 9627 // reflects the correct Z-order, but the window list may now 9628 // be out of sync with it. So here we will just rebuild the 9629 // entire app window list. Fun! 9630 defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked(); 9631 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock", 9632 defaultDisplay.pendingLayoutChanges); 9633 } 9634 9635 if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0 9636 && !mAppTransition.isReady()) { 9637 // At this point, there was a window with a wallpaper that 9638 // was force hiding other windows behind it, but now it 9639 // is going away. This may be simple -- just animate 9640 // away the wallpaper and its window -- or it may be 9641 // hard -- the wallpaper now needs to be shown behind 9642 // something that was hidden. 9643 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; 9644 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked", 9645 defaultDisplay.pendingLayoutChanges); 9646 } 9647 mInnerFields.mWallpaperForceHidingChanged = false; 9648 9649 if (mInnerFields.mWallpaperMayChange) { 9650 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting"); 9651 defaultDisplay.pendingLayoutChanges |= 9652 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 9653 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange", 9654 defaultDisplay.pendingLayoutChanges); 9655 } 9656 9657 if (mFocusMayChange) { 9658 mFocusMayChange = false; 9659 if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, 9660 false /*updateInputWindows*/)) { 9661 updateInputWindowsNeeded = true; 9662 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; 9663 } 9664 } 9665 9666 if (needsLayout()) { 9667 defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; 9668 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded", 9669 defaultDisplay.pendingLayoutChanges); 9670 } 9671 9672 for (i = mResizingWindows.size() - 1; i >= 0; i--) { 9673 WindowState win = mResizingWindows.get(i); 9674 if (win.mAppFreezing) { 9675 // Don't remove this window until rotation has completed. 9676 continue; 9677 } 9678 win.reportResized(); 9679 mResizingWindows.remove(i); 9680 } 9681 9682 if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG, 9683 "With display frozen, orientationChangeComplete=" 9684 + mInnerFields.mOrientationChangeComplete); 9685 if (mInnerFields.mOrientationChangeComplete) { 9686 if (mWindowsFreezingScreen) { 9687 mWindowsFreezingScreen = false; 9688 mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource; 9689 mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT); 9690 } 9691 stopFreezingDisplayLocked(); 9692 } 9693 9694 // Destroy the surface of any windows that are no longer visible. 9695 boolean wallpaperDestroyed = false; 9696 i = mDestroySurface.size(); 9697 if (i > 0) { 9698 do { 9699 i--; 9700 WindowState win = mDestroySurface.get(i); 9701 win.mDestroying = false; 9702 if (mInputMethodWindow == win) { 9703 mInputMethodWindow = null; 9704 } 9705 if (win == mWallpaperTarget) { 9706 wallpaperDestroyed = true; 9707 } 9708 win.mWinAnimator.destroySurfaceLocked(); 9709 } while (i > 0); 9710 mDestroySurface.clear(); 9711 } 9712 9713 // Time to remove any exiting tokens? 9714 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 9715 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 9716 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens; 9717 for (i = exitingTokens.size() - 1; i >= 0; i--) { 9718 WindowToken token = exitingTokens.get(i); 9719 if (!token.hasVisible) { 9720 exitingTokens.remove(i); 9721 if (token.windowType == TYPE_WALLPAPER) { 9722 mWallpaperTokens.remove(token); 9723 } 9724 } 9725 } 9726 } 9727 9728 // Time to remove any exiting applications? 9729 for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) { 9730 // Initialize state of exiting applications. 9731 final AppTokenList exitingAppTokens = 9732 mStackIdToStack.valueAt(stackNdx).mExitingAppTokens; 9733 for (i = exitingAppTokens.size() - 1; i >= 0; i--) { 9734 AppWindowToken token = exitingAppTokens.get(i); 9735 if (!token.hasVisible && !mClosingApps.contains(token) && !token.mDeferRemoval) { 9736 // Make sure there is no animation running on this token, 9737 // so any windows associated with it will be removed as 9738 // soon as their animations are complete 9739 token.mAppAnimator.clearAnimation(); 9740 token.mAppAnimator.animating = false; 9741 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, 9742 "performLayout: App token exiting now removed" + token); 9743 removeAppFromTaskLocked(token); 9744 exitingAppTokens.remove(i); 9745 } 9746 } 9747 } 9748 9749 if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) { 9750 for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) { 9751 try { 9752 mRelayoutWhileAnimating.get(j).mClient.doneAnimating(); 9753 } catch (RemoteException e) { 9754 } 9755 } 9756 mRelayoutWhileAnimating.clear(); 9757 } 9758 9759 if (wallpaperDestroyed) { 9760 defaultDisplay.pendingLayoutChanges |= 9761 WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; 9762 defaultDisplay.layoutNeeded = true; 9763 } 9764 9765 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 9766 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 9767 if (displayContent.pendingLayoutChanges != 0) { 9768 displayContent.layoutNeeded = true; 9769 } 9770 } 9771 9772 // Finally update all input windows now that the window changes have stabilized. 9773 mInputMonitor.updateInputWindowsLw(true /*force*/); 9774 9775 setHoldScreenLocked(mInnerFields.mHoldScreen); 9776 if (!mDisplayFrozen) { 9777 if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) { 9778 mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1); 9779 } else { 9780 mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager( 9781 toBrightnessOverride(mInnerFields.mScreenBrightness)); 9782 } 9783 if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) { 9784 mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1); 9785 } else { 9786 mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager( 9787 toBrightnessOverride(mInnerFields.mButtonBrightness)); 9788 } 9789 mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager( 9790 mInnerFields.mUserActivityTimeout); 9791 } 9792 9793 if (mTurnOnScreen) { 9794 if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!"); 9795 mPowerManager.wakeUp(SystemClock.uptimeMillis()); 9796 mTurnOnScreen = false; 9797 } 9798 9799 if (mInnerFields.mUpdateRotation) { 9800 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); 9801 if (updateRotationUncheckedLocked(false)) { 9802 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 9803 } else { 9804 mInnerFields.mUpdateRotation = false; 9805 } 9806 } 9807 9808 if (mWaitingForDrawnCallback != null || 9809 (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded && 9810 !mInnerFields.mUpdateRotation)) { 9811 checkDrawnWindowsLocked(); 9812 } 9813 9814 final int N = mPendingRemove.size(); 9815 if (N > 0) { 9816 if (mPendingRemoveTmp.length < N) { 9817 mPendingRemoveTmp = new WindowState[N+10]; 9818 } 9819 mPendingRemove.toArray(mPendingRemoveTmp); 9820 mPendingRemove.clear(); 9821 DisplayContentList displayList = new DisplayContentList(); 9822 for (i = 0; i < N; i++) { 9823 WindowState w = mPendingRemoveTmp[i]; 9824 removeWindowInnerLocked(w.mSession, w); 9825 final DisplayContent displayContent = w.getDisplayContent(); 9826 if (displayContent != null && !displayList.contains(displayContent)) { 9827 displayList.add(displayContent); 9828 } 9829 } 9830 9831 for (DisplayContent displayContent : displayList) { 9832 assignLayersLocked(displayContent.getWindowList()); 9833 displayContent.layoutNeeded = true; 9834 } 9835 } 9836 9837 // Remove all deferred displays stacks, tasks, and activities. 9838 for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) { 9839 mDisplayContents.valueAt(displayNdx).checkForDeferredActions(); 9840 } 9841 9842 if (updateInputWindowsNeeded) { 9843 mInputMonitor.updateInputWindowsLw(false /*force*/); 9844 } 9845 setFocusedStackFrame(); 9846 9847 // Check to see if we are now in a state where the screen should 9848 // be enabled, because the window obscured flags have changed. 9849 enableScreenIfNeededLocked(); 9850 9851 scheduleAnimationLocked(); 9852 9853 if (DEBUG_WINDOW_TRACE) { 9854 Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating=" 9855 + mAnimator.mAnimating); 9856 } 9857 } 9858 9859 private int toBrightnessOverride(float value) { 9860 return (int)(value * PowerManager.BRIGHTNESS_ON); 9861 } 9862 9863 void checkDrawnWindowsLocked() { 9864 if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) { 9865 return; 9866 } 9867 for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) { 9868 WindowState win = mWaitingForDrawn.get(j); 9869 if (DEBUG_SCREEN_ON) Slog.i(TAG, "Waiting for drawn " + win + 9870 ": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() + 9871 " mHasSurface=" + win.mHasSurface + 9872 " drawState=" + win.mWinAnimator.mDrawState); 9873 if (win.mRemoved || !win.mHasSurface) { 9874 // Window has been removed; no draw will now happen, so stop waiting. 9875 if (DEBUG_SCREEN_ON) Slog.w(TAG, "Aborted waiting for drawn: " + win); 9876 mWaitingForDrawn.remove(win); 9877 } else if (win.hasDrawnLw()) { 9878 // Window is now drawn (and shown). 9879 if (DEBUG_SCREEN_ON) Slog.d(TAG, "Window drawn win=" + win); 9880 mWaitingForDrawn.remove(win); 9881 } 9882 } 9883 if (mWaitingForDrawn.isEmpty()) { 9884 if (DEBUG_SCREEN_ON) Slog.d(TAG, "All windows drawn!"); 9885 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); 9886 mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN); 9887 } 9888 } 9889 9890 void setHoldScreenLocked(final Session newHoldScreen) { 9891 final boolean hold = newHoldScreen != null; 9892 9893 if (hold && mHoldingScreenOn != newHoldScreen) { 9894 mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid)); 9895 } 9896 mHoldingScreenOn = newHoldScreen; 9897 9898 final boolean state = mHoldingScreenWakeLock.isHeld(); 9899 if (hold != state) { 9900 if (hold) { 9901 mHoldingScreenWakeLock.acquire(); 9902 mPolicy.keepScreenOnStartedLw(); 9903 } else { 9904 mPolicy.keepScreenOnStoppedLw(); 9905 mHoldingScreenWakeLock.release(); 9906 } 9907 } 9908 } 9909 9910 void requestTraversal() { 9911 synchronized (mWindowMap) { 9912 requestTraversalLocked(); 9913 } 9914 } 9915 9916 void requestTraversalLocked() { 9917 if (!mTraversalScheduled) { 9918 mTraversalScheduled = true; 9919 mH.sendEmptyMessage(H.DO_TRAVERSAL); 9920 } 9921 } 9922 9923 /** Note that Locked in this case is on mLayoutToAnim */ 9924 void scheduleAnimationLocked() { 9925 if (!mAnimationScheduled) { 9926 mAnimationScheduled = true; 9927 mChoreographer.postCallback( 9928 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null); 9929 } 9930 } 9931 9932 private boolean needsLayout() { 9933 final int numDisplays = mDisplayContents.size(); 9934 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 9935 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 9936 if (displayContent.layoutNeeded) { 9937 return true; 9938 } 9939 } 9940 return false; 9941 } 9942 9943 boolean copyAnimToLayoutParamsLocked() { 9944 boolean doRequest = false; 9945 9946 final int bulkUpdateParams = mAnimator.mBulkUpdateParams; 9947 if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) { 9948 mInnerFields.mUpdateRotation = true; 9949 doRequest = true; 9950 } 9951 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { 9952 mInnerFields.mWallpaperMayChange = true; 9953 doRequest = true; 9954 } 9955 if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { 9956 mInnerFields.mWallpaperForceHidingChanged = true; 9957 doRequest = true; 9958 } 9959 if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) { 9960 mInnerFields.mOrientationChangeComplete = false; 9961 } else { 9962 mInnerFields.mOrientationChangeComplete = true; 9963 mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource; 9964 if (mWindowsFreezingScreen) { 9965 doRequest = true; 9966 } 9967 } 9968 if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) { 9969 mTurnOnScreen = true; 9970 } 9971 if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) { 9972 mInnerFields.mWallpaperActionPending = true; 9973 } 9974 9975 return doRequest; 9976 } 9977 9978 /** If a window that has an animation specifying a colored background and the current wallpaper 9979 * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to 9980 * suddenly disappear. */ 9981 int adjustAnimationBackground(WindowStateAnimator winAnimator) { 9982 WindowList windows = winAnimator.mWin.getWindowList(); 9983 for (int i = windows.size() - 1; i >= 0; --i) { 9984 WindowState testWin = windows.get(i); 9985 if (testWin.mIsWallpaper && testWin.isVisibleNow()) { 9986 return testWin.mWinAnimator.mAnimLayer; 9987 } 9988 } 9989 return winAnimator.mAnimLayer; 9990 } 9991 9992 boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation, 9993 boolean secure) { 9994 final SurfaceControl surface = winAnimator.mSurfaceControl; 9995 boolean leakedSurface = false; 9996 boolean killedApps = false; 9997 9998 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(), 9999 winAnimator.mSession.mPid, operation); 10000 10001 if (mForceRemoves == null) { 10002 mForceRemoves = new ArrayList<WindowState>(); 10003 } 10004 10005 long callingIdentity = Binder.clearCallingIdentity(); 10006 try { 10007 // There was some problem... first, do a sanity check of the 10008 // window list to make sure we haven't left any dangling surfaces 10009 // around. 10010 10011 Slog.i(TAG, "Out of memory for surface! Looking for leaks..."); 10012 final int numDisplays = mDisplayContents.size(); 10013 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10014 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); 10015 final int numWindows = windows.size(); 10016 for (int winNdx = 0; winNdx < numWindows; ++winNdx) { 10017 final WindowState ws = windows.get(winNdx); 10018 WindowStateAnimator wsa = ws.mWinAnimator; 10019 if (wsa.mSurfaceControl != null) { 10020 if (!mSessions.contains(wsa.mSession)) { 10021 Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): " 10022 + ws + " surface=" + wsa.mSurfaceControl 10023 + " token=" + ws.mToken 10024 + " pid=" + ws.mSession.mPid 10025 + " uid=" + ws.mSession.mUid); 10026 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null); 10027 wsa.mSurfaceControl.destroy(); 10028 wsa.mSurfaceShown = false; 10029 wsa.mSurfaceControl = null; 10030 ws.mHasSurface = false; 10031 mForceRemoves.add(ws); 10032 leakedSurface = true; 10033 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) { 10034 Slog.w(TAG, "LEAKED SURFACE (app token hidden): " 10035 + ws + " surface=" + wsa.mSurfaceControl 10036 + " token=" + ws.mAppToken); 10037 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null); 10038 wsa.mSurfaceControl.destroy(); 10039 wsa.mSurfaceShown = false; 10040 wsa.mSurfaceControl = null; 10041 ws.mHasSurface = false; 10042 leakedSurface = true; 10043 } 10044 } 10045 } 10046 } 10047 10048 if (!leakedSurface) { 10049 Slog.w(TAG, "No leaked surfaces; killing applicatons!"); 10050 SparseIntArray pidCandidates = new SparseIntArray(); 10051 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10052 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); 10053 final int numWindows = windows.size(); 10054 for (int winNdx = 0; winNdx < numWindows; ++winNdx) { 10055 final WindowState ws = windows.get(winNdx); 10056 if (mForceRemoves.contains(ws)) { 10057 continue; 10058 } 10059 WindowStateAnimator wsa = ws.mWinAnimator; 10060 if (wsa.mSurfaceControl != null) { 10061 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid); 10062 } 10063 } 10064 if (pidCandidates.size() > 0) { 10065 int[] pids = new int[pidCandidates.size()]; 10066 for (int i=0; i<pids.length; i++) { 10067 pids[i] = pidCandidates.keyAt(i); 10068 } 10069 try { 10070 if (mActivityManager.killPids(pids, "Free memory", secure)) { 10071 killedApps = true; 10072 } 10073 } catch (RemoteException e) { 10074 } 10075 } 10076 } 10077 } 10078 10079 if (leakedSurface || killedApps) { 10080 // We managed to reclaim some memory, so get rid of the trouble 10081 // surface and ask the app to request another one. 10082 Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry."); 10083 if (surface != null) { 10084 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin, 10085 "RECOVER DESTROY", null); 10086 surface.destroy(); 10087 winAnimator.mSurfaceShown = false; 10088 winAnimator.mSurfaceControl = null; 10089 winAnimator.mWin.mHasSurface = false; 10090 scheduleRemoveStartingWindow(winAnimator.mWin.mAppToken); 10091 } 10092 10093 try { 10094 winAnimator.mWin.mClient.dispatchGetNewSurface(); 10095 } catch (RemoteException e) { 10096 } 10097 } 10098 } finally { 10099 Binder.restoreCallingIdentity(callingIdentity); 10100 } 10101 10102 return leakedSurface || killedApps; 10103 } 10104 10105 private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) { 10106 WindowState newFocus = computeFocusedWindowLocked(); 10107 if (mCurrentFocus != newFocus) { 10108 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus"); 10109 // This check makes sure that we don't already have the focus 10110 // change message pending. 10111 mH.removeMessages(H.REPORT_FOCUS_CHANGE); 10112 mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE); 10113 // TODO(multidisplay): Focused windows on default display only. 10114 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 10115 final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked( 10116 mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS 10117 && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES); 10118 if (imWindowChanged) { 10119 displayContent.layoutNeeded = true; 10120 newFocus = computeFocusedWindowLocked(); 10121 } 10122 10123 if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG, "Changing focus from " + 10124 mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4)); 10125 final WindowState oldFocus = mCurrentFocus; 10126 mCurrentFocus = newFocus; 10127 mLosingFocus.remove(newFocus); 10128 10129 // TODO(multidisplay): Accessibilty supported only of default desiplay. 10130 if (mAccessibilityController != null 10131 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) { 10132 mAccessibilityController.onWindowFocusChangedLocked(); 10133 } 10134 10135 int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus); 10136 10137 if (imWindowChanged && oldFocus != mInputMethodWindow) { 10138 // Focus of the input method window changed. Perform layout if needed. 10139 if (mode == UPDATE_FOCUS_PLACING_SURFACES) { 10140 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows); 10141 focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; 10142 } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) { 10143 // Client will do the layout, but we need to assign layers 10144 // for handleNewWindowLocked() below. 10145 assignLayersLocked(displayContent.getWindowList()); 10146 } 10147 } 10148 10149 if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) { 10150 // The change in focus caused us to need to do a layout. Okay. 10151 displayContent.layoutNeeded = true; 10152 if (mode == UPDATE_FOCUS_PLACING_SURFACES) { 10153 performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows); 10154 } 10155 } 10156 10157 if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) { 10158 // If we defer assigning layers, then the caller is responsible for 10159 // doing this part. 10160 mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows); 10161 } 10162 10163 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); 10164 return true; 10165 } 10166 return false; 10167 } 10168 10169 private WindowState computeFocusedWindowLocked() { 10170 if (mAnimator.mUniverseBackground != null 10171 && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) { 10172 return mAnimator.mUniverseBackground.mWin; 10173 } 10174 10175 final int displayCount = mDisplayContents.size(); 10176 for (int i = 0; i < displayCount; i++) { 10177 final DisplayContent displayContent = mDisplayContents.valueAt(i); 10178 WindowState win = findFocusedWindowLocked(displayContent); 10179 if (win != null) { 10180 return win; 10181 } 10182 } 10183 return null; 10184 } 10185 10186 private WindowState findFocusedWindowLocked(DisplayContent displayContent) { 10187 final WindowList windows = displayContent.getWindowList(); 10188 for (int i = windows.size() - 1; i >= 0; i--) { 10189 final WindowState win = windows.get(i); 10190 10191 if (localLOGV || DEBUG_FOCUS) Slog.v( 10192 TAG, "Looking for focus: " + i 10193 + " = " + win 10194 + ", flags=" + win.mAttrs.flags 10195 + ", canReceive=" + win.canReceiveKeys()); 10196 10197 AppWindowToken wtoken = win.mAppToken; 10198 10199 // If this window's application has been removed, just skip it. 10200 if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { 10201 if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + wtoken + " because " 10202 + (wtoken.removed ? "removed" : "sendingToBottom")); 10203 continue; 10204 } 10205 10206 if (!win.canReceiveKeys()) { 10207 continue; 10208 } 10209 10210 // Descend through all of the app tokens and find the first that either matches 10211 // win.mAppToken (return win) or mFocusedApp (return null). 10212 if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING && 10213 mFocusedApp != null) { 10214 ArrayList<Task> tasks = displayContent.getTasks(); 10215 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { 10216 AppTokenList tokens = tasks.get(taskNdx).mAppTokens; 10217 int tokenNdx = tokens.size() - 1; 10218 for ( ; tokenNdx >= 0; --tokenNdx) { 10219 final AppWindowToken token = tokens.get(tokenNdx); 10220 if (wtoken == token) { 10221 break; 10222 } 10223 if (mFocusedApp == token) { 10224 // Whoops, we are below the focused app... no focus for you! 10225 if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG, 10226 "findFocusedWindow: Reached focused app=" + mFocusedApp); 10227 return null; 10228 } 10229 } 10230 if (tokenNdx >= 0) { 10231 // Early exit from loop, must have found the matching token. 10232 break; 10233 } 10234 } 10235 } 10236 10237 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: Found new focus @ " + i + 10238 " = " + win); 10239 return win; 10240 } 10241 10242 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: No focusable windows."); 10243 return null; 10244 } 10245 10246 private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) { 10247 if (mDisplayFrozen) { 10248 return; 10249 } 10250 10251 if (!mDisplayReady || !mPolicy.isScreenOnFully()) { 10252 // No need to freeze the screen before the system is ready or if 10253 // the screen is off. 10254 return; 10255 } 10256 10257 mScreenFrozenLock.acquire(); 10258 10259 mDisplayFrozen = true; 10260 mDisplayFreezeTime = SystemClock.elapsedRealtime(); 10261 mLastFinishedFreezeSource = null; 10262 10263 mInputMonitor.freezeInputDispatchingLw(); 10264 10265 // Clear the last input window -- that is just used for 10266 // clean transitions between IMEs, and if we are freezing 10267 // the screen then the whole world is changing behind the scenes. 10268 mPolicy.setLastInputMethodWindowLw(null, null); 10269 10270 if (mAppTransition.isTransitionSet()) { 10271 mAppTransition.freeze(); 10272 } 10273 10274 if (PROFILE_ORIENTATION) { 10275 File file = new File("/data/system/frozen"); 10276 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 10277 } 10278 10279 if (CUSTOM_SCREEN_ROTATION) { 10280 mExitAnimId = exitAnim; 10281 mEnterAnimId = enterAnim; 10282 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 10283 final int displayId = displayContent.getDisplayId(); 10284 ScreenRotationAnimation screenRotationAnimation = 10285 mAnimator.getScreenRotationAnimationLocked(displayId); 10286 if (screenRotationAnimation != null) { 10287 screenRotationAnimation.kill(); 10288 } 10289 10290 // Check whether the current screen contains any secure content. 10291 boolean isSecure = false; 10292 final WindowList windows = getDefaultWindowListLocked(); 10293 final int N = windows.size(); 10294 for (int i = 0; i < N; i++) { 10295 WindowState ws = windows.get(i); 10296 if (ws.isOnScreen() && (ws.mAttrs.flags & FLAG_SECURE) != 0) { 10297 isSecure = true; 10298 break; 10299 } 10300 } 10301 10302 // TODO(multidisplay): rotation on main screen only. 10303 displayContent.updateDisplayInfo(); 10304 screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent, 10305 mFxSession, inTransaction, mPolicy.isDefaultOrientationForced(), isSecure); 10306 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation); 10307 } 10308 } 10309 10310 private void stopFreezingDisplayLocked() { 10311 if (!mDisplayFrozen) { 10312 return; 10313 } 10314 10315 if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen 10316 || mClientFreezingScreen) { 10317 if (DEBUG_ORIENTATION) Slog.d(TAG, 10318 "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig 10319 + ", mAppsFreezingScreen=" + mAppsFreezingScreen 10320 + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen 10321 + ", mClientFreezingScreen=" + mClientFreezingScreen); 10322 return; 10323 } 10324 10325 mDisplayFrozen = false; 10326 mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime); 10327 StringBuilder sb = new StringBuilder(128); 10328 sb.append("Screen frozen for "); 10329 TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb); 10330 if (mLastFinishedFreezeSource != null) { 10331 sb.append(" due to "); 10332 sb.append(mLastFinishedFreezeSource); 10333 } 10334 Slog.i(TAG, sb.toString()); 10335 mH.removeMessages(H.APP_FREEZE_TIMEOUT); 10336 mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); 10337 if (PROFILE_ORIENTATION) { 10338 Debug.stopMethodTracing(); 10339 } 10340 10341 boolean updateRotation = false; 10342 10343 final DisplayContent displayContent = getDefaultDisplayContentLocked(); 10344 final int displayId = displayContent.getDisplayId(); 10345 ScreenRotationAnimation screenRotationAnimation = 10346 mAnimator.getScreenRotationAnimationLocked(displayId); 10347 if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null 10348 && screenRotationAnimation.hasScreenshot()) { 10349 if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation"); 10350 // TODO(multidisplay): rotation on main screen only. 10351 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 10352 // Get rotation animation again, with new top window 10353 boolean isDimming = displayContent.isDimming(); 10354 if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) { 10355 mExitAnimId = mEnterAnimId = 0; 10356 } 10357 if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, 10358 getTransitionAnimationScaleLocked(), displayInfo.logicalWidth, 10359 displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) { 10360 scheduleAnimationLocked(); 10361 } else { 10362 screenRotationAnimation.kill(); 10363 screenRotationAnimation = null; 10364 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation); 10365 updateRotation = true; 10366 } 10367 } else { 10368 if (screenRotationAnimation != null) { 10369 screenRotationAnimation.kill(); 10370 screenRotationAnimation = null; 10371 mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation); 10372 } 10373 updateRotation = true; 10374 } 10375 10376 mInputMonitor.thawInputDispatchingLw(); 10377 10378 boolean configChanged; 10379 10380 // While the display is frozen we don't re-compute the orientation 10381 // to avoid inconsistent states. However, something interesting 10382 // could have actually changed during that time so re-evaluate it 10383 // now to catch that. 10384 configChanged = updateOrientationFromAppTokensLocked(false); 10385 10386 // A little kludge: a lot could have happened while the 10387 // display was frozen, so now that we are coming back we 10388 // do a gc so that any remote references the system 10389 // processes holds on others can be released if they are 10390 // no longer needed. 10391 mH.removeMessages(H.FORCE_GC); 10392 mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000); 10393 10394 mScreenFrozenLock.release(); 10395 10396 if (updateRotation) { 10397 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation"); 10398 configChanged |= updateRotationUncheckedLocked(false); 10399 } 10400 10401 if (configChanged) { 10402 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); 10403 } 10404 } 10405 10406 static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps, 10407 DisplayMetrics dm) { 10408 if (index < tokens.length) { 10409 String str = tokens[index]; 10410 if (str != null && str.length() > 0) { 10411 try { 10412 int val = Integer.parseInt(str); 10413 return val; 10414 } catch (Exception e) { 10415 } 10416 } 10417 } 10418 if (defUnits == TypedValue.COMPLEX_UNIT_PX) { 10419 return defDps; 10420 } 10421 int val = (int)TypedValue.applyDimension(defUnits, defDps, dm); 10422 return val; 10423 } 10424 10425 void createWatermarkInTransaction() { 10426 if (mWatermark != null) { 10427 return; 10428 } 10429 10430 File file = new File("/system/etc/setup.conf"); 10431 FileInputStream in = null; 10432 DataInputStream ind = null; 10433 try { 10434 in = new FileInputStream(file); 10435 ind = new DataInputStream(in); 10436 String line = ind.readLine(); 10437 if (line != null) { 10438 String[] toks = line.split("%"); 10439 if (toks != null && toks.length > 0) { 10440 mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(), 10441 mRealDisplayMetrics, mFxSession, toks); 10442 } 10443 } 10444 } catch (FileNotFoundException e) { 10445 } catch (IOException e) { 10446 } finally { 10447 if (ind != null) { 10448 try { 10449 ind.close(); 10450 } catch (IOException e) { 10451 } 10452 } else if (in != null) { 10453 try { 10454 in.close(); 10455 } catch (IOException e) { 10456 } 10457 } 10458 } 10459 } 10460 10461 @Override 10462 public void statusBarVisibilityChanged(int visibility) { 10463 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR) 10464 != PackageManager.PERMISSION_GRANTED) { 10465 throw new SecurityException("Caller does not hold permission " 10466 + android.Manifest.permission.STATUS_BAR); 10467 } 10468 10469 synchronized (mWindowMap) { 10470 mLastStatusBarVisibility = visibility; 10471 visibility = mPolicy.adjustSystemUiVisibilityLw(visibility); 10472 updateStatusBarVisibilityLocked(visibility); 10473 } 10474 } 10475 10476 // TOOD(multidisplay): StatusBar on multiple screens? 10477 void updateStatusBarVisibilityLocked(int visibility) { 10478 mInputManager.setSystemUiVisibility(visibility); 10479 final WindowList windows = getDefaultWindowListLocked(); 10480 final int N = windows.size(); 10481 for (int i = 0; i < N; i++) { 10482 WindowState ws = windows.get(i); 10483 try { 10484 int curValue = ws.mSystemUiVisibility; 10485 int diff = curValue ^ visibility; 10486 // We are only interested in differences of one of the 10487 // clearable flags... 10488 diff &= View.SYSTEM_UI_CLEARABLE_FLAGS; 10489 // ...if it has actually been cleared. 10490 diff &= ~visibility; 10491 int newValue = (curValue&~diff) | (visibility&diff); 10492 if (newValue != curValue) { 10493 ws.mSeq++; 10494 ws.mSystemUiVisibility = newValue; 10495 } 10496 if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) { 10497 ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq, 10498 visibility, newValue, diff); 10499 } 10500 } catch (RemoteException e) { 10501 // so sorry 10502 } 10503 } 10504 } 10505 10506 @Override 10507 public void reevaluateStatusBarVisibility() { 10508 synchronized (mWindowMap) { 10509 int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility); 10510 updateStatusBarVisibilityLocked(visibility); 10511 performLayoutAndPlaceSurfacesLocked(); 10512 } 10513 } 10514 10515 @Override 10516 public FakeWindow addFakeWindow(Looper looper, 10517 InputEventReceiver.Factory inputEventReceiverFactory, 10518 String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags, 10519 boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) { 10520 synchronized (mWindowMap) { 10521 FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory, 10522 name, windowType, 10523 layoutParamsFlags, layoutParamsPrivateFlags, canReceiveKeys, 10524 hasFocus, touchFullscreen); 10525 int i=0; 10526 while (i<mFakeWindows.size()) { 10527 if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) { 10528 break; 10529 } 10530 } 10531 mFakeWindows.add(i, fw); 10532 mInputMonitor.updateInputWindowsLw(true); 10533 return fw; 10534 } 10535 } 10536 10537 boolean removeFakeWindowLocked(FakeWindow window) { 10538 synchronized (mWindowMap) { 10539 if (mFakeWindows.remove(window)) { 10540 mInputMonitor.updateInputWindowsLw(true); 10541 return true; 10542 } 10543 return false; 10544 } 10545 } 10546 10547 // It is assumed that this method is called only by InputMethodManagerService. 10548 public void saveLastInputMethodWindowForTransition() { 10549 synchronized (mWindowMap) { 10550 // TODO(multidisplay): Pass in the displayID. 10551 DisplayContent displayContent = getDefaultDisplayContentLocked(); 10552 if (mInputMethodWindow != null) { 10553 mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget); 10554 } 10555 } 10556 } 10557 10558 public int getInputMethodWindowVisibleHeight() { 10559 synchronized (mWindowMap) { 10560 return mPolicy.getInputMethodWindowVisibleHeightLw(); 10561 } 10562 } 10563 10564 @Override 10565 public boolean hasNavigationBar() { 10566 return mPolicy.hasNavigationBar(); 10567 } 10568 10569 @Override 10570 public void lockNow(Bundle options) { 10571 mPolicy.lockNow(options); 10572 } 10573 10574 public void showRecentApps() { 10575 mPolicy.showRecentApps(); 10576 } 10577 10578 @Override 10579 public boolean isSafeModeEnabled() { 10580 return mSafeMode; 10581 } 10582 10583 @Override 10584 public boolean clearWindowContentFrameStats(IBinder token) { 10585 if (!checkCallingPermission(Manifest.permission.FRAME_STATS, 10586 "clearWindowContentFrameStats()")) { 10587 throw new SecurityException("Requires FRAME_STATS permission"); 10588 } 10589 synchronized (mWindowMap) { 10590 WindowState windowState = mWindowMap.get(token); 10591 if (windowState == null) { 10592 return false; 10593 } 10594 SurfaceControl surfaceControl = windowState.mWinAnimator.mSurfaceControl; 10595 if (surfaceControl == null) { 10596 return false; 10597 } 10598 return surfaceControl.clearContentFrameStats(); 10599 } 10600 } 10601 10602 @Override 10603 public WindowContentFrameStats getWindowContentFrameStats(IBinder token) { 10604 if (!checkCallingPermission(Manifest.permission.FRAME_STATS, 10605 "getWindowContentFrameStats()")) { 10606 throw new SecurityException("Requires FRAME_STATS permission"); 10607 } 10608 synchronized (mWindowMap) { 10609 WindowState windowState = mWindowMap.get(token); 10610 if (windowState == null) { 10611 return null; 10612 } 10613 SurfaceControl surfaceControl = windowState.mWinAnimator.mSurfaceControl; 10614 if (surfaceControl == null) { 10615 return null; 10616 } 10617 if (mTempWindowRenderStats == null) { 10618 mTempWindowRenderStats = new WindowContentFrameStats(); 10619 } 10620 WindowContentFrameStats stats = mTempWindowRenderStats; 10621 if (!surfaceControl.getContentFrameStats(stats)) { 10622 return null; 10623 } 10624 return stats; 10625 } 10626 } 10627 10628 void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) { 10629 pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)"); 10630 mPolicy.dump(" ", pw, args); 10631 } 10632 10633 void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) { 10634 pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)"); 10635 mAnimator.dumpLocked(pw, " ", dumpAll); 10636 } 10637 10638 void dumpTokensLocked(PrintWriter pw, boolean dumpAll) { 10639 pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)"); 10640 if (mTokenMap.size() > 0) { 10641 pw.println(" All tokens:"); 10642 Iterator<WindowToken> it = mTokenMap.values().iterator(); 10643 while (it.hasNext()) { 10644 WindowToken token = it.next(); 10645 pw.print(" "); pw.print(token); 10646 if (dumpAll) { 10647 pw.println(':'); 10648 token.dump(pw, " "); 10649 } else { 10650 pw.println(); 10651 } 10652 } 10653 } 10654 if (mWallpaperTokens.size() > 0) { 10655 pw.println(); 10656 pw.println(" Wallpaper tokens:"); 10657 for (int i=mWallpaperTokens.size()-1; i>=0; i--) { 10658 WindowToken token = mWallpaperTokens.get(i); 10659 pw.print(" Wallpaper #"); pw.print(i); 10660 pw.print(' '); pw.print(token); 10661 if (dumpAll) { 10662 pw.println(':'); 10663 token.dump(pw, " "); 10664 } else { 10665 pw.println(); 10666 } 10667 } 10668 } 10669 if (mFinishedStarting.size() > 0) { 10670 pw.println(); 10671 pw.println(" Finishing start of application tokens:"); 10672 for (int i=mFinishedStarting.size()-1; i>=0; i--) { 10673 WindowToken token = mFinishedStarting.get(i); 10674 pw.print(" Finished Starting #"); pw.print(i); 10675 pw.print(' '); pw.print(token); 10676 if (dumpAll) { 10677 pw.println(':'); 10678 token.dump(pw, " "); 10679 } else { 10680 pw.println(); 10681 } 10682 } 10683 } 10684 if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) { 10685 pw.println(); 10686 if (mOpeningApps.size() > 0) { 10687 pw.print(" mOpeningApps="); pw.println(mOpeningApps); 10688 } 10689 if (mClosingApps.size() > 0) { 10690 pw.print(" mClosingApps="); pw.println(mClosingApps); 10691 } 10692 } 10693 } 10694 10695 void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) { 10696 pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)"); 10697 for (int i=0; i<mSessions.size(); i++) { 10698 Session s = mSessions.valueAt(i); 10699 pw.print(" Session "); pw.print(s); pw.println(':'); 10700 s.dump(pw, " "); 10701 } 10702 } 10703 10704 void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) { 10705 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)"); 10706 if (mDisplayReady) { 10707 final int numDisplays = mDisplayContents.size(); 10708 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10709 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 10710 displayContent.dump(" ", pw); 10711 } 10712 } else { 10713 pw.println(" NO DISPLAY"); 10714 } 10715 } 10716 10717 void dumpWindowsLocked(PrintWriter pw, boolean dumpAll, 10718 ArrayList<WindowState> windows) { 10719 pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)"); 10720 dumpWindowsNoHeaderLocked(pw, dumpAll, windows); 10721 } 10722 10723 void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll, 10724 ArrayList<WindowState> windows) { 10725 final int numDisplays = mDisplayContents.size(); 10726 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10727 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList(); 10728 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) { 10729 final WindowState w = windowList.get(winNdx); 10730 if (windows == null || windows.contains(w)) { 10731 pw.print(" Window #"); pw.print(winNdx); pw.print(' '); 10732 pw.print(w); pw.println(":"); 10733 w.dump(pw, " ", dumpAll || windows != null); 10734 } 10735 } 10736 } 10737 if (mInputMethodDialogs.size() > 0) { 10738 pw.println(); 10739 pw.println(" Input method dialogs:"); 10740 for (int i=mInputMethodDialogs.size()-1; i>=0; i--) { 10741 WindowState w = mInputMethodDialogs.get(i); 10742 if (windows == null || windows.contains(w)) { 10743 pw.print(" IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w); 10744 } 10745 } 10746 } 10747 if (mPendingRemove.size() > 0) { 10748 pw.println(); 10749 pw.println(" Remove pending for:"); 10750 for (int i=mPendingRemove.size()-1; i>=0; i--) { 10751 WindowState w = mPendingRemove.get(i); 10752 if (windows == null || windows.contains(w)) { 10753 pw.print(" Remove #"); pw.print(i); pw.print(' '); 10754 pw.print(w); 10755 if (dumpAll) { 10756 pw.println(":"); 10757 w.dump(pw, " ", true); 10758 } else { 10759 pw.println(); 10760 } 10761 } 10762 } 10763 } 10764 if (mForceRemoves != null && mForceRemoves.size() > 0) { 10765 pw.println(); 10766 pw.println(" Windows force removing:"); 10767 for (int i=mForceRemoves.size()-1; i>=0; i--) { 10768 WindowState w = mForceRemoves.get(i); 10769 pw.print(" Removing #"); pw.print(i); pw.print(' '); 10770 pw.print(w); 10771 if (dumpAll) { 10772 pw.println(":"); 10773 w.dump(pw, " ", true); 10774 } else { 10775 pw.println(); 10776 } 10777 } 10778 } 10779 if (mDestroySurface.size() > 0) { 10780 pw.println(); 10781 pw.println(" Windows waiting to destroy their surface:"); 10782 for (int i=mDestroySurface.size()-1; i>=0; i--) { 10783 WindowState w = mDestroySurface.get(i); 10784 if (windows == null || windows.contains(w)) { 10785 pw.print(" Destroy #"); pw.print(i); pw.print(' '); 10786 pw.print(w); 10787 if (dumpAll) { 10788 pw.println(":"); 10789 w.dump(pw, " ", true); 10790 } else { 10791 pw.println(); 10792 } 10793 } 10794 } 10795 } 10796 if (mLosingFocus.size() > 0) { 10797 pw.println(); 10798 pw.println(" Windows losing focus:"); 10799 for (int i=mLosingFocus.size()-1; i>=0; i--) { 10800 WindowState w = mLosingFocus.get(i); 10801 if (windows == null || windows.contains(w)) { 10802 pw.print(" Losing #"); pw.print(i); pw.print(' '); 10803 pw.print(w); 10804 if (dumpAll) { 10805 pw.println(":"); 10806 w.dump(pw, " ", true); 10807 } else { 10808 pw.println(); 10809 } 10810 } 10811 } 10812 } 10813 if (mResizingWindows.size() > 0) { 10814 pw.println(); 10815 pw.println(" Windows waiting to resize:"); 10816 for (int i=mResizingWindows.size()-1; i>=0; i--) { 10817 WindowState w = mResizingWindows.get(i); 10818 if (windows == null || windows.contains(w)) { 10819 pw.print(" Resizing #"); pw.print(i); pw.print(' '); 10820 pw.print(w); 10821 if (dumpAll) { 10822 pw.println(":"); 10823 w.dump(pw, " ", true); 10824 } else { 10825 pw.println(); 10826 } 10827 } 10828 } 10829 } 10830 if (mWaitingForDrawn.size() > 0) { 10831 pw.println(); 10832 pw.println(" Clients waiting for these windows to be drawn:"); 10833 for (int i=mWaitingForDrawn.size()-1; i>=0; i--) { 10834 WindowState win = mWaitingForDrawn.get(i); 10835 pw.print(" Waiting #"); pw.print(i); pw.print(' '); pw.print(win); 10836 } 10837 } 10838 pw.println(); 10839 pw.print(" mCurConfiguration="); pw.println(this.mCurConfiguration); 10840 pw.print(" mCurrentFocus="); pw.println(mCurrentFocus); 10841 if (mLastFocus != mCurrentFocus) { 10842 pw.print(" mLastFocus="); pw.println(mLastFocus); 10843 } 10844 pw.print(" mFocusedApp="); pw.println(mFocusedApp); 10845 if (mInputMethodTarget != null) { 10846 pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget); 10847 } 10848 pw.print(" mInTouchMode="); pw.print(mInTouchMode); 10849 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq); 10850 pw.print(" mLastDisplayFreezeDuration="); 10851 TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw); 10852 if ( mLastFinishedFreezeSource != null) { 10853 pw.print(" due to "); 10854 pw.print(mLastFinishedFreezeSource); 10855 } 10856 pw.println(); 10857 if (dumpAll) { 10858 pw.print(" mSystemDecorLayer="); pw.print(mSystemDecorLayer); 10859 pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString()); 10860 if (mLastStatusBarVisibility != 0) { 10861 pw.print(" mLastStatusBarVisibility=0x"); 10862 pw.println(Integer.toHexString(mLastStatusBarVisibility)); 10863 } 10864 if (mInputMethodWindow != null) { 10865 pw.print(" mInputMethodWindow="); pw.println(mInputMethodWindow); 10866 } 10867 pw.print(" mWallpaperTarget="); pw.println(mWallpaperTarget); 10868 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) { 10869 pw.print(" mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget); 10870 pw.print(" mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget); 10871 } 10872 pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX); 10873 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY); 10874 if (mInputMethodAnimLayerAdjustment != 0 || 10875 mWallpaperAnimLayerAdjustment != 0) { 10876 pw.print(" mInputMethodAnimLayerAdjustment="); 10877 pw.print(mInputMethodAnimLayerAdjustment); 10878 pw.print(" mWallpaperAnimLayerAdjustment="); 10879 pw.println(mWallpaperAnimLayerAdjustment); 10880 } 10881 pw.print(" mSystemBooted="); pw.print(mSystemBooted); 10882 pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled); 10883 if (needsLayout()) { 10884 pw.print(" layoutNeeded on displays="); 10885 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10886 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); 10887 if (displayContent.layoutNeeded) { 10888 pw.print(displayContent.getDisplayId()); 10889 } 10890 } 10891 pw.println(); 10892 } 10893 pw.print(" mTransactionSequence="); pw.println(mTransactionSequence); 10894 pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen); 10895 pw.print(" windows="); pw.print(mWindowsFreezingScreen); 10896 pw.print(" client="); pw.print(mClientFreezingScreen); 10897 pw.print(" apps="); pw.print(mAppsFreezingScreen); 10898 pw.print(" waitingForConfig="); pw.println(mWaitingForConfig); 10899 pw.print(" mRotation="); pw.print(mRotation); 10900 pw.print(" mAltOrientation="); pw.println(mAltOrientation); 10901 pw.print(" mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation); 10902 pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation); 10903 pw.print(" mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount); 10904 pw.print(" Animation settings: disabled="); pw.print(mAnimationsDisabled); 10905 pw.print(" window="); pw.print(mWindowAnimationScaleSetting); 10906 pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting); 10907 pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting); 10908 pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled); 10909 pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition); 10910 pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation); 10911 pw.println(" mLayoutToAnim:"); 10912 mAppTransition.dump(pw); 10913 } 10914 } 10915 10916 boolean dumpWindows(PrintWriter pw, String name, String[] args, 10917 int opti, boolean dumpAll) { 10918 WindowList windows = new WindowList(); 10919 if ("visible".equals(name)) { 10920 synchronized(mWindowMap) { 10921 final int numDisplays = mDisplayContents.size(); 10922 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10923 final WindowList windowList = 10924 mDisplayContents.valueAt(displayNdx).getWindowList(); 10925 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) { 10926 final WindowState w = windowList.get(winNdx); 10927 if (w.mWinAnimator.mSurfaceShown) { 10928 windows.add(w); 10929 } 10930 } 10931 } 10932 } 10933 } else { 10934 int objectId = 0; 10935 // See if this is an object ID. 10936 try { 10937 objectId = Integer.parseInt(name, 16); 10938 name = null; 10939 } catch (RuntimeException e) { 10940 } 10941 synchronized(mWindowMap) { 10942 final int numDisplays = mDisplayContents.size(); 10943 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { 10944 final WindowList windowList = 10945 mDisplayContents.valueAt(displayNdx).getWindowList(); 10946 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) { 10947 final WindowState w = windowList.get(winNdx); 10948 if (name != null) { 10949 if (w.mAttrs.getTitle().toString().contains(name)) { 10950 windows.add(w); 10951 } 10952 } else if (System.identityHashCode(w) == objectId) { 10953 windows.add(w); 10954 } 10955 } 10956 } 10957 } 10958 } 10959 10960 if (windows.size() <= 0) { 10961 return false; 10962 } 10963 10964 synchronized(mWindowMap) { 10965 dumpWindowsLocked(pw, dumpAll, windows); 10966 } 10967 return true; 10968 } 10969 10970 void dumpLastANRLocked(PrintWriter pw) { 10971 pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)"); 10972 if (mLastANRState == null) { 10973 pw.println(" <no ANR has occurred since boot>"); 10974 } else { 10975 pw.println(mLastANRState); 10976 } 10977 } 10978 10979 /** 10980 * Saves information about the state of the window manager at 10981 * the time an ANR occurred before anything else in the system changes 10982 * in response. 10983 * 10984 * @param appWindowToken The application that ANR'd, may be null. 10985 * @param windowState The window that ANR'd, may be null. 10986 * @param reason The reason for the ANR, may be null. 10987 */ 10988 public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState, 10989 String reason) { 10990 StringWriter sw = new StringWriter(); 10991 PrintWriter pw = new FastPrintWriter(sw, false, 1024); 10992 pw.println(" ANR time: " + DateFormat.getInstance().format(new Date())); 10993 if (appWindowToken != null) { 10994 pw.println(" Application at fault: " + appWindowToken.stringName); 10995 } 10996 if (windowState != null) { 10997 pw.println(" Window at fault: " + windowState.mAttrs.getTitle()); 10998 } 10999 if (reason != null) { 11000 pw.println(" Reason: " + reason); 11001 } 11002 pw.println(); 11003 dumpWindowsNoHeaderLocked(pw, true, null); 11004 pw.close(); 11005 mLastANRState = sw.toString(); 11006 } 11007 11008 @Override 11009 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11010 if (mContext.checkCallingOrSelfPermission("android.permission.DUMP") 11011 != PackageManager.PERMISSION_GRANTED) { 11012 pw.println("Permission Denial: can't dump WindowManager from from pid=" 11013 + Binder.getCallingPid() 11014 + ", uid=" + Binder.getCallingUid()); 11015 return; 11016 } 11017 11018 boolean dumpAll = false; 11019 11020 int opti = 0; 11021 while (opti < args.length) { 11022 String opt = args[opti]; 11023 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11024 break; 11025 } 11026 opti++; 11027 if ("-a".equals(opt)) { 11028 dumpAll = true; 11029 } else if ("-h".equals(opt)) { 11030 pw.println("Window manager dump options:"); 11031 pw.println(" [-a] [-h] [cmd] ..."); 11032 pw.println(" cmd may be one of:"); 11033 pw.println(" l[astanr]: last ANR information"); 11034 pw.println(" p[policy]: policy state"); 11035 pw.println(" a[animator]: animator state"); 11036 pw.println(" s[essions]: active sessions"); 11037 pw.println(" d[isplays]: active display contents"); 11038 pw.println(" t[okens]: token list"); 11039 pw.println(" w[indows]: window list"); 11040 pw.println(" cmd may also be a NAME to dump windows. NAME may"); 11041 pw.println(" be a partial substring in a window name, a"); 11042 pw.println(" Window hex object identifier, or"); 11043 pw.println(" \"all\" for all windows, or"); 11044 pw.println(" \"visible\" for the visible windows."); 11045 pw.println(" -a: include all available server state."); 11046 return; 11047 } else { 11048 pw.println("Unknown argument: " + opt + "; use -h for help"); 11049 } 11050 } 11051 11052 // Is the caller requesting to dump a particular piece of data? 11053 if (opti < args.length) { 11054 String cmd = args[opti]; 11055 opti++; 11056 if ("lastanr".equals(cmd) || "l".equals(cmd)) { 11057 synchronized(mWindowMap) { 11058 dumpLastANRLocked(pw); 11059 } 11060 return; 11061 } else if ("policy".equals(cmd) || "p".equals(cmd)) { 11062 synchronized(mWindowMap) { 11063 dumpPolicyLocked(pw, args, true); 11064 } 11065 return; 11066 } else if ("animator".equals(cmd) || "a".equals(cmd)) { 11067 synchronized(mWindowMap) { 11068 dumpAnimatorLocked(pw, args, true); 11069 } 11070 return; 11071 } else if ("sessions".equals(cmd) || "s".equals(cmd)) { 11072 synchronized(mWindowMap) { 11073 dumpSessionsLocked(pw, true); 11074 } 11075 return; 11076 } else if ("displays".equals(cmd) || "d".equals(cmd)) { 11077 synchronized(mWindowMap) { 11078 dumpDisplayContentsLocked(pw, true); 11079 } 11080 return; 11081 } else if ("tokens".equals(cmd) || "t".equals(cmd)) { 11082 synchronized(mWindowMap) { 11083 dumpTokensLocked(pw, true); 11084 } 11085 return; 11086 } else if ("windows".equals(cmd) || "w".equals(cmd)) { 11087 synchronized(mWindowMap) { 11088 dumpWindowsLocked(pw, true, null); 11089 } 11090 return; 11091 } else if ("all".equals(cmd) || "a".equals(cmd)) { 11092 synchronized(mWindowMap) { 11093 dumpWindowsLocked(pw, true, null); 11094 } 11095 return; 11096 } else { 11097 // Dumping a single name? 11098 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) { 11099 pw.println("Bad window command, or no windows match: " + cmd); 11100 pw.println("Use -h for help."); 11101 } 11102 return; 11103 } 11104 } 11105 11106 synchronized(mWindowMap) { 11107 pw.println(); 11108 if (dumpAll) { 11109 pw.println("-------------------------------------------------------------------------------"); 11110 } 11111 dumpLastANRLocked(pw); 11112 pw.println(); 11113 if (dumpAll) { 11114 pw.println("-------------------------------------------------------------------------------"); 11115 } 11116 dumpPolicyLocked(pw, args, dumpAll); 11117 pw.println(); 11118 if (dumpAll) { 11119 pw.println("-------------------------------------------------------------------------------"); 11120 } 11121 dumpAnimatorLocked(pw, args, dumpAll); 11122 pw.println(); 11123 if (dumpAll) { 11124 pw.println("-------------------------------------------------------------------------------"); 11125 } 11126 dumpSessionsLocked(pw, dumpAll); 11127 pw.println(); 11128 if (dumpAll) { 11129 pw.println("-------------------------------------------------------------------------------"); 11130 } 11131 dumpDisplayContentsLocked(pw, dumpAll); 11132 pw.println(); 11133 if (dumpAll) { 11134 pw.println("-------------------------------------------------------------------------------"); 11135 } 11136 dumpTokensLocked(pw, dumpAll); 11137 pw.println(); 11138 if (dumpAll) { 11139 pw.println("-------------------------------------------------------------------------------"); 11140 } 11141 dumpWindowsLocked(pw, dumpAll, null); 11142 } 11143 } 11144 11145 // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection). 11146 @Override 11147 public void monitor() { 11148 synchronized (mWindowMap) { } 11149 } 11150 11151 public interface OnHardKeyboardStatusChangeListener { 11152 public void onHardKeyboardStatusChange(boolean available); 11153 } 11154 11155 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) { 11156 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) { 11157 Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" + 11158 Integer.toHexString(pendingLayoutChanges)); 11159 } 11160 } 11161 11162 private DisplayContent newDisplayContentLocked(final Display display) { 11163 DisplayContent displayContent = new DisplayContent(display, this); 11164 final int displayId = display.getDisplayId(); 11165 if (DEBUG_DISPLAY) Slog.v(TAG, "Adding display=" + display); 11166 mDisplayContents.put(displayId, displayContent); 11167 11168 DisplayInfo displayInfo = displayContent.getDisplayInfo(); 11169 final Rect rect = new Rect(); 11170 mDisplaySettings.getOverscanLocked(displayInfo.name, rect); 11171 synchronized (displayContent.mDisplaySizeLock) { 11172 displayInfo.overscanLeft = rect.left; 11173 displayInfo.overscanTop = rect.top; 11174 displayInfo.overscanRight = rect.right; 11175 displayInfo.overscanBottom = rect.bottom; 11176 mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager( 11177 displayId, displayInfo); 11178 } 11179 configureDisplayPolicyLocked(displayContent); 11180 11181 // TODO: Create an input channel for each display with touch capability. 11182 if (displayId == Display.DEFAULT_DISPLAY) { 11183 displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent); 11184 registerPointerEventListener(displayContent.mTapDetector); 11185 } 11186 11187 return displayContent; 11188 } 11189 11190 public void createDisplayContentLocked(final Display display) { 11191 if (display == null) { 11192 throw new IllegalArgumentException("getDisplayContent: display must not be null"); 11193 } 11194 getDisplayContentLocked(display.getDisplayId()); 11195 } 11196 11197 /** 11198 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if 11199 * there is a Display for the displayId. 11200 * @param displayId The display the caller is interested in. 11201 * @return The DisplayContent associated with displayId or null if there is no Display for it. 11202 */ 11203 public DisplayContent getDisplayContentLocked(final int displayId) { 11204 DisplayContent displayContent = mDisplayContents.get(displayId); 11205 if (displayContent == null) { 11206 final Display display = mDisplayManager.getDisplay(displayId); 11207 if (display != null) { 11208 displayContent = newDisplayContentLocked(display); 11209 } 11210 } 11211 return displayContent; 11212 } 11213 11214 // There is an inherent assumption that this will never return null. 11215 public DisplayContent getDefaultDisplayContentLocked() { 11216 return getDisplayContentLocked(Display.DEFAULT_DISPLAY); 11217 } 11218 11219 public WindowList getDefaultWindowListLocked() { 11220 return getDefaultDisplayContentLocked().getWindowList(); 11221 } 11222 11223 public DisplayInfo getDefaultDisplayInfoLocked() { 11224 return getDefaultDisplayContentLocked().getDisplayInfo(); 11225 } 11226 11227 /** 11228 * Return the list of WindowStates associated on the passed display. 11229 * @param display The screen to return windows from. 11230 * @return The list of WindowStates on the screen, or null if the there is no screen. 11231 */ 11232 public WindowList getWindowListLocked(final Display display) { 11233 return getWindowListLocked(display.getDisplayId()); 11234 } 11235 11236 /** 11237 * Return the list of WindowStates associated on the passed display. 11238 * @param displayId The screen to return windows from. 11239 * @return The list of WindowStates on the screen, or null if the there is no screen. 11240 */ 11241 public WindowList getWindowListLocked(final int displayId) { 11242 final DisplayContent displayContent = getDisplayContentLocked(displayId); 11243 return displayContent != null ? displayContent.getWindowList() : null; 11244 } 11245 11246 public void onDisplayAdded(int displayId) { 11247 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0)); 11248 } 11249 11250 public void handleDisplayAdded(int displayId) { 11251 synchronized (mWindowMap) { 11252 final Display display = mDisplayManager.getDisplay(displayId); 11253 if (display != null) { 11254 createDisplayContentLocked(display); 11255 displayReady(displayId); 11256 } 11257 } 11258 } 11259 11260 public void onDisplayRemoved(int displayId) { 11261 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0)); 11262 } 11263 11264 private void handleDisplayRemovedLocked(int displayId) { 11265 final DisplayContent displayContent = getDisplayContentLocked(displayId); 11266 if (displayContent != null) { 11267 if (displayContent.isAnimating()) { 11268 displayContent.mDeferredRemoval = true; 11269 return; 11270 } 11271 if (DEBUG_DISPLAY) Slog.v(TAG, "Removing display=" + displayContent); 11272 mDisplayContents.delete(displayId); 11273 displayContent.close(); 11274 if (displayId == Display.DEFAULT_DISPLAY) { 11275 unregisterPointerEventListener(displayContent.mTapDetector); 11276 } 11277 } 11278 mAnimator.removeDisplayLocked(displayId); 11279 } 11280 11281 public void onDisplayChanged(int displayId) { 11282 mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0)); 11283 } 11284 11285 private void handleDisplayChangedLocked(int displayId) { 11286 final DisplayContent displayContent = getDisplayContentLocked(displayId); 11287 if (displayContent != null) { 11288 displayContent.updateDisplayInfo(); 11289 } 11290 } 11291 11292 @Override 11293 public Object getWindowManagerLock() { 11294 return mWindowMap; 11295 } 11296 11297 private final class LocalService extends WindowManagerInternal { 11298 @Override 11299 public void requestTraversalFromDisplayManager() { 11300 requestTraversal(); 11301 } 11302 11303 @Override 11304 public void setMagnificationSpec(MagnificationSpec spec) { 11305 synchronized (mWindowMap) { 11306 if (mAccessibilityController != null) { 11307 mAccessibilityController.setMagnificationSpecLocked(spec); 11308 } else { 11309 throw new IllegalStateException("Magnification callbacks not set!"); 11310 } 11311 } 11312 if (Binder.getCallingPid() != android.os.Process.myPid()) { 11313 spec.recycle(); 11314 } 11315 } 11316 11317 @Override 11318 public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) { 11319 synchronized (mWindowMap) { 11320 WindowState windowState = mWindowMap.get(windowToken); 11321 if (windowState == null) { 11322 return null; 11323 } 11324 MagnificationSpec spec = null; 11325 if (mAccessibilityController != null) { 11326 spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState); 11327 } 11328 if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) { 11329 return null; 11330 } 11331 spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec); 11332 spec.scale *= windowState.mGlobalScale; 11333 return spec; 11334 } 11335 } 11336 11337 @Override 11338 public void setMagnificationCallbacks(MagnificationCallbacks callbacks) { 11339 synchronized (mWindowMap) { 11340 if (mAccessibilityController == null) { 11341 mAccessibilityController = new AccessibilityController( 11342 WindowManagerService.this); 11343 } 11344 mAccessibilityController.setMagnificationCallbacksLocked(callbacks); 11345 if (!mAccessibilityController.hasCallbacksLocked()) { 11346 mAccessibilityController = null; 11347 } 11348 } 11349 } 11350 11351 @Override 11352 public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) { 11353 synchronized (mWindowMap) { 11354 if (mAccessibilityController == null) { 11355 mAccessibilityController = new AccessibilityController( 11356 WindowManagerService.this); 11357 } 11358 mAccessibilityController.setWindowsForAccessibilityCallback(callback); 11359 if (!mAccessibilityController.hasCallbacksLocked()) { 11360 mAccessibilityController = null; 11361 } 11362 } 11363 } 11364 11365 @Override 11366 public void setInputFilter(IInputFilter filter) { 11367 mInputManager.setInputFilter(filter); 11368 } 11369 11370 @Override 11371 public IBinder getFocusedWindowToken() { 11372 synchronized (mWindowMap) { 11373 WindowState windowState = getFocusedWindowLocked(); 11374 if (windowState != null) { 11375 return windowState.mClient.asBinder(); 11376 } 11377 return null; 11378 } 11379 } 11380 11381 @Override 11382 public boolean isKeyguardLocked() { 11383 return WindowManagerService.this.isKeyguardLocked(); 11384 } 11385 11386 @Override 11387 public void showGlobalActions() { 11388 WindowManagerService.this.showGlobalActions(); 11389 } 11390 11391 @Override 11392 public void getWindowFrame(IBinder token, Rect outBounds) { 11393 synchronized (mWindowMap) { 11394 WindowState windowState = mWindowMap.get(token); 11395 if (windowState != null) { 11396 outBounds.set(windowState.mFrame); 11397 } else { 11398 outBounds.setEmpty(); 11399 } 11400 } 11401 } 11402 11403 public void waitForAllWindowsDrawn(Runnable callback, long timeout) { 11404 synchronized (mWindowMap) { 11405 mWaitingForDrawnCallback = callback; 11406 final WindowList windows = getDefaultWindowListLocked(); 11407 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { 11408 final WindowState win = windows.get(winNdx); 11409 if (win.mHasSurface && win.mAppToken != null) { 11410 win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING; 11411 // Force add to mResizingWindows. 11412 win.mLastContentInsets.set(-1, -1, -1, -1); 11413 mWaitingForDrawn.add(win); 11414 } 11415 } 11416 requestTraversalLocked(); 11417 } 11418 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT); 11419 if (mWaitingForDrawn.isEmpty()) { 11420 callback.run(); 11421 } else { 11422 mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout); 11423 checkDrawnWindowsLocked(); 11424 } 11425 } 11426 } 11427} 11428