WindowManagerService.java revision e0a3884cb627efc650e19fbe76b1b3343468cf57
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2007 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrompackage com.android.server.wm;
182ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
190af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughesimport static android.view.WindowManager.LayoutParams.*;
2079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
2179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesimport static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers
230af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughesimport static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
240af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
252ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiroimport android.app.AppOpsManager;
26ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersimport android.util.TimeUtils;
275369c40f75fdcb1be7a7c06db212ce965c83a164Mathieu Chartierimport android.view.IWindowId;
2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes
2976b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughesimport com.android.internal.app.IBatteryStats;
301aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughesimport com.android.internal.policy.PolicyManager;
319837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogersimport com.android.internal.policy.impl.PhoneWindowManager;
324f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogersimport com.android.internal.util.FastPrintWriter;
331f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartierimport com.android.internal.view.IInputContext;
3494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchiimport com.android.internal.view.IInputMethodClient;
351d54e73444e017d3a65234e0f193846f3e27472bIan Rogersimport com.android.internal.view.IInputMethodManager;
36c56057e40938c587a74984651a510e320a8cb4fdMathieu Chartierimport com.android.internal.view.WindowManagerPolicyThread;
373dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Haoimport com.android.server.AttributeCache;
38ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiroimport com.android.server.EventLogTags;
39ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromimport com.android.server.UiThread;
40ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromimport com.android.server.Watchdog;
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersimport com.android.server.am.BatteryStatsService;
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersimport com.android.server.display.DisplayManagerService;
432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersimport com.android.server.input.InputManagerService;
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersimport com.android.server.power.PowerManagerService;
45b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersimport com.android.server.power.ShutdownThread;
462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
476d031046eeb5e9f62b657df0695b752e1d0aa583jguimport android.Manifest;
48491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstromimport android.app.ActivityManagerNative;
4953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogersimport android.app.IActivityManager;
502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiroimport android.app.StatusBarManager;
51a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesimport android.app.admin.DevicePolicyManager;
5200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersimport android.animation.ValueAnimator;
53a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughesimport android.content.BroadcastReceiver;
542ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiroimport android.content.Context;
552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersimport android.content.Intent;
56eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughesimport android.content.IntentFilter;
57df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogersimport android.content.pm.ActivityInfo;
58bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughesimport android.content.pm.PackageManager;
59bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughesimport android.content.res.CompatibilityInfo;
607934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.content.res.Configuration;
617934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.graphics.Bitmap;
622ced6a534157d5d963693346904389c19775d2daElliott Hughesimport android.graphics.Bitmap.Config;
637934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.graphics.Canvas;
647934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.graphics.Matrix;
652ced6a534157d5d963693346904389c19775d2daElliott Hughesimport android.graphics.PixelFormat;
667934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.graphics.Point;
677934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.graphics.Rect;
682ced6a534157d5d963693346904389c19775d2daElliott Hughesimport android.graphics.RectF;
697934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.graphics.Region;
707934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromimport android.hardware.display.DisplayManager;
71df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogersimport android.os.Binder;
72e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierimport android.os.Bundle;
73b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogersimport android.os.Debug;
74c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartierimport android.os.Handler;
7545619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogersimport android.os.IBinder;
7645619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogersimport android.os.IRemoteCallback;
7719c5d3786894af707d8079231105bca1b7dcd096Jeff Haoimport android.os.Looper;
7819c5d3786894af707d8079231105bca1b7dcd096Jeff Haoimport android.os.Message;
7919c5d3786894af707d8079231105bca1b7dcd096Jeff Haoimport android.os.Parcel;
8019c5d3786894af707d8079231105bca1b7dcd096Jeff Haoimport android.os.ParcelFileDescriptor;
8119c5d3786894af707d8079231105bca1b7dcd096Jeff Haoimport android.os.PowerManager;
826b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.Process;
836b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.RemoteException;
846b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.ServiceManager;
856b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.StrictMode;
866b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.SystemClock;
870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersimport android.os.SystemProperties;
886b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.Trace;
896b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.os.WorkSource;
906b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.provider.Settings;
916b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.DisplayMetrics;
926b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.EventLog;
936b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.FloatMath;
946b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.Log;
956b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.SparseArray;
966b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.Pair;
976b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.util.Slog;
98a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughesimport android.util.SparseIntArray;
99a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughesimport android.util.TypedValue;
100a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughesimport android.view.Choreographer;
101a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughesimport android.view.Display;
1026b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.view.DisplayInfo;
1036b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.view.Gravity;
1046b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.view.IApplicationToken;
1056b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughesimport android.view.IInputFilter;
106e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierimport android.view.IMagnificationCallbacks;
10700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersimport android.view.IOnKeyguardExitResult;
108b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogersimport android.view.IRotationWatcher;
10962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersimport android.view.IWindow;
110cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogersimport android.view.IWindowManager;
11162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersimport android.view.IWindowSession;
11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersimport android.view.InputChannel;
113cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogersimport android.view.InputDevice;
11414134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughesimport android.view.InputEvent;
11514134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughesimport android.view.InputEventReceiver;
116fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.KeyEvent;
117fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.MagnificationSpec;
118fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.MotionEvent;
119fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.Surface.OutOfResourcesException;
120fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.Surface;
121fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.SurfaceControl;
122fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.SurfaceSession;
123fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.View;
124fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.ViewTreeObserver;
125fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.WindowManager;
126fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzimport android.view.WindowManagerGlobal;
127c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport android.view.WindowManagerPolicy;
128c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport android.view.WindowManager.LayoutParams;
129c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport android.view.WindowManagerPolicy.FakeWindow;
130c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport android.view.WindowManagerPolicy.PointerEventListener;
131c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport android.view.animation.Animation;
132eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartierimport android.view.animation.AnimationUtils;
133eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartierimport android.view.animation.Transformation;
134eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
135c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport java.io.BufferedWriter;
136c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport java.io.DataInputStream;
137eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartierimport java.io.File;
138c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport java.io.FileDescriptor;
139c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport java.io.FileInputStream;
14000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersimport java.io.FileNotFoundException;
14100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersimport java.io.IOException;
142b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogersimport java.io.OutputStream;
143e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierimport java.io.OutputStreamWriter;
144c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport java.io.PrintWriter;
145c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierimport java.io.StringWriter;
146cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesimport java.net.Socket;
147e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierimport java.text.DateFormat;
148cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesimport java.util.ArrayList;
149cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesimport java.util.Date;
150004644fe87046b965442b1ee1008b7206817d187Brian Carlstromimport java.util.HashMap;
151004644fe87046b965442b1ee1008b7206817d187Brian Carlstromimport java.util.HashSet;
152cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesimport java.util.Iterator;
153cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesimport java.util.List;
154e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
155cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes/** {@hide} */
156cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughespublic class WindowManagerService extends IWindowManager.Stub
157cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
158cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
159cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    static final String TAG = "WindowManager";
160e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG = false;
16100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final boolean DEBUG_ADD_REMOVE = false;
162e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_FOCUS = false;
163cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    static final boolean DEBUG_FOCUS_LIGHT = DEBUG_FOCUS || false;
16400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final boolean DEBUG_ANIM = false;
165ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    static final boolean DEBUG_LAYOUT = false;
166ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    static final boolean DEBUG_RESIZE = false;
167e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_LAYERS = false;
168b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    static final boolean DEBUG_INPUT = false;
169e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_INPUT_METHOD = false;
170ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_VISIBILITY = false;
171ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_WINDOW_MOVEMENT = false;
172ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    static final boolean DEBUG_TOKEN_MOVEMENT = false;
17300fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom    static final boolean DEBUG_ORIENTATION = false;
174ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_APP_ORIENTATION = false;
175e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_CONFIGURATION = false;
176ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_APP_TRANSITIONS = false;
177ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_STARTING_WINDOW = false;
178ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_REORDER = false;
179e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_WALLPAPER = false;
180e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
181e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_DRAG = false;
182ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_SCREEN_ON = false;
183ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_SCREENSHOT = false;
184ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_BOOT = false;
185ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_LAYOUT_REPEATS = true;
186e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean DEBUG_SURFACE_TRACE = false;
187a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    static final boolean DEBUG_WINDOW_TRACE = false;
188ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_TASK_MOVEMENT = false;
189ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean DEBUG_STACK = false;
190ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean SHOW_SURFACE_ALLOC = false;
191ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    static final boolean SHOW_TRANSACTIONS = false;
192e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS;
19300fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom    static final boolean HIDE_STACK_CRAWLS = true;
19400fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom    static final int LAYOUT_REPEAT_THRESHOLD = 4;
19500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
19600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final boolean PROFILE_ORIENTATION = false;
197b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    static final boolean localLOGV = DEBUG;
198eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
199eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    /** How much to multiply the policy's type layer, to reserve room
200eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier     * for multiple windows of the same type and Z-ordering adjustment
201eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier     * with TYPE_LAYER_OFFSET. */
202c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    static final int TYPE_LAYER_MULTIPLIER = 10000;
203cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
204e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
205e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier     * or below others in the same layer. */
2060cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    static final int TYPE_LAYER_OFFSET = 1000;
2070cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
208eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    /** How much to increment the layer for each window, to reserve room
2099837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers     * for effect surfaces between them.
2100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers     */
2110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    static final int WINDOW_LAYER_MULTIPLIER = 5;
2120cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
213e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /**
2140cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers     * Dim surface layer is immediately below target window.
21500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     */
21662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    static final int LAYER_OFFSET_DIM = 1;
217eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
218eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    /**
21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * Blur surface layer is immediately below dim layer.
220cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers     */
22162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    static final int LAYER_OFFSET_BLUR = 2;
222491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom
223491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom    /**
224cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers     * FocusedStackFrame layer is immediately above focused window.
225eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier     */
226e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final int LAYER_OFFSET_FOCUSED_STACK = 1;
2270cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers
228cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    /**
229cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     * Animation thumbnail is as far as possible below the window above
230f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier     * the thumbnail (or in other words as far as possible above the window
231cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers     * below it).
2324dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers     */
233cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    static final int LAYER_OFFSET_THUMBNAIL = WINDOW_LAYER_MULTIPLIER-1;
2344dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers
235e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /**
23662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * Layer at which to put the rotation freeze snapshot.
23762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     */
23862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    static final int FREEZE_LAYER = (TYPE_LAYER_MULTIPLIER * 200) + 1;
239cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers
240e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /**
241cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     * Layer at which to put the mask for emulated screen sizes.
24200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     */
243ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    static final int MASK_LAYER = TYPE_LAYER_MULTIPLIER * 200;
244ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
245e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /** The maximum length we will accept for a loaded animation duration:
24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * this is 10 seconds.
247b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers     */
24854e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes    static final int MAX_ANIMATION_DURATION = 10*1000;
24962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
25062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    /** Amount of time (in milliseconds) to animate the fade-in-out transition for
25162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     * compatible windows.
25262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers     */
253814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes    static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
2540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
25500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
25600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
257b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers
25862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    /** Amount of time (in milliseconds) to delay before declaring a starting window leaked. */
25962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    static final int STARTING_WINDOW_TIMEOUT_DURATION = 10000;
26062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
26162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    /**
262b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes     * If true, the window manager will do its own custom freezing and general
263814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes     * management of the screen during rotation.
26400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     */
265b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    static final boolean CUSTOM_SCREEN_ROTATION = true;
26600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
26700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // Maximum number of milliseconds to wait for input devices to be enumerated before
268e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    // proceding with safe mode detection.
26900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
270814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
271814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes    // Default input dispatching timeout in nanoseconds.
27200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
27300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
27400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    /** Minimum value for createStack and resizeStack weight value */
275e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    public static final float STACK_WEIGHT_MIN = 0.2f;
27600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
277e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /** Maximum value for createStack and resizeStack weight value */
27800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    public static final float STACK_WEIGHT_MAX = 0.8f;
27900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
280e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    static final int UPDATE_FOCUS_NORMAL = 0;
28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
283814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes    static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
28400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
28500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private static final String SYSTEM_SECURE = "ro.secure";
28600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
28700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
28800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private static final String DENSITY_OVERRIDE = "ro.config.density_override";
289e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    private static final String SIZE_OVERRIDE = "ro.config.size_override";
290ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers
29100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private static final int MAX_SCREENSHOT_RETRIES = 3;
292e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
29300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    final private KeyguardDisableHandler mKeyguardDisableHandler;
294814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
295a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes    final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
296e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        @Override
297e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        public void onReceive(Context context, Intent intent) {
298e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            final String action = intent.getAction();
29900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
30000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                mKeyguardDisableHandler.sendEmptyMessage(
301ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers                    KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers            }
303e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
30400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    };
305a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
306a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes    // Current user when multi-user is enabled. Don't show windows of non-current user.
307462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes    int mCurrentUserId;
308e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
3097577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    final Context mContext;
3107577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
3117577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    final boolean mHaveInputMethods;
312462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes
313cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final boolean mAllowBootMessages;
314e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
315cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final boolean mLimitedAlphaCompositing;
316cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
317cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
318cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
319cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final IActivityManager mActivityManager;
320cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
321cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final IBatteryStats mBatteryStats;
322cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
323cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final AppOpsManager mAppOps;
324cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
325cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    final DisplaySettings mDisplaySettings;
326cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
327462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes    /**
328e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier     * All currently active sessions with clients.
329e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier     */
330e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    final HashSet<Session> mSessions = new HashSet<Session>();
33183a25328c595975097cf3948451088cbfc64fc09Elliott Hughes
33283a25328c595975097cf3948451088cbfc64fc09Elliott Hughes    /**
33383a25328c595975097cf3948451088cbfc64fc09Elliott Hughes     * Mapping from an IWindow IBinder to the server's Window object.
33483a25328c595975097cf3948451088cbfc64fc09Elliott Hughes     * This is also used as the lock for all of our state.
33583a25328c595975097cf3948451088cbfc64fc09Elliott Hughes     * NOTE: Never call into methods that lock ActivityManagerService while holding this object.
3368692215f793cbf8be9c3d25a705074ca877e09b8Brian Carlstrom     */
337462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes    final HashMap<IBinder, WindowState> mWindowMap = new HashMap<IBinder, WindowState>();
338365c10235438607541fa2259a5fec48061b90bd8Ian Rogers
3397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    /**
3407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes     * Mapping from a token IBinder to a WindowToken object.
341664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier     */
342e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    final HashMap<IBinder, WindowToken> mTokenMap = new HashMap<IBinder, WindowToken>();
343120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers
344120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    /**
345120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers     * List of window tokens that have finished starting their application,
346120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers     * and now need to have the policy remove their windows.
347120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers     */
3487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    final ArrayList<AppWindowToken> mFinishedStarting = new ArrayList<AppWindowToken>();
3497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
35079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    /**
35179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     * Fake windows added to the window manager.  Note: ordered from top to
352e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier     * bottom, opposite of mWindows.
35379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     */
35479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final ArrayList<FakeWindowImpl> mFakeWindows = new ArrayList<FakeWindowImpl>();
355355383f61d28f2dc8072fbde2639c80627adf16dYong WU
35694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    /**
3578daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes     * Windows that are being resized.  Used so we can tell the client about
358c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers     * the resize after closing the transaction in which we resized the
359d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers     * underlying surface.
36079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     */
36179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final ArrayList<WindowState> mResizingWindows = new ArrayList<WindowState>();
36279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
363ea2e1bd713ca8295ba4fcd01e77a3ce532ea61e4Hiroshi Yamauchi    /**
36494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi     * Windows whose animations have ended and now must be removed.
36579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     */
36679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final ArrayList<WindowState> mPendingRemove = new ArrayList<WindowState>();
36779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
36879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    /**
36979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     * Used when processing mPendingRemove to avoid working on the original array.
37079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     */
37179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    WindowState[] mPendingRemoveTmp = new WindowState[20];
3721bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes
3731bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes    /**
37479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     * Windows whose surface should be destroyed.
37500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     */
37600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    final ArrayList<WindowState> mDestroySurface = new ArrayList<WindowState>();
377b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers
37879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    /**
37900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * Windows that have lost input focus and are waiting for the new
38000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * focus window to be displayed before they are told about this.
38100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     */
38250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    ArrayList<WindowState> mLosingFocus = new ArrayList<WindowState>();
38300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
384d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers    /**
38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * This is set when we have run out of memory, and will either be an empty
38600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * list or contain windows that need to be force removed.
38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     */
38800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ArrayList<WindowState> mForceRemoves;
38900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
39000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    /**
39100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * Windows that clients are waiting to have drawn.
392c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers     */
39300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
39479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes            = new ArrayList<Pair<WindowState, IRemoteCallback>>();
39500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
39600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    /**
39700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * Windows that have called relayout() while we were running animations,
39800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * so we need to tell when the animation is done.
39979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     */
40000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
40179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
40279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    /**
40379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes     * Used when rebuilding window list to keep track of windows that have
40400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers     * been removed.
405c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers     */
406c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    WindowState[] mRebuildTmp = new WindowState[20];
407f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes
40879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    IInputMethodManager mInputMethodManager;
409dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes
41079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    DisplayMagnifier mDisplayMagnifier;
41179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
412c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    final SurfaceSession mFxSession;
41379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    Watermark mWatermark;
41479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    StrictModeFlash mStrictModeFlash;
415355383f61d28f2dc8072fbde2639c80627adf16dYong WU    FocusedStackFrame mFocusedStackFrame;
416355383f61d28f2dc8072fbde2639c80627adf16dYong WU
417355383f61d28f2dc8072fbde2639c80627adf16dYong WU    int mFocusedStackLayer;
418355383f61d28f2dc8072fbde2639c80627adf16dYong WU
419355383f61d28f2dc8072fbde2639c80627adf16dYong WU    final float[] mTmpFloats = new float[9];
420355383f61d28f2dc8072fbde2639c80627adf16dYong WU    final Rect mTmpContentRect = new Rect();
421355383f61d28f2dc8072fbde2639c80627adf16dYong WU
422355383f61d28f2dc8072fbde2639c80627adf16dYong WU    boolean mDisplayReady;
42379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mSafeMode;
42479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mDisplayEnabled = false;
42579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mSystemBooted = false;
42679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mForceDisplayEnabled = false;
427355383f61d28f2dc8072fbde2639c80627adf16dYong WU    boolean mShowingBootMessages = false;
428355383f61d28f2dc8072fbde2639c80627adf16dYong WU
429355383f61d28f2dc8072fbde2639c80627adf16dYong WU    String mLastANRState;
430355383f61d28f2dc8072fbde2639c80627adf16dYong WU
431355383f61d28f2dc8072fbde2639c80627adf16dYong WU    /** All DisplayContents in the world, kept here */
432355383f61d28f2dc8072fbde2639c80627adf16dYong WU    SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
433355383f61d28f2dc8072fbde2639c80627adf16dYong WU
434355383f61d28f2dc8072fbde2639c80627adf16dYong WU    int mRotation = 0;
435355383f61d28f2dc8072fbde2639c80627adf16dYong WU    int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
43693de4273d72a2558a7b3423547b5074cd76c5796Calin Juravle    boolean mAltOrientation = false;
437355383f61d28f2dc8072fbde2639c80627adf16dYong WU    ArrayList<IRotationWatcher> mRotationWatchers
438355383f61d28f2dc8072fbde2639c80627adf16dYong WU            = new ArrayList<IRotationWatcher>();
43983c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier    int mDeferredRotationPauseCount;
44012f7423a2bb4bfab76700d84eb6d4338d211983aMathieu Chartier
4418f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    int mSystemDecorLayer = 0;
4428f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    final Rect mScreenRect = new Rect();
44379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
44479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mTraversalScheduled = false;
44579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mDisplayFrozen = false;
44679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    long mDisplayFreezeTime = 0;
44779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    int mLastDisplayFreezeDuration = 0;
44879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    Object mLastFinishedFreezeSource = null;
44979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mWaitingForConfig = false;
45079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mWindowsFreezingScreen = false;
45179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mClientFreezingScreen = false;
45279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    int mAppsFreezingScreen = 0;
45379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    int mLastWindowForcedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
45479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
45579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    int mLayoutSeq = 0;
456355383f61d28f2dc8072fbde2639c80627adf16dYong WU
457355383f61d28f2dc8072fbde2639c80627adf16dYong WU    int mLastStatusBarVisibility = 0;
458355383f61d28f2dc8072fbde2639c80627adf16dYong WU
45979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // State while inside of layoutAndPlaceSurfacesLocked().
46094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    boolean mFocusMayChange;
46179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
46279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    Configuration mCurConfiguration = new Configuration();
46300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
46479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // This is held as long as we have the screen frozen, to give us time to
465c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    // perform a rotation animation when turning off shows the lock screen which
46679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // changes the orientation.
467f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    private final PowerManager.WakeLock mScreenFrozenLock;
46879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
469f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes    final AppTransition mAppTransition;
47079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mStartingIconInTransition = false;
47179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mSkipAppTransitionAnimation = false;
47279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
47379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
47479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
47579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
47679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mIsTouchDevice;
47779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
47879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
479c31664f3d82e6cd68275a529a8a73f067a52e8beElliott Hughes    final DisplayMetrics mRealDisplayMetrics = new DisplayMetrics();
48079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final DisplayMetrics mTmpDisplayMetrics = new DisplayMetrics();
48179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
482ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
483ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    final H mH = new H();
48402e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier
485ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    final Choreographer mChoreographer = Choreographer.getInstance();
486ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
487ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    WindowState mCurrentFocus = null;
488ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    WindowState mLastFocus = null;
48902e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier
490ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    /** This just indicates the window the input method is on top of, not
491ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes     * necessarily the window its input is going to. */
492ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    WindowState mInputMethodTarget = null;
493ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
494ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    /** If true hold off on modifying the animation layer of mInputMethodTarget */
495ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    boolean mInputMethodTargetWaitingAnim;
496ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    int mInputMethodAnimLayerAdjustment;
49779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
49802e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    WindowState mInputMethodWindow = null;
499e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
50079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
50179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mHardKeyboardAvailable;
50279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mHardKeyboardEnabled;
503a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
50479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
50579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
50679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
507e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    // If non-null, this is the currently visible window that is associated
508b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    // with the wallpaper.
50979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    WindowState mWallpaperTarget = null;
51079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // If non-null, we are in the middle of animating from one wallpaper target
511e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    // to another, and this is the lower one in Z-order.
51202e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    WindowState mLowerWallpaperTarget = null;
51302e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    // If non-null, we are in the middle of animating from one wallpaper target
51479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // to another, and this is the higher one in Z-order.
51579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    WindowState mUpperWallpaperTarget = null;
51679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    int mWallpaperAnimLayerAdjustment;
51779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    float mLastWallpaperX = -1;
51879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    float mLastWallpaperY = -1;
519355383f61d28f2dc8072fbde2639c80627adf16dYong WU    float mLastWallpaperXStep = -1;
520355383f61d28f2dc8072fbde2639c80627adf16dYong WU    float mLastWallpaperYStep = -1;
521355383f61d28f2dc8072fbde2639c80627adf16dYong WU    // This is set when we are waiting for a wallpaper to tell us it is done
522355383f61d28f2dc8072fbde2639c80627adf16dYong WU    // changing its scroll position.
523355383f61d28f2dc8072fbde2639c80627adf16dYong WU    WindowState mWaitingOnWallpaper;
524355383f61d28f2dc8072fbde2639c80627adf16dYong WU    // The last time we had a timeout when waiting for a wallpaper.
525355383f61d28f2dc8072fbde2639c80627adf16dYong WU    long mLastWallpaperTimeoutTime;
526355383f61d28f2dc8072fbde2639c80627adf16dYong WU    // We give a wallpaper up to 150ms to finish scrolling.
527355383f61d28f2dc8072fbde2639c80627adf16dYong WU    static final long WALLPAPER_TIMEOUT = 150;
528355383f61d28f2dc8072fbde2639c80627adf16dYong WU    // Time we wait after a timeout before trying to wait again.
529355383f61d28f2dc8072fbde2639c80627adf16dYong WU    static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
53079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    boolean mAnimateWallpaperWithTarget;
531e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
5324dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    AppWindowToken mFocusedApp = null;
5334dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes
53479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    PowerManagerService mPowerManager;
53579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
53679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    float mWindowAnimationScale = 1.0f;
53779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    float mTransitionAnimationScale = 1.0f;
538a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes    float mAnimatorDurationScale = 1.0f;
53992827a5fc2598589b3717269cc09c33b8c53f30bBrian Carlstrom
54079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final InputManagerService mInputManager;
541e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    final DisplayManagerService mDisplayManagerService;
54279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    final DisplayManager mDisplayManager;
54379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
54483c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier    // Who is holding the screen on.
5458f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    Session mHoldingScreenOn;
54683c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier    PowerManager.WakeLock mHoldingScreenWakeLock;
5478f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier
5488f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    boolean mTurnOnScreen;
5498f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier
55079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    DragState mDragState = null;
5515369c40f75fdcb1be7a7c06db212ce965c83a164Mathieu Chartier
55279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // For frozen screen animations.
55379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    int mExitAnimId, mEnterAnimId;
5542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
5552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    /** Pulled out of performLayoutAndPlaceSurfacesLockedInner in order to refactor into multiple
5563b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier     * methods. */
5572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    class LayoutFields {
5582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        static final int SET_UPDATE_ROTATION                = 1 << 0;
5592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        static final int SET_WALLPAPER_MAY_CHANGE           = 1 << 1;
5602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        static final int SET_FORCE_HIDING_CHANGED           = 1 << 2;
5612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        static final int SET_ORIENTATION_CHANGE_COMPLETE    = 1 << 3;
5622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        static final int SET_TURN_ON_SCREEN                 = 1 << 4;
5632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 5;
5642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
5652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        boolean mWallpaperForceHidingChanged = false;
5662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        boolean mWallpaperMayChange = false;
567e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        boolean mOrientationChangeComplete = true;
5683b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        Object mLastWindowFreezeSource = null;
5692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        private Session mHoldScreen = null;
570bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        private boolean mObscured = false;
571bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        private boolean mSyswin = false;
5723b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        private float mScreenBrightness = -1;
573e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        private float mButtonBrightness = -1;
5743b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        private long mUserActivityTimeout = -1;
5752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        private boolean mUpdateRotation = false;
5764ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers        boolean mWallpaperActionPending = false;
5774ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers
578cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // Set to true when the display contains content to show the user.
579cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // When false, the display manager may choose to mirror or blank the display.
58025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        boolean mDisplayHasContent = false;
581cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
582cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // Only set while traversing the default display based on its content.
583cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // Affects the behavior of mirroring on secondary displays.
58425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        boolean mObscureApplicationContentOnSecondaryDisplays = false;
585cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
586e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    final LayoutFields mInnerFields = new LayoutFields();
58718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
58818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes    boolean mAnimationScheduled;
589cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
5903b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
5915fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
5925fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    private int mTransactionSequence;
593cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
594ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    /** Only do a maximum of 6 repeated layouts. After that quit */
595e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    private int mLayoutRepeatCount;
5965fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes
597eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    final WindowAnimator mAnimator;
598eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
5999837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers    SparseArray<Task> mTaskIdToTask = new SparseArray<Task>();
6005fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>();
6019837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers
6025fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    private final PointerEventDispatcher mPointerEventDispatcher;
60300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
604cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    final class DragInputEventReceiver extends InputEventReceiver {
605ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        public DragInputEventReceiver(InputChannel inputChannel, Looper looper) {
60662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers            super(inputChannel, looper);
6073b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        }
60800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
60962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers        @Override
61018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes        public void onInputEvent(InputEvent event) {
61118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes            boolean handled = false;
61262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers            try {
6133b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                if (event instanceof MotionEvent
61400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0
61562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers                        && mDragState != null) {
616cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    final MotionEvent motionEvent = (MotionEvent)event;
61718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes                    boolean endDrag = false;
618cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    final float newX = motionEvent.getRawX();
6193b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    final float newY = motionEvent.getRawY();
62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
621e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    switch (motionEvent.getAction()) {
622e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    case MotionEvent.ACTION_DOWN: {
6238c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier                        if (DEBUG_DRAG) {
624d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz                            Slog.w(TAG, "Unexpected ACTION_DOWN in drag layer");
625d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz                        }
626d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz                    } break;
627d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz
628d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz                    case MotionEvent.ACTION_MOVE: {
629d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz                        synchronized (mWindowMap) {
630ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                            // move the surface and tell the involved window(s) where we are
631e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                            mDragState.notifyMoveLw(newX, newY);
632ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                        }
633e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    } break;
6348c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier
635ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                    case MotionEvent.ACTION_UP: {
63618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes                        if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at "
637ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                                + newX + "," + newY);
638cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        synchronized (mWindowMap) {
6393b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                            endDrag = mDragState.notifyDropLw(newX, newY);
64000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        }
641e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    } break;
6428c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier
643ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                    case MotionEvent.ACTION_CANCEL: {
644ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                        if (DEBUG_DRAG) Slog.d(TAG, "Drag cancelled!");
645e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        endDrag = true;
646ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                    } break;
647e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    }
6488c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier
649ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                    if (endDrag) {
650cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (DEBUG_DRAG) Slog.d(TAG, "Drag ended; tearing down state");
651cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // tell all the windows that the drag has ended
65237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes                        synchronized (mWindowMap) {
6533b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                            mDragState.endDragLw();
65400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        }
655e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    }
65600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
65737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes                    handled = true;
65837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes                }
659885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            } catch (Exception e) {
6603b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                Slog.e(TAG, "Exception caught by drag handleMotion", e);
66100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            } finally {
662e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                finishInputEvent(event, handled);
66300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
66418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes        }
66518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes    }
6661268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath
6671268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath    /**
66837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes     * Whether the UI is currently running in touch mode (not showing
6692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers     * navigational focus because the user is directly pressing the screen).
6702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers     */
67100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    boolean mInTouchMode = true;
672e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
673e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    private ViewServer mViewServer;
6741268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath    private final ArrayList<WindowChangeListener> mWindowChangeListeners =
675cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        new ArrayList<WindowChangeListener>();
67618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes    private boolean mWindowsChanged = false;
677e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes
6782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    public interface WindowChangeListener {
679e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        public void windowsChanged();
6805d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom        public void focusChanged();
68137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    }
68237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
683ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    final Configuration mTempConfiguration = new Configuration();
684e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
685e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    // The desired scaling factor for compatible apps.
686e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes    float mCompatibleScreenScale;
68737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
68837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    // If true, only the core apps and services are being launched because the device
68937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    // is in a special boot mode, such as being encrypted or waiting for a decryption password.
69037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    // For example, when this flag is true, there will be no wallpaper service.
69100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    final boolean mOnlyCore;
692e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
693e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    public static WindowManagerService main(final Context context,
69437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes            final PowerManagerService pm, final DisplayManagerService dm,
69537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes            final InputManagerService im, final Handler wmHandler,
69662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers            final boolean haveInputMethods, final boolean showBootMsgs,
69762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers            final boolean onlyCore) {
69837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes        final WindowManagerService[] holder = new WindowManagerService[1];
69937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes        wmHandler.runWithScissors(new Runnable() {
70037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes            @Override
701e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes            public void run() {
7022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                holder[0] = new WindowManagerService(context, pm, dm, im,
703e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        haveInputMethods, showBootMsgs, onlyCore);
70437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes            }
70537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes        }, 0);
70637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes        return holder[0];
707120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    }
70837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
70937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    private void initPolicy(Handler uiHandler) {
71037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes        uiHandler.runWithScissors(new Runnable() {
711a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov            @Override
712a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov            public void run() {
71318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes                WindowManagerPolicyThread.set(Thread.currentThread(), Looper.myLooper());
71418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
71537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes                mPolicy.init(mContext, WindowManagerService.this, WindowManagerService.this);
71600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                mAnimator.mAboveUniverseLayer = mPolicy.getAboveUniverseLayer()
71772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        * TYPE_LAYER_MULTIPLIER
7183a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov                        + TYPE_LAYER_OFFSET;
7193a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov            }
7203a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov        }, 0);
7213a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov    }
7223a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
723eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    private WindowManagerService(Context context, PowerManagerService pm,
724eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier            DisplayManagerService displayManager, InputManagerService inputManager,
725eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier            boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
726eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mContext = context;
727eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mHaveInputMethods = haveInputMethods;
72862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        mAllowBootMessages = showBootMsgs;
7299f1020305292a21fd14a402b189c765a125226abSebastien Hertz        mOnlyCore = onlyCore;
73062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        mLimitedAlphaCompositing = context.getResources().getBoolean(
73162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                com.android.internal.R.bool.config_sf_limitedAlpha);
732e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        mInputManager = inputManager; // Must be before createDisplayContentLocked.
733eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mDisplayManagerService = displayManager;
734eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mDisplaySettings = new DisplaySettings(context);
735eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mDisplaySettings.readSettingsLocked();
73662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
7379f1020305292a21fd14a402b189c765a125226abSebastien Hertz        mPointerEventDispatcher = new PointerEventDispatcher(mInputManager.monitorInput(TAG));
73862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
73962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        mFxSession = new SurfaceSession();
740491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
741eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mDisplayManager.registerDisplayListener(this, null);
74272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        Display[] displays = mDisplayManager.getDisplays();
74372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        for (Display display : displays) {
744e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            createDisplayContentLocked(display);
74572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        }
746eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
74772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
74872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
74962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        mPowerManager = pm;
750e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        mPowerManager.setPolicy(mPolicy);
75172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
75262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SCREEN_FROZEN");
75372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        mScreenFrozenLock.setReferenceCounted(false);
75472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
755eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mAppTransition = new AppTransition(context, mH);
75662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
75772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        mActivityManager = ActivityManagerNative.getDefault();
758eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mBatteryStats = BatteryStatsService.getService();
7599f1020305292a21fd14a402b189c765a125226abSebastien Hertz        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
760cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null,
76118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes                new AppOpsManager.OnOpChangedInternalListener() {
762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    @Override
76300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    public void onOpChanged(int op, String packageName) {
764e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        updateAppOpsState();
76500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    }
76618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes                }
76718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes        );
76825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers
769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // Get persisted window scale setting
770cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        mWindowAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
77118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes                Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7722ced6a534157d5d963693346904389c19775d2daElliott Hughes        mTransitionAnimationScale = Settings.Global.getFloat(context.getContentResolver(),
77335aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban                Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
77435aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban        setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
77535aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban                Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale));
7762ced6a534157d5d963693346904389c19775d2daElliott Hughes
7772ced6a534157d5d963693346904389c19775d2daElliott Hughes        // Track changes to DevicePolicyManager state so we can enable/disable keyguard.
778ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers        IntentFilter filter = new IntentFilter();
779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
780c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes        mContext.registerReceiver(mBroadcastReceiver, filter);
781c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes
7822ced6a534157d5d963693346904389c19775d2daElliott Hughes        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
78300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                | PowerManager.ON_AFTER_RELEASE, TAG);
784e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        mHoldingScreenWakeLock.setReferenceCounted(false);
78500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
78600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        mAnimator = new WindowAnimator(this);
787cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
788c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes        initPolicy(UiThread.getHandler());
7892ced6a534157d5d963693346904389c19775d2daElliott Hughes
79035aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban        // Add ourself to the Watchdog monitors.
79135aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban        Watchdog.getInstance().addMonitor(this);
79235aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban
79372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        SurfaceControl.openTransaction();
79472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        try {
795cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            createWatermarkInTransaction();
79625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            mFocusedStackFrame = new FocusedStackFrame(
797e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    getDefaultDisplayContentLocked().getDisplay(), mFxSession);
798e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier        } finally {
799e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier            SurfaceControl.closeTransaction();
800e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier        }
801e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    }
80200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    public InputMonitor getInputMonitor() {
804b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers        return mInputMonitor;
80500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
807c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes    @Override
808ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            throws RemoteException {
810e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        try {
811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            return super.onTransact(code, data, reply, flags);
812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        } catch (RuntimeException e) {
813ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers            // The window manager only throws security exceptions, so let's
814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // log all others.
815ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers            if (!(e instanceof SecurityException)) {
816b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers                Slog.wtf(TAG, "Window Manager Crash", e);
817ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
818cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            throw e;
819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    private void placeWindowAfter(WindowState pos, WindowState window) {
823ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        final WindowList windows = pos.getWindowList();
824cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        final int i = windows.indexOf(pos);
82500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
826e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            TAG, "Adding window " + window + " at "
827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            + (i+1) + " of " + windows.size() + " (after " + pos + ")");
828ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        windows.add(i+1, window);
829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        mWindowsChanged = true;
830c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    }
831c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
832c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    private void placeWindowBefore(WindowState pos, WindowState window) {
833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        final WindowList windows = pos.getWindowList();
834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        int i = windows.indexOf(pos);
835ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            TAG, "Adding window " + window + " at "
83725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            + i + " of " + windows.size() + " (before " + pos + ")");
838e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (i < 0) {
839e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier            Slog.w(TAG, "placeWindowBefore: Unable to find " + pos + " in " + windows);
840e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier            i = 0;
841e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier        }
842e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier        windows.add(i, window);
843e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier        mWindowsChanged = true;
8444dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers    }
845ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    //This method finds out the index of a window that has the same app token as
847e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    //win. used for z ordering the windows in mWindows
848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    private int findIdxBasedOnAppTokens(WindowState win) {
849cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        WindowList windows = win.getWindowList();
85035aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban        for(int j = windows.size() - 1; j >= 0; j--) {
851ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers            WindowState wentry = windows.get(j);
852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if(wentry.mAppToken == win.mAppToken) {
853ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers                return j;
854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return -1;
857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
859cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    /**
860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     * Return the list of Windows from the passed token on the given Display.
861cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     * @param token The token with all the windows.
862cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     * @param displayContent The display we are interested in.
86383ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro     * @return List of windows from token that are on displayContent.
864cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     */
865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    WindowList getTokenWindowsOnDisplay(WindowToken token, DisplayContent displayContent) {
866ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        final WindowList windowList = new WindowList();
867ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        final int count = token.windows.size();
868ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        for (int i = 0; i < count; i++) {
869ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom            final WindowState win = token.windows.get(i);
870491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom            if (win.mDisplayContent == displayContent) {
871491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                windowList.add(win);
872ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom            }
87383ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro        }
874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return windowList;
875885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
8763b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier
87700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    /**
878e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier     * Recursive search through a WindowList and all of its windows' children.
879c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier     * @param targetWin The window to search for.
880c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier     * @param windows The list to search.
881885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes     * @return The index of win in windows or of the window that is an ancestor of win.
88250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers     */
883cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    private int indexOfWinInWindowList(WindowState targetWin, WindowList windows) {
884cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        for (int i = windows.size() - 1; i >= 0; i--) {
885bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            final WindowState w = windows.get(i);
886cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (w == targetWin) {
88772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                return i;
8883b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier            }
8893b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier            if (!w.mChildWindows.isEmpty()) {
890bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (indexOfWinInWindowList(targetWin, w.mChildWindows) >= 0) {
891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    return i;
892cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
89572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        return -1;
8963b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    }
8973b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier
89800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private int addAppWindowToListLocked(final WindowState win) {
899e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        final IWindow client = win.mClient;
900c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier        final WindowToken token = win.mToken;
901c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier        final DisplayContent displayContent = win.mDisplayContent;
902885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
903e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        final WindowList windows = win.getWindowList();
904c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier        final int N = windows.size();
905c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier        WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
90630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes        int tokenWindowsPos = 0;
90700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        int windowListPos = tokenWindowList.size();
90872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        if (!tokenWindowList.isEmpty()) {
909e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            // If this application has existing windows, we
910c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier            // simply place the new window on top of them... but
9115d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers            // keep the starting window on top.
912e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
913cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // Base windows go behind everything else.
914cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                WindowState lowestWindow = tokenWindowList.get(0);
91572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                placeWindowBefore(lowestWindow, win);
9163b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                tokenWindowsPos = indexOfWinInWindowList(lowestWindow, token.windows);
9173b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier            } else {
91800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                AppWindowToken atoken = win.mAppToken;
919e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
920c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier                if (atoken != null && lastWindow == atoken.startingWindow) {
921c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier                    placeWindowBefore(lastWindow, win);
922885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    tokenWindowsPos = indexOfWinInWindowList(lastWindow, token.windows);
923e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                } else {
924e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    int newIdx = findIdxBasedOnAppTokens(win);
925e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    //there is a window above this one associated with the same
92630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes                    //apptoken note that the window could be a floating window
92700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    //that was created later or a window at the top of the list of
92872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    //windows associated with this token.
929e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
930e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                            "not Base app: Adding window " + win + " at " + (newIdx + 1) + " of " +
9315d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers                            N);
932e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    windows.add(newIdx + 1, win);
933cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (newIdx < 0) {
934cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // No window from token found on win's display.
935bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        tokenWindowsPos = 0;
9363b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    } else {
9373b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                        tokenWindowsPos = indexOfWinInWindowList(
9383b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                                windows.get(newIdx), token.windows) + 1;
93900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    }
940bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    mWindowsChanged = true;
941cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
942ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
943bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            return tokenWindowsPos;
944bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        }
9453b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier
9463b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        // No windows from this token on this display
9473b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        if (localLOGV) Slog.v(TAG, "Figuring out where to add app window " + client.asBinder()
94800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                + " (token=" + token + ")");
949bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        // Figure out where the window should go, based on the
950cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // order of applications.
951ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        WindowState pos = null;
95272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
95372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        final ArrayList<Task> tasks = displayContent.getTasks();
95472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        int taskNdx;
9553b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        int tokenNdx = -1;
9563b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
95725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
95800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
95972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                final AppWindowToken t = tokens.get(tokenNdx);
96000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (t == token) {
961cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    --tokenNdx;
962ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    if (tokenNdx < 0) {
96372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        --taskNdx;
9643b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                        if (taskNdx >= 0) {
9653b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                            tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
96600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        }
96700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    }
96800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    break;
969cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
970ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
97172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                // We haven't reached the token yet; if this token
9723b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                // is not going to the bottom and has windows on this display, we can
9733b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                // use it as an anchor for when we do reach the token.
97400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
97553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                if (!t.sendingToBottom && tokenWindowList.size() > 0) {
97653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                    pos = tokenWindowList.get(0);
97700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
978cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
979ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            if (tokenNdx >= 0) {
98072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                // early exit
98172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                break;
98272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            }
9832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
9842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
98525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        // We now know the index into the apps.  If we found
98600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // an app window above, that gives us the position; else
98772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        // we need to look some more.
988f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes        if (pos != null) {
989cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // Move behind any windows attached to this one.
990ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
99172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            if (atoken != null) {
9922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                tokenWindowList =
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        getTokenWindowsOnDisplay(atoken, displayContent);
99400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                final int NC = tokenWindowList.size();
99500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (NC > 0) {
996cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    WindowState bottom = tokenWindowList.get(0);
997ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    if (bottom.mSubLayer < 0) {
99872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        pos = bottom;
9992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    }
10002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
100100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
100253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            placeWindowBefore(pos, win);
100353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            return tokenWindowsPos;
1004cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
1005ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
100672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        // Continue looking down until we find the first
100772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        // token that has windows on this display.
100872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        for ( ; taskNdx >= 0; --taskNdx) {
10092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
10102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            for ( ; tokenNdx >= 0; --tokenNdx) {
1011bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                final AppWindowToken t = tokens.get(tokenNdx);
101200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                tokenWindowList = getTokenWindowsOnDisplay(t, displayContent);
101372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                final int NW = tokenWindowList.size();
1014f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                if (NW > 0) {
1015cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    pos = tokenWindowList.get(NW-1);
1016ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    break;
101772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                }
10182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
10192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (tokenNdx >= 0) {
102000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                // found
102100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                break;
1022cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1023ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
102472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
10252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (pos != null) {
10262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            // Move in front of any windows attached to this
102700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            // one.
102853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            WindowToken atoken = mTokenMap.get(pos.mClient.asBinder());
102953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            if (atoken != null) {
1030cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                final int NC = atoken.windows.size();
1031ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (NC > 0) {
103272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    WindowState top = atoken.windows.get(NC-1);
103372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    if (top.mSubLayer >= 0) {
103472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        pos = top;
10352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    }
10362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
103725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            }
103800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            placeWindowAfter(pos, win);
103972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            return tokenWindowsPos;
1040f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes        }
1041cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1042ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        // Just search for the start of this layer.
104372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        final int myLayer = win.mBaseLayer;
10442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int i;
10452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        for (i = 0; i < N; i++) {
104600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            WindowState w = windows.get(i);
104700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (w.mBaseLayer > myLayer) {
1048cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                break;
1049ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
105072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        }
10512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
10522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                "Based on layer: Adding window " + win + " at " + i + " of " + N);
105300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        windows.add(i, win);
105453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers        mWindowsChanged = true;
105553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers        return tokenWindowsPos;
1056cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
1057ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
105872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    private void addFreeWindowToListLocked(final WindowState win) {
105972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        final WindowList windows = win.getWindowList();
106072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
10612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        // Figure out where window should go, based on layer.
10622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final int myLayer = win.mBaseLayer;
106325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        int i;
106400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        for (i = windows.size() - 1; i >= 0; i--) {
106572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            if (windows.get(i).mBaseLayer <= myLayer) {
1066f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                break;
1067cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1068ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
106972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        i++;
10702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (DEBUG_FOCUS_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
10712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                "Free window: Adding window " + win + " at " + i + " of " + windows.size());
107200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        windows.add(i, win);
107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        mWindowsChanged = true;
1074cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
1075ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
107672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) {
10772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final WindowToken token = win.mToken;
10782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final DisplayContent displayContent = win.mDisplayContent;
107900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        final WindowState attached = win.mAttachedWindow;
108053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers
108153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers        WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent);
1082cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1083ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        // Figure out this window's ordering relative to the window
108472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        // it is attached to.
108572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        final int NA = tokenWindowList.size();
108672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        final int sublayer = win.mSubLayer;
10872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int largestSublayer = Integer.MIN_VALUE;
10882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        WindowState windowWithLargestSublayer = null;
1089bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        int i;
109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        for (i = 0; i < NA; i++) {
109172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            WindowState w = tokenWindowList.get(i);
1092f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes            final int wSublayer = w.mSubLayer;
1093cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (wSublayer >= largestSublayer) {
1094ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                largestSublayer = wSublayer;
109572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                windowWithLargestSublayer = w;
10962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
10972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (sublayer < 0) {
109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                // For negative sublayers, we go below all windows
109900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                // in the same sublayer.
1100cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (wSublayer >= sublayer) {
1101ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    if (addToToken) {
110272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
11032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        token.windows.add(i, win);
11042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    }
110500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    placeWindowBefore(wSublayer >= 0 ? attached : w, win);
110653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                    break;
110753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                }
1108cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            } else {
1109ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                // For positive sublayers, we go above all windows
111072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                // in the same sublayer.
111172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                if (wSublayer > sublayer) {
111272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    if (addToToken) {
11132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
11142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        token.windows.add(i, win);
111525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                    }
111600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    placeWindowBefore(w, win);
111772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    break;
1118f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                }
1119cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1120ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
112172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        if (i >= NA) {
11222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (addToToken) {
11232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
112400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                token.windows.add(win);
112500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1126cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (sublayer < 0) {
1127ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                placeWindowBefore(attached, win);
112872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            } else {
11292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                placeWindowAfter(largestSublayer >= 0
11302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                 ? windowWithLargestSublayer
113100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                 : attached,
113253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                 win);
113353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            }
1134cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
1135ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    }
113672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
113772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    private void addWindowToListInOrderLocked(final WindowState win, boolean addToToken) {
113872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        if (DEBUG_FOCUS_LIGHT) Slog.d(TAG, "addWindowToListInOrderLocked: win=" + win +
11392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                " Callers=" + Debug.getCallers(4));
11402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (win.mAttachedWindow == null) {
114125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            final WindowToken token = win.mToken;
114200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            int tokenWindowsPos = 0;
114372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            if (token.appWindowToken != null) {
1144f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                tokenWindowsPos = addAppWindowToListLocked(win);
1145cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            } else {
1146ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                addFreeWindowToListLocked(win);
114772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            }
11482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (addToToken) {
11492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + win + " to " + token);
115000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                token.windows.add(tokenWindowsPos, win);
115100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1152cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        } else {
1153ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            addAttachedWindowToListLocked(win, addToToken);
115472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        }
11552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
11562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (win.mAppToken != null && addToToken) {
115700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            win.mAppToken.allAppWindows.add(win);
115853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers        }
115953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    }
1160cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1161ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    static boolean canBeImeTarget(WindowState w) {
116272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        final int fl = w.mAttrs.flags
116372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
116472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)
11652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                || w.mAttrs.type == TYPE_APPLICATION_STARTING) {
11662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (DEBUG_INPUT_METHOD) {
116725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                Slog.i(TAG, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding());
116800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (!w.isVisibleOrAdding()) {
116972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    Slog.i(TAG, "  mSurface=" + w.mWinAnimator.mSurfaceControl
1170f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                            + " relayoutCalled=" + w.mRelayoutCalled + " viewVis=" + w.mViewVisibility
1171cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            + " policyVis=" + w.mPolicyVisibility
1172ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            + " policyVisAfterAnim=" + w.mPolicyVisibilityAfterAnim
117372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                            + " attachHid=" + w.mAttachedHidden
11742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            + " exiting=" + w.mExiting + " destroying=" + w.mDestroying);
11752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    if (w.mAppToken != null) {
117600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        Slog.i(TAG, "  mAppToken.hiddenRequested=" + w.mAppToken.hiddenRequested);
117700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    }
1178cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
1179ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
118072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            return w.isVisibleOrAdding();
11812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
11822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        return false;
118300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
118453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers
118553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    /**
1186cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes     * Dig through the WindowStates and find the one that the Input Method will target.
1187ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro     * @param willMove
118872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes     * @return The index+1 in mWindows of the discovered target.
118972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes     */
119072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
11912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
11922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        // same display. Or even when the current IME/target are not on the same screen as the next
119325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        // IME/target. For now only look for input windows on the main screen.
11941b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers        WindowList windows = getDefaultWindowListLocked();
119572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        WindowState w = null;
1196cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        int i;
1197ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        for (i = windows.size() - 1; i >= 0; --i) {
119872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes            WindowState win = windows.get(i);
11992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
12002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (DEBUG_INPUT_METHOD && willMove) Slog.i(TAG, "Checking window @" + i
120100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    + " " + win + " fl=0x" + Integer.toHexString(win.mAttrs.flags));
120200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (canBeImeTarget(win)) {
1203cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                w = win;
1204ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                //Slog.i(TAG, "Putting input method here!");
120572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
12062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                // Yet more tricksyness!  If this window is a "starting"
12072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                // window, we do actually want to be on top of it, but
120800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                // it is not -really- where input will go.  So if the caller
120953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                // is not actually looking to move the IME, look down below
1210cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // for a real window to target...
1211ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (!willMove
12121bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        && w.mAttrs.type == TYPE_APPLICATION_STARTING
1213cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        && i > 0) {
121472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    WindowState wb = windows.get(i-1);
12153b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
12163b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                        i--;
121725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                        w = wb;
121800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    }
121900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
1220cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                break;
1221cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1222cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
1223ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1224bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        // Now w is either mWindows[0] or an IME (or null if mWindows is empty).
1225bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
12263b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        if (DEBUG_INPUT_METHOD && willMove) Slog.v(TAG, "Proposed new IME target: " + w);
12273b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier
122800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // Now, a special case -- if the last target's window is in the
122900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // process of exiting, and is above the new target, keep on the
123000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // last target to avoid flicker.  Consider for example a Dialog with
1231cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // the IME shown: when the Dialog is dismissed, we want to keep
1232ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        // the IME above it until it is completely gone so it doesn't drop
1233bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        // behind the dialog or its full-screen scrim.
1234bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        final WindowState curTarget = mInputMethodTarget;
12353b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        if (curTarget != null
12363b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                && curTarget.isDisplayedLw()
123700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                && curTarget.isClosing()
123853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                && (w == null || curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
123900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
1240cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            return windows.indexOf(curTarget) + 1;
1241ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
1242bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
1243bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
1244cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                + w + " willMove=" + willMove);
124572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
12462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (willMove && w != null) {
12472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            AppWindowToken token = curTarget == null ? null : curTarget.mAppToken;
124825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            if (token != null) {
124900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // Now some fun for dealing with window animations that
1251f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                // modify the Z order.  We need to look at all windows below
1252cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // the current target that are in this app, finding the highest
1253ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                // visible one in layering.
1254bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                WindowState highestTarget = null;
1255bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                int highestPos = 0;
12562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (token.mAppAnimator.animating || token.mAppAnimator.animation != null) {
12572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    WindowList curWindows = curTarget.getWindowList();
125800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    int pos = curWindows.indexOf(curTarget);
125900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    while (pos >= 0) {
1260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        WindowState win = curWindows.get(pos);
1261ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                        if (win.mAppToken != token) {
1262bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                            break;
1263bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        }
12642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        if (!win.mRemoved) {
12652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            if (highestTarget == null || win.mWinAnimator.mAnimLayer >
126600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                    highestTarget.mWinAnimator.mAnimLayer) {
126753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                highestTarget = win;
1268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                                highestPos = pos;
1269ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            }
12701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        }
1271cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        pos--;
127272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                    }
12732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
12742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
127525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                if (highestTarget != null) {
127600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    if (DEBUG_INPUT_METHOD) Slog.v(TAG, mAppTransition + " " + highestTarget
1277cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            + " animating=" + highestTarget.mWinAnimator.isAnimating()
1278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                            + " layer=" + highestTarget.mWinAnimator.mAnimLayer
1279cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            + " new layer=" + w.mWinAnimator.mAnimLayer);
1280ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1281bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    if (mAppTransition.isTransitionSet()) {
1282bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        // If we are currently setting up for an animation,
12832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        // hold everything until we can find out what will happen.
12842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        mInputMethodTargetWaitingAnim = true;
128500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        mInputMethodTarget = highestTarget;
128600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        return highestPos + 1;
1287cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    } else if (highestTarget.mWinAnimator.isAnimating() &&
1288ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            highestTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
1289bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        // If the window we are currently targeting is involved
1290bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        // with an animation, and it is on top of the next target
12912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        // we will be over, then hold off on moving until
12922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        // that is done.
129300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        mInputMethodTargetWaitingAnim = true;
129453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                        mInputMethodTarget = highestTarget;
1295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        return highestPos + 1;
1296ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    }
12971bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                }
1298cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
129972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        }
13002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
13012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        //Slog.i(TAG, "Placing input method @" + (i+1));
1302bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (w != null) {
130300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (willMove) {
1304cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to "
1305f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                        + w + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
1306cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                mInputMethodTarget = w;
1307ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                mInputMethodTargetWaitingAnim = false;
1308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (w.mAppToken != null) {
1309bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
13102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                } else {
13112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    setInputMethodAnimLayerAdjustment(0);
131200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
131300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1314cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            return i+1;
1315ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
1316bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (willMove) {
1317bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " + curTarget + " to null."
13182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    + (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
13192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            mInputMethodTarget = null;
132000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            setInputMethodAnimLayerAdjustment(0);
132153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers        }
1322cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return -1;
1323ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    }
13241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes
1325cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    void addInputMethodWindowToListLocked(WindowState win) {
132672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        int pos = findDesiredInputMethodWindowIndexLocked(true);
13272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (pos >= 0) {
13282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            win.mTargetAppToken = mInputMethodTarget.mAppToken;
132925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(
133000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    TAG, "Adding input method window " + win + " at " + pos);
1331cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // TODO(multidisplay): IMEs are only supported on the default display.
1332f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes            getDefaultWindowListLocked().add(pos, win);
1333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            mWindowsChanged = true;
1334ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            moveInputMethodDialogsLocked(pos+1);
1335bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            return;
1336bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        }
13372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        win.mTargetAppToken = null;
13382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        addWindowToListInOrderLocked(win, true);
133900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        moveInputMethodDialogsLocked(pos);
134000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
1341cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1342ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    void setInputMethodAnimLayerAdjustment(int adj) {
1343bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (DEBUG_LAYERS) Slog.v(TAG, "Setting im layer adj to " + adj);
1344bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        mInputMethodAnimLayerAdjustment = adj;
13452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        WindowState imw = mInputMethodWindow;
13462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (imw != null) {
134700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
134853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
1349cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    + " anim layer: " + imw.mWinAnimator.mAnimLayer);
1350ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            int wi = imw.mChildWindows.size();
13511bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            while (wi > 0) {
1352cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                wi--;
135372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                WindowState cw = imw.mChildWindows.get(wi);
13542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
13552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + cw
135625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                        + " anim layer: " + cw.mWinAnimator.mAnimLayer);
135700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1358cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
1359f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes        int di = mInputMethodDialogs.size();
1360cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        while (di > 0) {
1361ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            di --;
1362bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            imw = mInputMethodDialogs.get(di);
1363bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
13642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (DEBUG_LAYERS) Slog.v(TAG, "IM win " + imw
13652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    + " anim layer: " + imw.mWinAnimator.mAnimLayer);
136600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
136700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
1368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1369ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
1370bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        WindowList windows = win.getWindowList();
1371bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        int wpos = windows.indexOf(win);
13722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (wpos >= 0) {
13732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (wpos < interestingPos) interestingPos--;
137400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing at " + wpos + ": " + win);
137553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            windows.remove(wpos);
1376cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            mWindowsChanged = true;
1377ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            int NC = win.mChildWindows.size();
13781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            while (NC > 0) {
1379cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                NC--;
138072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                WindowState cw = win.mChildWindows.get(NC);
13812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                int cpos = windows.indexOf(cw);
13822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (cpos >= 0) {
138325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                    if (cpos < interestingPos) interestingPos--;
138400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Temp removing child at "
1385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            + cpos + ": " + cw);
1386f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                    windows.remove(cpos);
1387cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
1388ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
1389bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        }
1390bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        return interestingPos;
13912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
13922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
139300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    private void reAddWindowToListInOrderLocked(WindowState win) {
139400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        addWindowToListInOrderLocked(win, false);
1395cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // This is a hack to get all of the child windows added as well
1396ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        // at the right position.  Child windows should be rare and
1397bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        // this case should be rare, so it shouldn't be that big a deal.
1398bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        WindowList windows = win.getWindowList();
13992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int wpos = windows.indexOf(win);
14002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (wpos >= 0) {
140100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "ReAdd removing from " + wpos + ": " + win);
140253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers            windows.remove(wpos);
1403cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            mWindowsChanged = true;
1404ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            reAddWindowLocked(wpos, win);
14051bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        }
1406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
140772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
14082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    void logWindowList(final WindowList windows, String prefix) {
14092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int N = windows.size();
141025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        while (N > 0) {
141100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            N--;
1412cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            Slog.v(TAG, prefix + "#" + N + ": " + windows.get(N));
1413f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes        }
1414cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
1415ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1416bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    void moveInputMethodDialogsLocked(int pos) {
1417bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        ArrayList<WindowState> dialogs = mInputMethodDialogs;
14182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
14192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        // TODO(multidisplay): IMEs are only supported on the default display.
142000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        WindowList windows = getDefaultWindowListLocked();
142100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        final int N = dialogs.size();
1422cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
1423ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        for (int i=0; i<N; i++) {
1424bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
1425bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        }
14262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (DEBUG_INPUT_METHOD) {
14272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            Slog.v(TAG, "Window list w/pos=" + pos);
142800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            logWindowList(windows, "  ");
142953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers        }
1430cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1431ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        if (pos >= 0) {
14321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
1433cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (pos < windows.size()) {
143472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                WindowState wp = windows.get(pos);
14352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (wp == mInputMethodWindow) {
14362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    pos++;
143725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                }
143800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1439cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
1440f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes            for (int i=0; i<N; i++) {
1441cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                WindowState win = dialogs.get(i);
1442ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                win.mTargetAppToken = targetAppToken;
1443bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                pos = reAddWindowLocked(pos, win);
1444bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            }
14452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (DEBUG_INPUT_METHOD) {
14462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                Slog.v(TAG, "Final window list:");
144700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                logWindowList(windows, "  ");
144800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1449cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            return;
1450ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
1451bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        for (int i=0; i<N; i++) {
1452bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            WindowState win = dialogs.get(i);
14532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            win.mTargetAppToken = null;
14542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            reAddWindowToListInOrderLocked(win);
145500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DEBUG_INPUT_METHOD) {
145653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                Slog.v(TAG, "No IM target, final list:");
1457cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                logWindowList(windows, "  ");
1458ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
14591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        }
1460cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
146172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
14622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
14632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final WindowState imWin = mInputMethodWindow;
146425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        final int DN = mInputMethodDialogs.size();
146500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        if (imWin == null && DN == 0) {
1466cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            return false;
1467cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
1468ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1469ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        // TODO(multidisplay): IMEs are only supported on the default display.
1470ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        WindowList windows = getDefaultWindowListLocked();
14712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
14722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int imPos = findDesiredInputMethodWindowIndexLocked(true);
147300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        if (imPos >= 0) {
147400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            // In this case, the input method windows are to be placed
1475cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // immediately above the window they are targeting.
1476ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1477bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            // First check to see if the input method windows are already
1478bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            // located here, and contiguous.
14792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            final int N = windows.size();
14802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            WindowState firstImWin = imPos < N
148100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    ? windows.get(imPos) : null;
148253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers
1483cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // Figure out the actual input method window that should be
1484ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            // at the bottom of their stack.
1485bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            WindowState baseImWin = imWin != null
14863b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    ? imWin : mInputMethodDialogs.get(0);
14873b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier            if (baseImWin.mChildWindows.size() > 0) {
14883b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                WindowState cw = baseImWin.mChildWindows.get(0);
148900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (cw.mSubLayer < 0) baseImWin = cw;
1490bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            }
1491cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1492ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            if (firstImWin == baseImWin) {
1493bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                // The windows haven't moved...  but are they still contiguous?
1494bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                // First find the top IM window.
14953b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                int pos = imPos+1;
14963b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                while (pos < N) {
14973b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    if (!(windows.get(pos)).mIsImWindow) {
149800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        break;
1499bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    }
1500cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    pos++;
1501ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                }
1502885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                pos++;
15033b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                // Now there should be no more input method windows above.
15043b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                while (pos < N) {
150500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    if ((windows.get(pos)).mIsImWindow) {
1506e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        break;
1507e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    }
150800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    pos++;
1509cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
1510ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (pos >= N) {
1511885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    // Z order is good.
15123b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    // The IM target window may be changed, so update the mTargetAppToken.
151300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    if (imWin != null) {
1514e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
15152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers                    }
1516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    return false;
1517ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                }
1518885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            }
15192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
15202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (imWin != null) {
152100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (DEBUG_INPUT_METHOD) {
1522e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    Slog.v(TAG, "Moving IM from " + imPos);
1523e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    logWindowList(windows, "  ");
1524e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                }
1525d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                imPos = tmpRemoveWindowLocked(imPos, imWin);
1526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (DEBUG_INPUT_METHOD) {
1527ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    Slog.v(TAG, "List after removing with new pos " + imPos + ":");
1528885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    logWindowList(windows, "  ");
15292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
153000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
1531e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                reAddWindowLocked(imPos, imWin);
1532e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                if (DEBUG_INPUT_METHOD) {
1533d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                    Slog.v(TAG, "List after moving IM to " + imPos + ":");
1534cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    logWindowList(windows, "  ");
1535ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                }
1536885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
15372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            } else {
15382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                moveInputMethodDialogsLocked(imPos);
153900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1540e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
1541e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        } else {
1542bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            // In this case, the input method windows go in a fixed layer,
1543885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            // because they aren't currently associated with a focus window.
15442fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
15452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (imWin != null) {
15462fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers                if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Moving IM from " + imPos);
1547e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                tmpRemoveWindowLocked(0, imWin);
1548bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                imWin.mTargetAppToken = null;
15492fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers                reAddWindowToListInOrderLocked(imWin);
1550885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                if (DEBUG_INPUT_METHOD) {
15512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    Slog.v(TAG, "List with no IM target:");
15522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    logWindowList(windows, "  ");
155300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
1554e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                if (DN > 0) moveInputMethodDialogsLocked(-1);
1555e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            } else {
1556d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz                moveInputMethodDialogsLocked(-1);
1557885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            }
15582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
15592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
15602fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
1561e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (needAssignLayers) {
1562d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz            assignLayersLocked(windows);
15632fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers        }
1564885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1565bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        return true;
1566cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
1567ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1568885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    final boolean isWallpaperVisible(WindowState wallpaperTarget) {
1569bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
1570cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
1571ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
1572885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
1573bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                + " upper=" + mUpperWallpaperTarget
1574cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                + " lower=" + mLowerWallpaperTarget);
1575ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        return (wallpaperTarget != null
1576885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
1577bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
1578cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                || mUpperWallpaperTarget != null
1579ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                || mLowerWallpaperTarget != null;
1580885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
1581bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
1582cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
1583ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
1584885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1585bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    int adjustWallpaperWindowsLocked() {
1586cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        mInnerFields.mWallpaperMayChange = false;
1587ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        boolean targetChanged = false;
1588885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1589bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        // TODO(multidisplay): Wallpapers on main screen only.
1590cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
1591ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        final int dw = displayInfo.logicalWidth;
1592885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes        final int dh = displayInfo.logicalHeight;
1593bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
1594cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // First find top-most window that has asked to be on top of the
1595ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        // wallpaper; all wallpapers go behind it.
15961bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        final WindowList windows = getDefaultWindowListLocked();
1597bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        int N = windows.size();
1598cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        WindowState w = null;
1599ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        WindowState foundW = null;
16001bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        int foundI = 0;
1601bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        WindowState topCurW = null;
160283ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro        int topCurI = 0;
1603cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        int windowDetachedI = -1;
16041bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        int i = N;
1605bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        while (i > 0) {
16069b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro            i--;
1607ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            w = windows.get(i);
16081bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            if ((w.mAttrs.type == TYPE_WALLPAPER)) {
1609bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (topCurW == null) {
1610cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    topCurW = w;
1611ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    topCurI = i;
16121bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                }
1613bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                continue;
1614cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1615ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            topCurW = null;
16161bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
1617bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                // If this window's app token is hidden and not animating,
1618885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                // it is of no interest to us.
1619885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
16201bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                    if (DEBUG_WALLPAPER) Slog.v(TAG,
1621bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                            "Skipping hidden and not animating token: " + w);
1622885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    continue;
1623885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                }
16241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            }
1625bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
1626885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
1627885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0 && w.isOnScreen()
1628885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
1629bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (DEBUG_WALLPAPER) Slog.v(TAG,
1630885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        "Found wallpaper target: #" + i + "=" + w);
1631885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                foundW = w;
1632885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                foundI = i;
1633bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
1634885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    // The current wallpaper target is animating, so we'll
1635885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    // look behind it for another possible target and figure
1636885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    // out what is going on below.
1637bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
1638885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                            + ": token animating, looking behind.");
1639885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    continue;
1640885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                }
1641bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                break;
1642885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            } else if (w == mAnimator.mWindowDetachedWallpaper) {
1643885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                windowDetachedI = i;
1644885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            }
1645bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        }
1646885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1647885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes        if (foundW == null && windowDetachedI >= 0) {
1648885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
1649bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    "Found animating detached wallpaper activity: #" + i + "=" + w);
1650885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            foundW = w;
1651885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            foundI = windowDetachedI;
1652885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes        }
1653bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
1654885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes        if (mWallpaperTarget != foundW
1655885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
1656885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            if (DEBUG_WALLPAPER_LIGHT) {
1657bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                Slog.v(TAG, "New wallpaper target: " + foundW
1658885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        + " oldTarget: " + mWallpaperTarget);
1659885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            }
1660885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1661bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            mLowerWallpaperTarget = null;
1662885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            mUpperWallpaperTarget = null;
1663885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1664885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            WindowState oldW = mWallpaperTarget;
1665bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            mWallpaperTarget = foundW;
1666885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            targetChanged = true;
1667885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1668885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            // Now what is happening...  if the current and new targets are
1669bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            // animating, then we are in our super special mode!
1670885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes            if (foundW != null && oldW != null) {
1671885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                boolean oldAnim = oldW.isAnimatingLw();
1672885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                boolean foundAnim = foundW.isAnimatingLw();
1673bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (DEBUG_WALLPAPER_LIGHT) {
1674885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    Slog.v(TAG, "New animation: " + foundAnim
1675885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                            + " old animation: " + oldAnim);
1676885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                }
1677bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (foundAnim && oldAnim) {
1678885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    int oldI = windows.indexOf(oldW);
1679885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    if (DEBUG_WALLPAPER_LIGHT) {
1680885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
1681bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    }
1682885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                    if (oldI >= 0) {
1683885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        if (DEBUG_WALLPAPER_LIGHT) {
1684885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                            Slog.v(TAG, "Animating wallpapers: old#" + oldI
1685bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    + "=" + oldW + "; new#" + foundI
1686885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                                    + "=" + foundW);
1687885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes                        }
1688885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1689bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        // Set the new target correctly.
1690cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
1691ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            if (DEBUG_WALLPAPER_LIGHT) {
16921bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                                Slog.v(TAG, "Old wallpaper still the target.");
1693cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            }
169472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                            mWallpaperTarget = oldW;
16953b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                            foundW = oldW;
169625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                            foundI = oldI;
1697e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        }
169800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        // Now set the upper and lower wallpaper targets
1699cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // correctly, and make sure that we are positioning
1700cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // the wallpaper below the lower.
1701cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        else if (foundI > oldI) {
1702ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            // The new target is on top of the old one.
17031bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                            if (DEBUG_WALLPAPER_LIGHT) {
17043b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                                Slog.v(TAG, "Found target above old target.");
170500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            }
1706e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                            mUpperWallpaperTarget = foundW;
170700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            mLowerWallpaperTarget = oldW;
1708cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            foundW = oldW;
1709ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            foundI = oldI;
17101bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        } else {
17113b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                            // The new target is below the old one.
171200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            if (DEBUG_WALLPAPER_LIGHT) {
1713e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                Slog.v(TAG, "Found target below old target.");
171400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            }
1715cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            mUpperWallpaperTarget = oldW;
1716ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            mLowerWallpaperTarget = foundW;
17171bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        }
1718cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
171972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                }
17202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
172125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers
1722e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        } else if (mLowerWallpaperTarget != null) {
1723cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // Is it time to stop animating?
1724f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes            if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
1725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (DEBUG_WALLPAPER_LIGHT) {
1726ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    Slog.v(TAG, "No longer animating wallpaper targets!");
17271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                }
17282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                mLowerWallpaperTarget = null;
172900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                mUpperWallpaperTarget = null;
1730e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                mWallpaperTarget = foundW;
1731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                targetChanged = true;
1732ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
17331bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        }
17342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
173500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        boolean visible = foundW != null;
1736e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (visible) {
1737cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // The window is visible to the compositor...  but is it visible
1738ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            // to the user?  That is what the wallpaper cares about.
17391bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            visible = isWallpaperVisible(foundW);
1740cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
174172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
17422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            // If the wallpaper target is animating, we may need to copy
174325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            // its layer adjustment.  Only do this if we are not transfering
1744e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            // between two wallpaper targets.
1745cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            mWallpaperAnimLayerAdjustment =
1746f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                    (mLowerWallpaperTarget == null && foundW.mAppToken != null)
1747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
1748ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17491bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            final int maxLayer = mPolicy.getMaxWallpaperLayer()
17502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    * TYPE_LAYER_MULTIPLIER
175100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    + TYPE_LAYER_OFFSET;
1752e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
1753cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            // Now w is the window we are supposed to be behind...  but we
1754ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            // need to be sure to also be behind any of its attached windows,
17551bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            // AND any starting window associated with it, AND below the
17562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            // maximum layer the policy allows for wallpapers.
175700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            while (foundI > 0) {
1758e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                WindowState wb = windows.get(foundI-1);
1759cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (wb.mBaseLayer < maxLayer &&
1760ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                        wb.mAttachedWindow != foundW &&
17611bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                        (foundW.mAttachedWindow == null ||
1762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                                wb.mAttachedWindow != foundW.mAttachedWindow) &&
176372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
17642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                foundW.mToken == null || wb.mToken != foundW.mToken)) {
176525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                    // This window is not related to the previous one in any
1766e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    // interesting way, so stop here.
1767cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    break;
1768f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                }
1769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                foundW = wb;
1770ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                foundI--;
17711bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            }
17722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        } else {
177300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
1774e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
1775cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1776ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        if (foundW == null && topCurW != null) {
17771bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            // There is no wallpaper target, so it goes at the bottom.
17782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            // We will assume it is the same place as last time, if known.
177900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            foundW = topCurW;
1780e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            foundI = topCurI+1;
1781cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        } else {
1782ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            // Okay i is the position immediately above the wallpaper.  Look at
17831bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            // what is below it for later.
1784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            foundW = foundI > 0 ? windows.get(foundI-1) : null;
178572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        }
17862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
178725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        if (visible) {
1788e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            if (mWallpaperTarget.mWallpaperX >= 0) {
1789cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                mLastWallpaperX = mWallpaperTarget.mWallpaperX;
1790f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
1791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1792ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            if (mWallpaperTarget.mWallpaperY >= 0) {
17931bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                mLastWallpaperY = mWallpaperTarget.mWallpaperY;
17942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
179500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
1796e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
1797cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1798ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        // Start stepping backwards from here, ensuring that our wallpaper windows
17991bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        // are correctly placed.
18002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int changed = 0;
180100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        int curTokenIndex = mWallpaperTokens.size();
1802e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        while (curTokenIndex > 0) {
1803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            curTokenIndex--;
1804ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            WindowToken token = mWallpaperTokens.get(curTokenIndex);
18051bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            if (token.hidden == visible) {
1806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
180772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        "Wallpaper token " + token + " hidden=" + !visible);
18082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
180925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                token.hidden = !visible;
1810e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                // Need to do a layout to ensure the wallpaper now has the
1811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // correct size.
1812f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                getDefaultDisplayContentLocked().layoutNeeded = true;
1813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
1814ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18151bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            int curWallpaperIndex = token.windows.size();
18162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            while (curWallpaperIndex > 0) {
181700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                curWallpaperIndex--;
1818e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                WindowState wallpaper = token.windows.get(curWallpaperIndex);
1819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1820ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (visible) {
18211bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                    updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
18222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
182300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1824e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                // First, make sure the client has the current visibility
1825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // state.
1826ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                dispatchWallpaperVisibility(wallpaper, visible);
18271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes
1828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
182972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
18302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
183125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers
1832e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                // First, if this window is at the current index, then all
1833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // is well.
1834f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                if (wallpaper == foundW) {
1835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    foundI--;
1836ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    foundW = foundI > 0
18371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                            ? windows.get(foundI-1) : null;
18382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    continue;
183900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
1840e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
1841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // The window didn't match...  the current wallpaper window,
1842ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                // wherever it is, is in the wrong place, so make sure it is
18431bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                // not in the list.
18442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                int oldIndex = windows.indexOf(wallpaper);
184500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (oldIndex >= 0) {
1846e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
1847cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            + oldIndex + ": " + wallpaper);
1848ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    windows.remove(oldIndex);
18491bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                    mWindowsChanged = true;
1850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (oldIndex < foundI) {
185172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                        foundI--;
18522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    }
185325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers                }
1854e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
1855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
1856f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes                // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
1857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                int insertionIndex = 0;
1858ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (visible && foundW != null) {
18591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                    final int type = foundW.mAttrs.type;
18602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    if (type == TYPE_KEYGUARD || type == TYPE_KEYGUARD_SCRIM) {
186100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        insertionIndex = windows.indexOf(foundW);
1862e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    }
1863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
1864ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
18651bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                    Slog.v(TAG, "Moving wallpaper " + wallpaper
18662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            + " from " + oldIndex + " to " + insertionIndex);
186700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
1868e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
1869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                windows.add(insertionIndex, wallpaper);
1870ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                mWindowsChanged = true;
18711bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
1872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
187372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes        }
18742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
187525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers        /*
1876e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        final TaskStack targetStack =
1877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                mWallpaperTarget == null ? null : mWallpaperTarget.getStack();
1878f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes        if ((changed & ADJUST_WALLPAPER_LAYERS_CHANGED) != 0 &&
1879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                targetStack != null && !targetStack.isHomeStack()) {
1880ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            // If the wallpaper target is not on the home stack then make sure that all windows
18811bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes            // from other non-home stacks are above the wallpaper.
18822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            for (i = foundI - 1; i >= 0; --i) {
188300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                WindowState win = windows.get(i);
1884e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                if (!win.isVisibleLw()) {
1885cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    continue;
1886ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                }
18871bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                final TaskStack winStack = win.getStack();
18882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (winStack != null && !winStack.isHomeStack() && winStack != targetStack) {
188900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    windows.remove(i);
1890e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    windows.add(foundI + 1, win);
1891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
1892ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
18931bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        }
1894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        */
189572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
18962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (targetChanged && DEBUG_WALLPAPER_LIGHT) {
189725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers            Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
1898e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    + " lower=" + mLowerWallpaperTarget + " upper="
1899cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    + mUpperWallpaperTarget);
1900cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
1901ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19021bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        return changed;
19032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
190400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1905e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    void setWallpaperAnimLayerAdjustmentLocked(int adj) {
1906cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
1907ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                "Setting wallpaper layer adj to " + adj);
19081bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes        mWallpaperAnimLayerAdjustment = adj;
19092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int curTokenIndex = mWallpaperTokens.size();
191000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        while (curTokenIndex > 0) {
1911e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            curTokenIndex--;
1912cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowToken token = mWallpaperTokens.get(curTokenIndex);
1913ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            int curWallpaperIndex = token.windows.size();
1914814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes            while (curWallpaperIndex > 0) {
19151d99e4549309d05007d041d058b1878de88e9585Ian Rogers                curWallpaperIndex--;
19161d99e4549309d05007d041d058b1878de88e9585Ian Rogers                WindowState wallpaper = token.windows.get(curWallpaperIndex);
19171d99e4549309d05007d041d058b1878de88e9585Ian Rogers                wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
19181d99e4549309d05007d041d058b1878de88e9585Ian Rogers                if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
19191d99e4549309d05007d041d058b1878de88e9585Ian Rogers                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
19201d99e4549309d05007d041d058b1878de88e9585Ian Rogers            }
19211d99e4549309d05007d041d058b1878de88e9585Ian Rogers        }
1922bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
192300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1924e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
192500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            boolean sync) {
1926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean changed = false;
1927ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        boolean rawChanged = false;
1928814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
1929e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
1930e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
1931814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
193200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        changed = wallpaperWin.mXOffset != offset;
1933e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (changed) {
193400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
1935cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    + wallpaperWin + " x: " + offset);
1936ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            wallpaperWin.mXOffset = offset;
1937814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        }
19382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
193900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            wallpaperWin.mWallpaperX = wpx;
1940e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            wallpaperWin.mWallpaperXStep = wpxs;
1941814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes            rawChanged = true;
1942814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        }
1943814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
19442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
194500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
1946e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
1947814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
1948814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        if (wallpaperWin.mYOffset != offset) {
1949bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
1950bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    + wallpaperWin + " y: " + offset);
19512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            changed = true;
195200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            wallpaperWin.mYOffset = offset;
1953e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
1954b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
195500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            wallpaperWin.mWallpaperY = wpy;
1956b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            wallpaperWin.mWallpaperYStep = wpys;
19573b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier            rawChanged = true;
1958b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        }
1959b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1960b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
19618a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes                    WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
1962ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            try {
1963bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
1964bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                        + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
19652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        + " y=" + wallpaperWin.mWallpaperY);
196600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (sync) {
1967e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    mWaitingOnWallpaper = wallpaperWin;
1968b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                }
196900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                wallpaperWin.mClient.dispatchWallpaperOffsets(
1970b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                        wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
19713b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                        wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
1972b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                if (sync) {
1973b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                    if (mWaitingOnWallpaper != null) {
1974b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                        long start = SystemClock.uptimeMillis();
1975cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
1976ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                                < start) {
19777577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                            try {
19783b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                                if (DEBUG_WALLPAPER) Slog.v(TAG,
197900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                        "Waiting for offset complete...");
1980e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                mWindowMap.wait(WALLPAPER_TIMEOUT);
1981e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                            } catch (InterruptedException e) {
198256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                            }
198356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                            if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
198456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                            if ((start+WALLPAPER_TIMEOUT)
198556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                                    < SystemClock.uptimeMillis()) {
198656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                                Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
198756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                                        + wallpaperWin);
198856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                                mLastWallpaperTimeoutTime = start;
198956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                            }
199056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                        }
199156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                        mWaitingOnWallpaper = null;
199256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                    }
199356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                }
199456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            } catch (RemoteException e) {
199556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            }
199656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        }
199756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih
199856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        return changed;
19997577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
2000cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2001ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    void wallpaperOffsetsComplete(IBinder window) {
2002590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        synchronized (mWindowMap) {
20032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (mWaitingOnWallpaper != null &&
200400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    mWaitingOnWallpaper.mClient.asBinder() == window) {
200556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                mWaitingOnWallpaper = null;
200656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                mWindowMap.notifyAll();
200756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            }
200856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        }
200956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
2010cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2011ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
20127577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes        final DisplayContent displayContent = changingTarget.mDisplayContent;
201356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
201456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        final int dw = displayInfo.logicalWidth;
201556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        final int dh = displayInfo.logicalHeight;
201656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih
201756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        WindowState target = mWallpaperTarget;
201856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        if (target != null) {
201956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            if (target.mWallpaperX >= 0) {
202056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                mLastWallpaperX = target.mWallpaperX;
202156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            } else if (changingTarget.mWallpaperX >= 0) {
202256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                mLastWallpaperX = changingTarget.mWallpaperX;
202356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            }
202456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            if (target.mWallpaperY >= 0) {
202556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                mLastWallpaperY = target.mWallpaperY;
202656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            } else if (changingTarget.mWallpaperY >= 0) {
202756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                mLastWallpaperY = changingTarget.mWallpaperY;
2028cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2029ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
20307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
203156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        int curTokenIndex = mWallpaperTokens.size();
203256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        while (curTokenIndex > 0) {
203356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            curTokenIndex--;
203456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            WindowToken token = mWallpaperTokens.get(curTokenIndex);
203556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            int curWallpaperIndex = token.windows.size();
203656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih            while (curWallpaperIndex > 0) {
203756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                curWallpaperIndex--;
203856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih                WindowState wallpaper = token.windows.get(curWallpaperIndex);
2039cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
2040ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
20417577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                    winAnimator.computeShownFrameLocked();
2042e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    // No need to lay out the windows - we can just set the wallpaper position
2043e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    // directly.
20447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                    winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
2045e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    // We only want to be synchronous with one wallpaper.
20467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                    sync = false;
20477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                }
2048ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers            }
2049e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
20507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
20517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
2052e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    /**
20537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes     * Check wallpaper for visiblity change and notify window if so.
20547577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes     * @param wallpaper The wallpaper to test and notify.
20557577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes     * @param visible Current visibility.
20567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes     */
2057b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
2058b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        if (wallpaper.mWallpaperVisible != visible) {
20597577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            wallpaper.mWallpaperVisible = visible;
20607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            try {
2061b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
2062b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                        "Updating vis of wallpaper " + wallpaper
2063bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes                        + ": " + visible + " from:\n" + Debug.getCallers(4, "  "));
20642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                wallpaper.mClient.dispatchAppVisibility(visible);
206500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            } catch (RemoteException e) {
2066e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            }
2067ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom        }
206896a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
206996a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes
2070e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    void updateWallpaperVisibilityLocked() {
2071bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes        final boolean visible = isWallpaperVisible(mWallpaperTarget);
2072cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        final DisplayContent displayContent = mWallpaperTarget.mDisplayContent;
2073ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
2074814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes        final int dw = displayInfo.logicalWidth;
20753b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier        final int dh = displayInfo.logicalHeight;
207600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
2077e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        int curTokenIndex = mWallpaperTokens.size();
2078e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        while (curTokenIndex > 0) {
207900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            curTokenIndex--;
2080cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowToken token = mWallpaperTokens.get(curTokenIndex);
2081d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes            if (token.hidden == visible) {
2082bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                token.hidden = !visible;
2083bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                // Need to do a layout to ensure the wallpaper now has the
20842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                // correct size.
208500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                getDefaultDisplayContentLocked().layoutNeeded = true;
2086e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            }
2087e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
2088e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            int curWallpaperIndex = token.windows.size();
2089d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz            while (curWallpaperIndex > 0) {
2090cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                curWallpaperIndex--;
2091f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes                WindowState wallpaper = token.windows.get(curWallpaperIndex);
2092cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (visible) {
20932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
2094cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2095ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2096cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                dispatchWallpaperVisibility(wallpaper, visible);
20972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
2098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
2099ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    }
2100cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
21012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    public int addWindow(Session session, IWindow client, int seq,
2102cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
2103ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            Rect outContentInsets, InputChannel outInputChannel) {
2104cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        int[] appOp = new int[1];
21052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        int res = mPolicy.checkAddPermission(attrs, appOp);
2106cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        if (res != WindowManagerGlobal.ADD_OKAY) {
2107ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            return res;
2108cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
21092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2110cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean reportNewConfig = false;
2111ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        WindowState attachedWindow = null;
2112cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        WindowState win = null;
21132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        long origId;
2114cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        final int type = attrs.type;
2115ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2116cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        synchronized(mWindowMap) {
21172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (!mDisplayReady) {
2118cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                throw new IllegalStateException("Display has not been initialialized");
2119f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes            }
21201d99e4549309d05007d041d058b1878de88e9585Ian Rogers
21211d99e4549309d05007d041d058b1878de88e9585Ian Rogers            final DisplayContent displayContent = getDisplayContentLocked(displayId);
21221d99e4549309d05007d041d058b1878de88e9585Ian Rogers            if (displayContent == null) {
212396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes                Slog.w(TAG, "Attempted to add window to a display that does not exist: "
21241d99e4549309d05007d041d058b1878de88e9585Ian Rogers                        + displayId + ".  Aborting.");
212596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
21262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
2127cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (!displayContent.hasAccess(session.mUid)) {
2128cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                Slog.w(TAG, "Attempted to add window to a display for which the application "
2129ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                        + "does not have access: " + displayId + ".  Aborting.");
2130e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
21311d99e4549309d05007d041d058b1878de88e9585Ian Rogers            }
2132e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
21331d99e4549309d05007d041d058b1878de88e9585Ian Rogers            if (mWindowMap.containsKey(client.asBinder())) {
21341d99e4549309d05007d041d058b1878de88e9585Ian Rogers                Slog.w(TAG, "Window " + client + " is already added");
21351d99e4549309d05007d041d058b1878de88e9585Ian Rogers                return WindowManagerGlobal.ADD_DUPLICATE_ADD;
21361d99e4549309d05007d041d058b1878de88e9585Ian Rogers            }
21371d99e4549309d05007d041d058b1878de88e9585Ian Rogers
21381d99e4549309d05007d041d058b1878de88e9585Ian Rogers            if (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW) {
2139b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier                attachedWindow = windowForClientLocked(null, attrs.token, false);
21401d99e4549309d05007d041d058b1878de88e9585Ian Rogers                if (attachedWindow == null) {
21411d99e4549309d05007d041d058b1878de88e9585Ian Rogers                    Slog.w(TAG, "Attempted to add window with token that is not a window: "
21421d99e4549309d05007d041d058b1878de88e9585Ian Rogers                          + attrs.token + ".  Aborting.");
2143cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
2144cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
21457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
2146e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
2147e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
21481d99e4549309d05007d041d058b1878de88e9585Ian Rogers                            + attrs.token + ".  Aborting.");
2149e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
21501d99e4549309d05007d041d058b1878de88e9585Ian Rogers                }
21511d99e4549309d05007d041d058b1878de88e9585Ian Rogers            }
21521d99e4549309d05007d041d058b1878de88e9585Ian Rogers
21531d99e4549309d05007d041d058b1878de88e9585Ian Rogers            if (type == TYPE_PRIVATE_PRESENTATION && !displayContent.isPrivate()) {
21541d99e4549309d05007d041d058b1878de88e9585Ian Rogers                Slog.w(TAG, "Attempted to add private presentation window to a non-private display.  Aborting.");
21551d99e4549309d05007d041d058b1878de88e9585Ian Rogers                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
21561d99e4549309d05007d041d058b1878de88e9585Ian Rogers            }
21571d99e4549309d05007d041d058b1878de88e9585Ian Rogers
21581d99e4549309d05007d041d058b1878de88e9585Ian Rogers            boolean addToken = false;
2159d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz            WindowToken token = mTokenMap.get(attrs.token);
21601d99e4549309d05007d041d058b1878de88e9585Ian Rogers            if (token == null) {
21611d99e4549309d05007d041d058b1878de88e9585Ian Rogers                if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
21627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                    Slog.w(TAG, "Attempted to add application window with unknown token "
21637577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                          + attrs.token + ".  Aborting.");
216400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
2165f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes                }
2166f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes                if (type == TYPE_INPUT_METHOD) {
2167cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    Slog.w(TAG, "Attempted to add input method window with unknown token "
21682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                          + attrs.token + ".  Aborting.");
2169cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
2170ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                }
2171a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers                if (type == TYPE_WALLPAPER) {
21723b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier                    Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
217300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                          + attrs.token + ".  Aborting.");
2174e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
21752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
21762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (type == TYPE_DREAM) {
21772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    Slog.w(TAG, "Attempted to add Dream window with unknown token "
21782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                          + attrs.token + ".  Aborting.");
21792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
2180590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                }
2181590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                token = new WindowToken(this, attrs.token, -1, false);
21821d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier                addToken = true;
2183590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
2184e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                AppWindowToken atoken = token.appWindowToken;
2185590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                if (atoken == null) {
2186590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    Slog.w(TAG, "Attempted to add window with non-application token "
2187a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers                          + token + ".  Aborting.");
2188a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers                    return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
2189ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers                } else if (atoken.removed) {
2190b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                    Slog.w(TAG, "Attempted to add window with exiting application token "
2191b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                          + token + ".  Aborting.");
21922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    return WindowManagerGlobal.ADD_APP_EXITING;
21932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
21942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
21952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    // No need for this guy!
21962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    if (localLOGV) Slog.v(
21972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            TAG, "**** NO NEED TO START: " + attrs.getTitle());
21982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
21992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
22002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            } else if (type == TYPE_INPUT_METHOD) {
22012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (token.windowType != TYPE_INPUT_METHOD) {
22022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    Slog.w(TAG, "Attempted to add input method window with bad token "
22032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            + attrs.token + ".  Aborting.");
2204b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
2205b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                }
22067577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            } else if (type == TYPE_WALLPAPER) {
22072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (token.windowType != TYPE_WALLPAPER) {
2208cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    Slog.w(TAG, "Attempted to add wallpaper window with bad token "
2209ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            + attrs.token + ".  Aborting.");
22107577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
22112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
2212cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            } else if (type == TYPE_DREAM) {
2213ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (token.windowType != TYPE_DREAM) {
22147577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                    Slog.w(TAG, "Attempted to add Dream window with bad token "
22152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                            + attrs.token + ".  Aborting.");
2216cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                      return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
2217ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                }
22187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            }
22192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2220cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            win = new WindowState(this, session, client, token,
2221ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
22227577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            if (win.mDeathRecipient == null) {
22232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                // Client has apparently died, so there is no reason to
2224cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // continue.
2225ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                Slog.w(TAG, "Adding window client " + client.asBinder()
22267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                        + " that is dead, aborting.");
22272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                return WindowManagerGlobal.ADD_APP_EXITING;
2228cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2229ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            mPolicy.adjustWindowParamsLw(win.mAttrs);
22312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
2232cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2233ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            res = mPolicy.prepareAddWindowLw(win, attrs);
22347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            if (res != WindowManagerGlobal.ADD_OKAY) {
22352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                return res;
2236cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2237ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2238590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            if (outInputChannel != null && (attrs.inputFeatures
2239590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
22402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                String name = win.makeInputChannelName();
22412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
2242cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.setInputChannel(inputChannels[0]);
2243ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                inputChannels[1].transferTo(outInputChannel);
2244590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
22452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                mInputManager.registerInputChannel(win.mInputChannel, win.mInputWindowHandle);
2246cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2247ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2248590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            // From now on, no exceptions or errors allowed!
22492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            res = WindowManagerGlobal.ADD_OKAY;
2251ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2252590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            origId = Binder.clearCallingIdentity();
2253590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
22542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (addToken) {
2255cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                mTokenMap.put(attrs.token, token);
2256ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
2257590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            win.attach();
2258590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            mWindowMap.put(client.asBinder(), win);
22592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (win.mAppOp != AppOpsManager.OP_NONE) {
2260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (mAppOps.startOpNoThrow(win.mAppOp, win.getOwningUid(), win.getOwningPackage())
2261ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                        != AppOpsManager.MODE_ALLOWED) {
2262590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    win.setAppOpVisibilityLw(false);
22632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
2264cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2265ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2266590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            if (type == TYPE_APPLICATION_STARTING && token.appWindowToken != null) {
22672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                token.appWindowToken.startingWindow = win;
2268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
2269ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                        + " startingWindow=" + win);
2270590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                Message m = mH.obtainMessage(H.REMOVE_STARTING_TIMEOUT, token.appWindowToken);
2271590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                mH.sendMessageDelayed(m, STARTING_WINDOW_TIMEOUT_DURATION);
22722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
2273cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2274ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            boolean imMayMove = true;
2275bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
2276bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (type == TYPE_INPUT_METHOD) {
22772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                win.mGivenInsetsPending = true;
2278e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                mInputMethodWindow = win;
2279cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                addInputMethodWindowToListLocked(win);
2280ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                imMayMove = false;
2281bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            } else if (type == TYPE_INPUT_METHOD_DIALOG) {
2282bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                mInputMethodDialogs.add(win);
22832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                addWindowToListInOrderLocked(win, true);
2284cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
2285ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                imMayMove = false;
2286bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            } else {
2287bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                addWindowToListInOrderLocked(win, true);
22882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (type == TYPE_WALLPAPER) {
2289cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    mLastWallpaperTimeoutTime = 0;
2290ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2291bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2292bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
22932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                } else if (mWallpaperTarget != null
2294e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                        && mWallpaperTarget.mLayer >= win.mBaseLayer) {
2295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // If there is currently a wallpaper being shown, and
2296ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                    // the base layer of the new window is below the current
2297bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    // layer of the target window, then adjust the wallpaper.
2298bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    // This is to avoid a new window being placed between the
22992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    // wallpaper and its target.
2300e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
2301cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2302ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
2303bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
2304bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            win.mWinAnimator.mEnterAnimationPending = true;
23052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2306cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (displayContent.isDefaultDisplay) {
2307ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                mPolicy.getContentInsetHintLw(attrs, outContentInsets);
2308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            } else {
2309bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                outContentInsets.setEmpty();
23102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
2311cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2312ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            if (mInTouchMode) {
2313bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
2314bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            }
23152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (win.mAppToken == null || !win.mAppToken.clientHidden) {
2316e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
2317cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2318ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2319bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            mInputMonitor.setUpdateInputWindowsNeededLw();
2320bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
23212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            boolean focusChanged = false;
2322491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom            if (win.canReceiveKeys()) {
2323cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
2324ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                        false /*updateInputWindows*/);
2325bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (focusChanged) {
2326bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                    imMayMove = false;
23272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
2328cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2329ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2330bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (imMayMove) {
2331bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                moveInputMethodWindowsIfNeededLocked(false);
23322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
2333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2334ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            assignLayersLocked(displayContent.getWindowList());
2335bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            // Don't do layout here, the window must call
2336bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            // relayout to be displayed, so we'll do it there.
23372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2338491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom            if (focusChanged) {
2339cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                finishUpdateFocusedWindowAfterAssignLayersLocked(false /*updateInputWindows*/);
2340ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            }
2341bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            mInputMonitor.updateInputWindowsLw(false /*force*/);
2342bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
23432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (localLOGV) Slog.v(
2344491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                TAG, "New client " + client.asBinder()
2345cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                + ": window=" + win);
2346ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2347bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
2348bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                reportNewConfig = true;
23492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
2350cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
2351ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2352bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (reportNewConfig) {
2353bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            sendNewConfiguration();
23542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
2355cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2356ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        Binder.restoreCallingIdentity(origId);
2357bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
2358bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        return res;
23592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
2360e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
2361cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    public void removeWindow(Session session, IWindow client) {
2362ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        synchronized(mWindowMap) {
2363bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            WindowState win = windowForClientLocked(session, client, false);
2364bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (win == null) {
2365c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes                return;
2366c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            }
2367c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            removeWindowLocked(session, win);
2368bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        }
2369bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
2370bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
2371aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    public void removeWindowLocked(Session session, WindowState win) {
2372bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2373bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
23742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            removeStartingWindowTimeout(win.mAppToken);
237500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
2376e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
2377bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
2378bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                TAG, "Remove " + win + " client="
2379bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                + Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
2380bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                + ", surface=" + win.mWinAnimator.mSurfaceControl + " Callers="
2381bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                + Debug.getCallers(4));
23822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2383bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers        final long origId = Binder.clearCallingIdentity();
2384cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        win.disposeInputChannel();
2386fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
2387fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        if (DEBUG_APP_TRANSITIONS) Slog.v(
2388fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                TAG, "Remove " + win + ": mSurface=" + win.mWinAnimator.mSurfaceControl
2389fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + " mExiting=" + win.mExiting
2390fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + " isAnimating=" + win.mWinAnimator.isAnimating()
2391fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + " app-animation="
2392fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
2393fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + " inPendingTransaction="
2394fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
2395fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                + " mDisplayFrozen=" + mDisplayFrozen);
2396fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        // Visibility of the removed window. Will be used later to update orientation later on.
23971eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers        boolean wasVisible = false;
2398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // First, see if we need to run an animation.  If we do, we have
23991eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers        // to hold off on removing the window until the animation is done.
2400cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // If the display is frozen, just remove immediately, since the
2401cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // animation wouldn't be seen.
24020af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes        if (win.mHasSurface && okToDisplay()) {
2403e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            // If we are not currently running the exit animation, we
2404e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            // need to see about starting one.
24055174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes            wasVisible = win.isWinVisibleLw();
2406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (wasVisible) {
2407e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
24080177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers                int transit = WindowManagerPolicy.TRANSIT_EXIT;
2409c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes                if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
24100177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers                    transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
24110177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers                }
241200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                // Try starting an animation.
2413cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (win.mWinAnimator.applyAnimationLocked(transit, false)) {
24145174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes                    win.mExiting = true;
2415c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes                }
2416bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                //TODO (multidisplay): Magnification is supported only for the default display.
2417bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                if (mDisplayMagnifier != null
241800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
2419cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    mDisplayMagnifier.onWindowTransitionLocked(win, transit);
2420cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
24215174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes            }
24224dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes            if (win.mExiting || win.mWinAnimator.isAnimating()) {
24235174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes                // The exit animation is running... wait for it!
2424fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                //Slog.i(TAG, "*** Running exit animation...");
24254dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers                win.mExiting = true;
2426cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mRemoveOnExit = true;
24274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers                win.mDisplayContent.layoutNeeded = true;
2428ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
24295174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes                        false /*updateInputWindows*/);
24302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                performLayoutAndPlaceSurfacesLocked();
243100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                if (win.mAppToken != null) {
2432e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                    win.mAppToken.updateReportedVisibilityLocked();
24335174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes                }
24344dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes                //dump();
24355174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes                Binder.restoreCallingIdentity(origId);
24362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                return;
24375174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes            }
2438e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
24395174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
244000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        removeWindowInnerLocked(session, win);
24412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        // Removing a visible window will effect the computed orientation
24425174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes        // So just update orientation if needed.
24435174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes        if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
24445174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
2445e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
24465174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes        updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
244700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        Binder.restoreCallingIdentity(origId);
24482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
24495174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
24505174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    private void removeWindowInnerLocked(Session session, WindowState win) {
24515174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes        if (win.mRemoved) {
24522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            // Nothing to do.
24532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            return;
24542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
24552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
24565174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes        for (int i=win.mChildWindows.size()-1; i>=0; i--) {
2457cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowState cwin = win.mChildWindows.get(i);
2458ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            Slog.w(TAG, "Force-removing child win " + cwin + " from container "
2459719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers                    + win);
24602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            removeWindowInnerLocked(cwin.mSession, cwin);
246100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
2462e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
2463e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        win.mRemoved = true;
246400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
2465ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes        if (mInputMethodTarget == win) {
2466ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes            moveInputMethodWindowsIfNeededLocked(false);
246700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
2468ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes
2469cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        if (false) {
2470ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            RuntimeException e = new RuntimeException("here");
2471719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers            e.fillInStackTrace();
24722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            Slog.w(TAG, "Removing window " + win, e);
247300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
2474e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
247500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        mPolicy.removeWindowLw(win);
247600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        win.removeLocked();
2477ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes
2478ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
247900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        mWindowMap.remove(win.mClient.asBinder());
2480ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes        if (win.mAppOp != AppOpsManager.OP_NONE) {
2481f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes            mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
2482ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
2483cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
24842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final WindowList windows = win.getWindowList();
2485cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        windows.remove(win);
2486e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        mPendingRemove.remove(win);
248769f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes        mResizingWindows.remove(win);
2488cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        mWindowsChanged = true;
2489e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win);
2490cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2491e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (mInputMethodWindow == win) {
2492cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            mInputMethodWindow = null;
2493ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        } else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
2494b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            mInputMethodDialogs.remove(win);
249596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes        }
2496ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
249745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom        final WindowToken token = win.mToken;
249896a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes        final AppWindowToken atoken = win.mAppToken;
2499e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + win + " from " + token);
2500e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        token.windows.remove(win);
250145d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom        if (atoken != null) {
250296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes            atoken.allAppWindows.remove(win);
2503ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        }
250485a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom        if (localLOGV) Slog.v(
250545d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom                TAG, "**** Removing window " + win + ": count="
250645d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom                + token.windows.size());
250745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom        if (token.windows.size() == 0) {
250845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom            if (!token.explicit) {
2509b56812165dd3a2e6eb8b85c810943b3d7bd9bfc4Elliott Hughes                mTokenMap.remove(token.token);
2510b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            } else if (atoken != null) {
2511ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                atoken.firstWindowDrawn = false;
2512aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes            }
2513aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes        }
2514eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes
2515e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (atoken != null) {
2516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (atoken.startingWindow == win) {
2517ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
2518b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                removeStartingWindowTimeout(atoken);
2519e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                atoken.startingWindow = null;
2520e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
2521cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // If this is the last window and we had requested a starting
2522ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                // transition window, well there is no point now.
2523b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling last startingWindow");
2524e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                atoken.startingData = null;
2525e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            } else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
2526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // If this is the last window except for a starting transition
2527ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                // window, we need to get rid of the starting transition.
2528b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                scheduleRemoveStartingWindow(atoken);
2529246a0130c5583170f4d168532feb49367fce2b47Andreas Gampe            }
2530246a0130c5583170f4d168532feb49367fce2b47Andreas Gampe        }
2531246a0130c5583170f4d168532feb49367fce2b47Andreas Gampe
2532b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        if (win.mAttrs.type == TYPE_WALLPAPER) {
2533b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            mLastWallpaperTimeoutTime = 0;
2534b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            getDefaultDisplayContentLocked().pendingLayoutChanges |=
2535b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
2536b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
2537c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier            getDefaultDisplayContentLocked().pendingLayoutChanges |=
2538c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
2539196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi        }
2540196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi
2541196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi        if (!mInLayout) {
25422ced6a534157d5d963693346904389c19775d2daElliott Hughes            assignLayersLocked(windows);
25432ced6a534157d5d963693346904389c19775d2daElliott Hughes            win.mDisplayContent.layoutNeeded = true;
25442ced6a534157d5d963693346904389c19775d2daElliott Hughes            performLayoutAndPlaceSurfacesLocked();
2545c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier            if (win.mAppToken != null) {
2546b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                win.mAppToken.updateReportedVisibilityLocked();
2547b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            }
2548b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        }
2549b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2550eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        mInputMonitor.updateInputWindowsLw(true /*force*/);
2551b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
2552eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
2553b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    public void updateAppOpsState() {
2554b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        synchronized(mWindowMap) {
2555b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            final int numDisplays = mDisplayContents.size();
2556b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
25572e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom                final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
25582e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom                final int numWindows = windows.size();
2559cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
256000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    final WindowState win = windows.get(winNdx);
256100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    if (win.mAppOp != AppOpsManager.OP_NONE) {
256235aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban                        final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
256335aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban                                win.getOwningPackage());
256400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED);
2565aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes                    }
256600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                }
256700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
256800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
256900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
257035aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban
257100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    static void logSurface(WindowState w, String msg, RuntimeException where) {
257200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        String str = "  SURFACE " + msg + ": " + w;
257300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        if (where != null) {
257400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            Slog.i(TAG, str, where);
257500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        } else {
257600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            Slog.i(TAG, str);
257700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
257800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
25792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
25801d99e4549309d05007d041d058b1878de88e9585Ian Rogers    static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) {
258196a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes        String str = "  SURFACE " + s + ": " + msg + " / " + title;
25821d99e4549309d05007d041d058b1878de88e9585Ian Rogers        if (where != null) {
258396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes            Slog.i(TAG, str, where);
25842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        } else {
258550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers            Slog.i(TAG, str);
258600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
258700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
258800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
25892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    void setTransparentRegionWindow(Session session, IWindow client, Region region) {
25902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        long origId = Binder.clearCallingIdentity();
25912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        try {
2592b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers            synchronized (mWindowMap) {
259300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                WindowState w = windowForClientLocked(session, client, false);
25942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if ((w != null) && w.mHasSurface) {
25952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    w.mWinAnimator.setTransparentRegionHintLocked(region);
25962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
25972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
25982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        } finally {
25992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            Binder.restoreCallingIdentity(origId);
26002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
26012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
26022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    void setInsetsWindow(Session session, IWindow client,
26042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            int touchableInsets, Rect contentInsets,
26052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            Rect visibleInsets, Region touchableRegion) {
26062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        long origId = Binder.clearCallingIdentity();
26072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        try {
26082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            synchronized (mWindowMap) {
26092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                WindowState w = windowForClientLocked(session, client, false);
26102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                if (w != null) {
26112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    w.mGivenInsetsPending = false;
26122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    w.mGivenContentInsets.set(contentInsets);
26132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    w.mGivenVisibleInsets.set(visibleInsets);
2614590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    w.mGivenTouchableRegion.set(touchableRegion);
2615590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    w.mTouchableInsets = touchableInsets;
2616590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    if (w.mGlobalScale != 1) {
2617590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                        w.mGivenContentInsets.scale(w.mGlobalScale);
2618590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                        w.mGivenVisibleInsets.scale(w.mGlobalScale);
26192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        w.mGivenTouchableRegion.scale(w.mGlobalScale);
2620590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    }
2621590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    w.mDisplayContent.layoutNeeded = true;
2622590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    performLayoutAndPlaceSurfacesLocked();
26232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
2624590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            }
2625590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        } finally {
2626590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            Binder.restoreCallingIdentity(origId);
2627590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        }
26282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
262900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
263000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    public void getWindowDisplayFrame(Session session, IWindow client,
263100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            Rect outDisplayFrame) {
26322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        synchronized(mWindowMap) {
2633590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            WindowState win = windowForClientLocked(session, client, false);
26342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (win == null) {
2635590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                outDisplayFrame.setEmpty();
26362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                return;
26372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
26382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            outDisplayFrame.set(win.mDisplayFrame);
26392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
26402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
26412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
26432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            float xStep, float yStep) {
26442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        if (window.mWallpaperX != x || window.mWallpaperY != y)  {
26452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            window.mWallpaperX = x;
26462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            window.mWallpaperY = y;
26472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            window.mWallpaperXStep = xStep;
2648ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers            window.mWallpaperYStep = yStep;
2649590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            updateWallpaperOffsetLocked(window, true);
26502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
2651590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    }
26522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    void wallpaperCommandComplete(IBinder window, Bundle result) {
2654d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier        synchronized (mWindowMap) {
2655d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier            if (mWaitingOnWallpaper != null &&
2656d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier                    mWaitingOnWallpaper.mClient.asBinder() == window) {
2657d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier                mWaitingOnWallpaper = null;
2658d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier                mWindowMap.notifyAll();
2659d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier            }
2660d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier        }
2661d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier    }
2662d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier
2663d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier    public Bundle sendWindowWallpaperCommandLocked(WindowState window,
2664590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            String action, int x, int y, int z, Bundle extras, boolean sync) {
2665590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        if (window == mWallpaperTarget || window == mLowerWallpaperTarget
2666590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                || window == mUpperWallpaperTarget) {
2667590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            boolean doWait = sync;
266800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            int curTokenIndex = mWallpaperTokens.size();
2669590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            while (curTokenIndex > 0) {
2670590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                curTokenIndex--;
26713e8b2e1f14176c6beb61a31a27af30bc35998e80Mathieu Chartier                WindowToken token = mWallpaperTokens.get(curTokenIndex);
26721d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier                int curWallpaperIndex = token.windows.size();
26731d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier                while (curWallpaperIndex > 0) {
2674590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    curWallpaperIndex--;
267500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    WindowState wallpaper = token.windows.get(curWallpaperIndex);
267600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                    try {
267700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        wallpaper.mClient.dispatchWallpaperCommand(action,
26782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                x, y, z, extras, sync);
26792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        // We only want to be synchronous with one wallpaper.
26802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                        sync = false;
26812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    } catch (RemoteException e) {
26822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                    }
26832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                }
26842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
26852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            if (doWait) {
26872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                // XXX Need to wait for result.
26882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers            }
26892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        }
26902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        return null;
26922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
26932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    public void setUniverseTransformLocked(WindowState window, float alpha,
269500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            float offx, float offy, float dsdx, float dtdx, float dsdy, float dtdy) {
269600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        Transformation transform = window.mWinAnimator.mUniverseTransform;
269700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        transform.setAlpha(alpha);
26982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        Matrix matrix = transform.getMatrix();
26992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        matrix.getValues(mTmpFloats);
27002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        mTmpFloats[Matrix.MTRANS_X] = offx;
27012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        mTmpFloats[Matrix.MTRANS_Y] = offy;
27022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        mTmpFloats[Matrix.MSCALE_X] = dsdx;
27032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        mTmpFloats[Matrix.MSKEW_Y] = dtdx;
27042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        mTmpFloats[Matrix.MSKEW_X] = dsdy;
27052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        mTmpFloats[Matrix.MSCALE_Y] = dtdy;
27062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        matrix.setValues(mTmpFloats);
27072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo();
27082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        final RectF dispRect = new RectF(0, 0,
27092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                displayInfo.logicalWidth, displayInfo.logicalHeight);
27102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        matrix.mapRect(dispRect);
27112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        window.mGivenTouchableRegion.set(0, 0,
27122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                displayInfo.logicalWidth, displayInfo.logicalHeight);
27132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
27142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
271500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
271600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        window.mDisplayContent.layoutNeeded = true;
2717cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        performLayoutAndPlaceSurfacesLocked();
2718ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    }
271988c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes
2720e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
2721e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        synchronized (mWindowMap) {
2722e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            if (mDisplayMagnifier != null) {
2723e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                WindowState window = mWindowMap.get(token);
2724cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                //TODO (multidisplay): Magnification is supported only for the default display.
2725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
2726cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle, immediate);
2727cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2728cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2729cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
2730cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
2731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2732cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    public IWindowId getWindowId(IBinder token) {
2733cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        synchronized (mWindowMap) {
2734cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowState window = mWindowMap.get(token);
2735cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            return window != null ? window.mWindowId : null;
2736cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
2737cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
2738cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2739cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    public int relayoutWindow(Session session, IWindow client, int seq,
2740cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowManager.LayoutParams attrs, int requestedWidth,
2741cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            int requestedHeight, int viewVisibility, int flags,
2742cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
2743cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
2744cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean toBeDisplayed = false;
2745cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean inTouchMode;
2746cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean configChanged;
2747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean surfaceChanged = false;
2748cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        boolean animating;
2749cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2750cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        // if they don't have this permission, mask out the status bar bits
2751cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        int systemUiVisibility = 0;
2752cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        if (attrs != null) {
2753cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
2754cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
2755cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
2756cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        != PackageManager.PERMISSION_GRANTED) {
2757cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
2758cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2759cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2760cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
2761cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        long origId = Binder.clearCallingIdentity();
2762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2763cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        synchronized(mWindowMap) {
2764cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowState win = windowForClientLocked(session, client, false);
2765cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (win == null) {
2766cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                return 0;
2767cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2768cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            WindowStateAnimator winAnimator = win.mWinAnimator;
2769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (win.mRequestedWidth != requestedWidth
2770cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    || win.mRequestedHeight != requestedHeight) {
2771cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mLayoutNeeded = true;
2772cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mRequestedWidth = requestedWidth;
2773cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mRequestedHeight = requestedHeight;
2774cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2775cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (attrs != null && seq == win.mSeq) {
2776cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mSystemUiVisibility = systemUiVisibility;
2777cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2778cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (attrs != null) {
2780cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                mPolicy.adjustWindowParamsLw(attrs);
2781cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2782cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2783cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            winAnimator.mSurfaceDestroyDeferred =
2784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
2785cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2786cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            int attrChanges = 0;
2787cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            int flagChanges = 0;
2788cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (attrs != null) {
2789cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (win.mAttrs.type != attrs.type) {
2790cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    throw new IllegalArgumentException(
2791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            "Window type can not be changed after the window is added.");
2792cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2793cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                flagChanges = win.mAttrs.flags ^= attrs.flags;
2794cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                attrChanges = win.mAttrs.copyFrom(attrs);
2795cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if ((attrChanges & (WindowManager.LayoutParams.LAYOUT_CHANGED
2796cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        | WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED)) != 0) {
2797cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    win.mLayoutNeeded = true;
2798cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2799cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2800cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
2802cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    + " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
2803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2804cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            win.mEnforceSizeCompat =
2805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    (win.mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
2806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {
2808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                winAnimator.mAlpha = attrs.alpha;
2809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2810cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            final boolean scaledWindow =
2812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                ((win.mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0);
2813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (scaledWindow) {
2815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // requested{Width|Height} Surface's physical size
2816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                // attrs.{width|height} Size on screen
2817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mHScale = (attrs.width  != requestedWidth)  ?
2818cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        (attrs.width  / (float)requestedWidth) : 1.0f;
2819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mVScale = (attrs.height != requestedHeight) ?
2820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        (attrs.height / (float)requestedHeight) : 1.0f;
2821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            } else {
2822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mHScale = win.mVScale = 1;
2823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2824cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
2826cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            final boolean isDefaultDisplay = win.isDefaultDisplay();
2828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
2829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
2830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    || (!win.mRelayoutCalled));
2831cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2832cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
2833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
2834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
2835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            win.mRelayoutCalled = true;
2837cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            final int oldVisibility = win.mViewVisibility;
2838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            win.mViewVisibility = viewVisibility;
2839cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (DEBUG_SCREEN_ON) {
2840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                RuntimeException stack = new RuntimeException();
2841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                stack.fillInStackTrace();
2842cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                Slog.i(TAG, "Relayout " + win + ": oldVis=" + oldVisibility
2843cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        + " newVis=" + viewVisibility, stack);
2844cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
2845cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (viewVisibility == View.VISIBLE &&
2846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    (win.mAppToken == null || !win.mAppToken.clientHidden)) {
2847cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                toBeDisplayed = !win.isVisibleLw();
2848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (win.mExiting) {
2849cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    winAnimator.cancelExitAnimationForNextAnimationLocked();
2850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    win.mExiting = false;
2851cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (win.mDestroying) {
2853cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    win.mDestroying = false;
2854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    mDestroySurface.remove(win);
2855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (oldVisibility == View.GONE) {
2857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    winAnimator.mEnterAnimationPending = true;
2858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2859cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (toBeDisplayed) {
2860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (win.isDrawnLw() && okToDisplay()) {
2861cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        winAnimator.applyEnterAnimationLocked();
2862cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
2863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if ((win.mAttrs.flags
2864cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            & WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) != 0) {
2865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (DEBUG_VISIBILITY) Slog.v(TAG,
2866cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                                "Relayout window turning screen on: " + win);
2867cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        win.mTurnOnScreen = true;
2868cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
2869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (win.isConfigChanged()) {
2870cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
2871cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                                + " visible with new config: " + mCurConfiguration);
2872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        outConfig.setTo(mCurConfiguration);
2873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
2874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2875cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
2876cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // To change the format, we need to re-build the surface.
2877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    winAnimator.destroySurfaceLocked();
2878cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    toBeDisplayed = true;
2879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    surfaceChanged = true;
2880cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                try {
2882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (!win.mHasSurface) {
2883cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        surfaceChanged = true;
2884cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
2885cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
2886cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (surfaceControl != null) {
2887cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        outSurface.copyFrom(surfaceControl);
2888cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (SHOW_TRANSACTIONS) Slog.i(TAG,
2889cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                                "  OUT SURFACE " + outSurface + ": copied");
2890cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    } else {
2891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // For some reason there isn't a surface.  Clear the
2892cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // caller's object so they see the same state.
2893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        outSurface.release();
2894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
2895cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                } catch (Exception e) {
2896cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    mInputMonitor.updateInputWindowsLw(true /*force*/);
2897cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2898cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    Slog.w(TAG, "Exception thrown when creating surface for client "
2899cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                             + client + " (" + win.mAttrs.getTitle() + ")",
2900cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                             e);
2901cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    Binder.restoreCallingIdentity(origId);
2902cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    return 0;
2903cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2904cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (toBeDisplayed) {
2905cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    focusMayChange = isDefaultDisplay;
2906cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2907cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (win.mAttrs.type == TYPE_INPUT_METHOD
2908cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        && mInputMethodWindow == null) {
2909cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    mInputMethodWindow = win;
2910cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    imMayMove = true;
2911cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2912cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (win.mAttrs.type == TYPE_BASE_APPLICATION
2913cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        && win.mAppToken != null
2914cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        && win.mAppToken.startingWindow != null) {
2915cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // Special handling of starting window over the base
2916cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // window of the app: propagate lock screen flags to it,
2917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // to provide the correct semantics while starting.
2918cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    final int mask =
2919cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
2920cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
2921cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON;
2922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    WindowManager.LayoutParams sa = win.mAppToken.startingWindow.mAttrs;
2923cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    sa.flags = (sa.flags&~mask) | (win.mAttrs.flags&mask);
2924cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
2925cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            } else {
2926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                winAnimator.mEnterAnimationPending = false;
2927cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (winAnimator.mSurfaceControl != null) {
2928cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (DEBUG_VISIBILITY) Slog.i(TAG, "Relayout invis " + win
2929cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            + ": mExiting=" + win.mExiting);
2930cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // If we are not currently running the exit animation, we
2931cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    // need to see about starting one.
2932cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (!win.mExiting) {
2933cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        surfaceChanged = true;
2934cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // Try starting an animation; if there isn't one, we
2935cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        // can destroy the surface right away.
2936cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        int transit = WindowManagerPolicy.TRANSIT_EXIT;
2937cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
2938cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
2939cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        }
2940cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        if (win.isWinVisibleLw() &&
2941cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                                winAnimator.applyAnimationLocked(transit, false)) {
2942cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            focusMayChange = isDefaultDisplay;
2943cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            win.mExiting = true;
2944cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        } else if (win.mWinAnimator.isAnimating()) {
2945cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            // Currently in a hide animation... turn this into
2946cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            // an exit.
2947cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            win.mExiting = true;
2948cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                        } else if (win == mWallpaperTarget) {
2949cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            // If the wallpaper is currently behind this
2950cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            // window, we need to change both of them inside
2951cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            // of a transaction to avoid artifacts.
2952cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            win.mExiting = true;
2953ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                            win.mWinAnimator.mAnimating = true;
2954ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro                        } else {
29557577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                            if (mInputMethodWindow == win) {
295669f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes                                mInputMethodWindow = null;
29577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                            }
29585a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                            winAnimator.destroySurfaceLocked();
29595a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                        }
29604ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes                        //TODO (multidisplay): Magnification is supported only for the default
2961dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers                        if (mDisplayMagnifier != null
29625a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers                                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
296388c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes                            mDisplayMagnifier.onWindowTransitionLocked(win, transit);
29644ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes                        }
296588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes                    }
2966a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes                }
296740ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes
296840ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes                outSurface.release();
2969c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes                if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
2970c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes            }
2971c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes
2972590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            if (focusMayChange) {
2973590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                //System.out.println("Focus may change: " + win.mAttrs.getTitle());
2974590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                if (updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
2975590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                        false /*updateInputWindows*/)) {
2976590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                    imMayMove = false;
2977590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                }
2978590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                //System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
2979590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            }
2980590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2981590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            // updateFocusedWindowLocked() already assigned layers so we only need to
2982590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            // reassign them at this point if the IM window state gets shuffled
2983590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier            if (imMayMove && (moveInputMethodWindowsIfNeededLocked(false) || toBeDisplayed)) {
298488c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes                // Little hack here -- we -should- be able to rely on the
298588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes                // function to return true if the IME has moved and needs
298688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes                // its layer recomputed.  However, if the IME was hidden
29874ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes                // and isn't actually moved in the list, its layer may be
29884ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes                // out of data so we make sure to recompute it.
298973e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes                assignLayersLocked(win.getWindowList());
299073e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes            }
299173e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes
29929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes            if (wallpaperMayMove) {
29939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes                getDefaultDisplayContentLocked().pendingLayoutChanges |=
299435aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
299535aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban            }
29961bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes
29972ced6a534157d5d963693346904389c19775d2daElliott Hughes            win.mDisplayContent.layoutNeeded = true;
29982ced6a534157d5d963693346904389c19775d2daElliott Hughes            win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
29992ced6a534157d5d963693346904389c19775d2daElliott Hughes            configChanged = updateOrientationFromAppTokensLocked(false);
30002ced6a534157d5d963693346904389c19775d2daElliott Hughes            performLayoutAndPlaceSurfacesLocked();
300135aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban            if (toBeDisplayed && win.mIsWallpaper) {
30022ced6a534157d5d963693346904389c19775d2daElliott Hughes                DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
30032ced6a534157d5d963693346904389c19775d2daElliott Hughes                updateWallpaperOffsetLocked(win,
30042ced6a534157d5d963693346904389c19775d2daElliott Hughes                        displayInfo.logicalWidth, displayInfo.logicalHeight, false);
30052ced6a534157d5d963693346904389c19775d2daElliott Hughes            }
30062ced6a534157d5d963693346904389c19775d2daElliott Hughes            if (win.mAppToken != null) {
30072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                win.mAppToken.updateReportedVisibilityLocked();
30082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            }
30092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            outFrame.set(win.mCompatFrame);
30102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            outOverscanInsets.set(win.mOverscanInsets);
30112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            outContentInsets.set(win.mContentInsets);
3012ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            outVisibleInsets.set(win.mVisibleInsets);
3013ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro            if (localLOGV) Slog.v(
3014bddf97641c9371ec74c63bca52fff62fecd73750Brian Carlstrom                TAG, "Relayout given client " + client.asBinder()
30152ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                + ", requestedWidth=" + requestedWidth
301683a25328c595975097cf3948451088cbfc64fc09Elliott Hughes                + ", requestedHeight=" + requestedHeight
301783a25328c595975097cf3948451088cbfc64fc09Elliott Hughes                + ", viewVisibility=" + viewVisibility
30182ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                + "\nRelayout returning frame=" + outFrame
30192ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                + ", surface=" + outSurface);
3020e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers
30212ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            if (localLOGV || DEBUG_FOCUS) Slog.v(
30222ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
3023f1a5adc87760f938b01df26d906295063546b259Elliott Hughes
30242ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            inTouchMode = mInTouchMode;
30252ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            animating = mAnimator.mAnimating && win.mWinAnimator.isAnimating();
302600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            if (animating && !mRelayoutWhileAnimating.contains(win)) {
30272ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                mRelayoutWhileAnimating.add(win);
30282ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            }
302900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3030bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom            mInputMonitor.updateInputWindowsLw(true /*force*/);
3031bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom
3032bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom            if (DEBUG_LAYOUT) {
3033bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom                Slog.v(TAG, "Relayout complete " + win + ": outFrame=" + outFrame.toShortString());
3034bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom            }
3035bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom        }
3036bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom
303769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom        if (configChanged) {
303869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom            sendNewConfiguration();
303969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom        }
30402ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
30412ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        Binder.restoreCallingIdentity(origId);
3042f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
30432ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
3044e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
3045f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes                | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
30462ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
3047f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes    }
304869f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes
30492ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro    public void performDeferredDestroyWindow(Session session, IWindow client) {
30502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        long origId = Binder.clearCallingIdentity();
30512ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
30522ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        try {
30532ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            synchronized (mWindowMap) {
30541bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                WindowState win = windowForClientLocked(session, client, false);
30552ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                if (win == null) {
30562ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                    return;
30572ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                }
3058cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                win.mWinAnimator.destroyDeferredSurfaceLocked();
3059cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
3060cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        } finally {
3061e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            Binder.restoreCallingIdentity(origId);
3062cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
3063cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
30646a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes
30656a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    public boolean outOfMemoryWindow(Session session, IWindow client) {
30666a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes        long origId = Binder.clearCallingIdentity();
30672ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
30682ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        try {
3069cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            synchronized (mWindowMap) {
30707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                WindowState win = windowForClientLocked(session, client, false);
30712ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                if (win == null) {
30722ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                    return false;
3073cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
30747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
30752ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            }
30762ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        } finally {
3077cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            Binder.restoreCallingIdentity(origId);
3078e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
3079cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3080cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
30816a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    public void finishDrawingWindow(Session session, IWindow client) {
30826a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes        final long origId = Binder.clearCallingIdentity();
30836a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes        try {
30846a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes            synchronized (mWindowMap) {
30852ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                WindowState win = windowForClientLocked(session, client, false);
30862ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro                if (win != null && win.mWinAnimator.finishDrawingLocked()) {
3087cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
30883b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes                        getDefaultDisplayContentLocked().pendingLayoutChanges |=
30893b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
30903b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes                    }
30913b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes                    win.mDisplayContent.layoutNeeded = true;
309283a25328c595975097cf3948451088cbfc64fc09Elliott Hughes                    requestTraversalLocked();
3093cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
3094cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
3095e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        } finally {
3096cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            Binder.restoreCallingIdentity(origId);
3097cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
3098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3099e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
3100e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    @Override
3101cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    public void getWindowFrame(IBinder token, Rect outBounds) {
3102cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
3103cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                "getWindowInfo()")) {
31042ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
31052ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro        }
3106cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        synchronized (mWindowMap) {
31072ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro            WindowState windowState = mWindowMap.get(token);
310888c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes            if (windowState != null) {
3109e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                outBounds.set(windowState.mFrame);
3110e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier            } else {
3111e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                outBounds.setEmpty();
3112cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
3113cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
3114cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3115cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3116cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    @Override
3117ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro    public void setMagnificationSpec(MagnificationSpec spec) {
3118ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro        if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3119491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                "setMagnificationSpec()")) {
312069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes            throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3121e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        }
3122e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        synchronized (mWindowMap) {
31234ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes            if (mDisplayMagnifier != null) {
31247934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom                mDisplayMagnifier.setMagnificationSpecLocked(spec);
3125a09576416788b916095739e43a16917e7948f3a4Elliott Hughes            } else {
31268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes                throw new IllegalStateException("Magnification callbacks not set!");
3127bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes            }
312800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
3129c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        if (Binder.getCallingPid() != android.os.Process.myPid()) {
3130c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            spec.recycle();
3131c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        }
3132c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    }
3133c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
313488c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes    @Override
31354ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes    public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
313688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes        if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3137a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes                "getCompatibleMagnificationSpecForWindow()")) {
3138f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes            throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3139f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes        }
3140de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes        synchronized (mWindowMap) {
314179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes            WindowState windowState = mWindowMap.get(windowToken);
3142de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes            if (windowState == null) {
3143de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes                return null;
3144c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            }
3145c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            MagnificationSpec spec = null;
3146c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            if (mDisplayMagnifier != null) {
3147c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                spec = mDisplayMagnifier.getMagnificationSpecForWindowLocked(windowState);
3148c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            }
3149c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
3150c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                return null;
3151c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            }
3152c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
3153c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            spec.scale *= windowState.mGlobalScale;
3154c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            return spec;
3155c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        }
3156c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    }
3157c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
3158c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    @Override
3159c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
3160c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
3161c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                "setMagnificationCallbacks()")) {
3162c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
3163c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        }
316488c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes        synchronized (mWindowMap) {
316588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes            if (mDisplayMagnifier == null) {
316688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes                mDisplayMagnifier = new DisplayMagnifier(this, callbacks);
31674ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes            } else {
31684ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes                if (callbacks == null) {
3169ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                    if (mDisplayMagnifier != null) {
3170ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                        mDisplayMagnifier.destroyLocked();
3171ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                        mDisplayMagnifier = null;
3172ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                    }
3173ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                } else {
317450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers                    throw new IllegalStateException("Magnification callbacks already set!");
3175ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                }
3176b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers            }
3177ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes        }
3178ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    }
3179ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
3180c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    private boolean applyAnimationLocked(AppWindowToken atoken,
3181c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            WindowManager.LayoutParams lp, int transit, boolean enter) {
3182c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        // Only apply an animation if the display isn't frozen.  If it is
3183ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes        // frozen, there is no reason to animate and it can cause strange
3184ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes        // artifacts when we unfreeze the display if some different animation
3185ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes        // is running.
3186ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes        if (okToDisplay()) {
3187ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes            DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
318850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers            final int width = displayInfo.appWidth;
3189ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes            final int height = displayInfo.appHeight;
3190ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes            if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
3191ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes                    + atoken);
3192ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes            Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height);
3193c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            if (a != null) {
3194c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                if (DEBUG_ANIM) {
3195c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                    RuntimeException e = null;
3196c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                    if (!HIDE_STACK_CRAWLS) {
3197c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                        e = new RuntimeException();
3198c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                        e.fillInStackTrace();
3199c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                    }
3200c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                    Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e);
3201c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                }
3202c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                atoken.mAppAnimator.setAnimation(a, width, height);
3203c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            }
3204c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        } else {
3205c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            atoken.mAppAnimator.clearAnimation();
3206c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        }
3207c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
3208c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier        return atoken.mAppAnimator.animation != null;
3209c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    }
3210ea2e1bd713ca8295ba4fcd01e77a3ce532ea61e4Hiroshi Yamauchi
3211c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    // -------------------------------------------------------------
3212c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    // Application Window Tokens
321373e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes    // -------------------------------------------------------------
321450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers
32159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes    public void validateAppTokens(int stackId, List<TaskGroup> tasks) {
3216b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers        synchronized (mWindowMap) {
321773e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes            int t = tasks.size() - 1;
32189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes            if (t < 0) {
32199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes                Slog.w(TAG, "validateAppTokens: empty task list");
3220c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                return;
3221c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier            }
32229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
32239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes            TaskGroup task = tasks.get(0);
32249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes            int taskId = task.taskId;
3225055d46c479369ea825712834353660b45215c195Mathieu Chartier            Task targetTask = mTaskIdToTask.get(taskId);
32260cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier            DisplayContent displayContent = targetTask.getDisplayContent();
32271eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers            if (displayContent == null) {
32281eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers                Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId);
3229cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                return;
3230cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
3231cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
32327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            final ArrayList<Task> localTasks = mStackIdToStack.get(stackId).getTasks();
32337577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes            int taskNdx;
323479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes            for (taskNdx = localTasks.size() - 1; taskNdx >= 0 && t >= 0; --taskNdx, --t) {
323550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers                AppTokenList localTokens = localTasks.get(taskNdx).mAppTokens;
323679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                task = tasks.get(t);
323779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                List<IApplicationToken> tokens = task.tokens;
323850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers
323979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                DisplayContent lastDisplayContent = displayContent;
324079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                displayContent = mTaskIdToTask.get(taskId).getDisplayContent();
3241e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                if (displayContent != lastDisplayContent) {
3242eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                    Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!");
32437577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                    return;
32447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                }
32457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
32461eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers                int tokenNdx;
32477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                int v;
3248eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                for (tokenNdx = localTokens.size() - 1, v = task.tokens.size() - 1;
32497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                        tokenNdx >= 0 && v >= 0; ) {
3250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    final AppWindowToken atoken = localTokens.get(tokenNdx);
3251cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    if (atoken.removed) {
32524dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes                        --tokenNdx;
3253eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                        continue;
32541bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes                    }
32551eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers                    if (tokens.get(v) != atoken.token) {
32567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes                        break;
3257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    }
3258cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    --tokenNdx;
3259cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    v--;
3260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
3261cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3262cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                if (tokenNdx >= 0 || v >= 0) {
3263cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    break;
3264cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                }
3265cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            }
3266cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3267cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            if (taskNdx >= 0 || t >= 0) {
3268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks);
326900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + localTasks);
327000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4));
327100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            }
327200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
3273cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
327400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
327500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    public void validateStackOrder(Integer[] remoteStackIds) {
3276355383f61d28f2dc8072fbde2639c80627adf16dYong WU        // TODO:
3277355383f61d28f2dc8072fbde2639c80627adf16dYong WU    }
3278355383f61d28f2dc8072fbde2639c80627adf16dYong WU
3279355383f61d28f2dc8072fbde2639c80627adf16dYong WU    boolean checkCallingPermission(String permission, String func) {
328093de4273d72a2558a7b3423547b5074cd76c5796Calin Juravle        // Quick check: if the calling permission is me, it's all okay.
328193de4273d72a2558a7b3423547b5074cd76c5796Calin Juravle        if (Binder.getCallingPid() == Process.myPid()) {
3282355383f61d28f2dc8072fbde2639c80627adf16dYong WU            return true;
3283355383f61d28f2dc8072fbde2639c80627adf16dYong WU        }
3284355383f61d28f2dc8072fbde2639c80627adf16dYong WU
328500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        if (mContext.checkCallingPermission(permission)
3286cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                == PackageManager.PERMISSION_GRANTED) {
328784b2f14d57eaf55988c0e0ff80551fde27daffc1Elliott Hughes            return true;
3288cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        }
3289e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        String msg = "Permission Denial: " + func + " from pid="
32901eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers                + Binder.getCallingPid()
329135d5c3baf701ca3d1e2d5b0b3653a5ca16f21f7eColin Cross                + ", uid=" + Binder.getCallingUid()
3292cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                + " requires " + permission;
3293cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        Slog.w(TAG, msg);
3294cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return false;
3295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
329600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
329700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    boolean okToDisplay() {
329879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        return !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully();
329950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    }
330079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3301e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    AppWindowToken findAppWindowToken(IBinder token) {
3302eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        WindowToken wtoken = mTokenMap.get(token);
330300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        if (wtoken == null) {
330400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            return null;
330579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        }
330600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        return wtoken.appWindowToken;
330700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
330800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3309eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    @Override
331000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    public void addWindowToken(IBinder token, int type) {
331179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3312cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                "addWindowToken()")) {
3313eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3314055d46c479369ea825712834353660b45215c195Mathieu Chartier        }
3315cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
33167935372ab784477db452d11112cd60d26be87093Elliott Hughes        synchronized(mWindowMap) {
3317355383f61d28f2dc8072fbde2639c80627adf16dYong WU            WindowToken wtoken = mTokenMap.get(token);
3318355383f61d28f2dc8072fbde2639c80627adf16dYong WU            if (wtoken != null) {
3319355383f61d28f2dc8072fbde2639c80627adf16dYong WU                Slog.w(TAG, "Attempted to add existing input method token: " + token);
3320355383f61d28f2dc8072fbde2639c80627adf16dYong WU                return;
3321355383f61d28f2dc8072fbde2639c80627adf16dYong WU            }
3322355383f61d28f2dc8072fbde2639c80627adf16dYong WU            wtoken = new WindowToken(this, token, type, true);
3323355383f61d28f2dc8072fbde2639c80627adf16dYong WU            mTokenMap.put(token, wtoken);
3324355383f61d28f2dc8072fbde2639c80627adf16dYong WU            if (type == TYPE_WALLPAPER) {
3325e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                mWallpaperTokens.add(wtoken);
33264dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes            }
332785affca81271f573c75c32316aa6faa8e52448b1Elliott Hughes        }
332879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    }
332979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
333079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    @Override
333179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    public void removeWindowToken(IBinder token) {
333279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
333379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                "removeWindowToken()")) {
333479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3335eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        }
3336eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier
3337eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        final long origId = Binder.clearCallingIdentity();
333879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        synchronized(mWindowMap) {
3339ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes            DisplayContent displayContent = null;
3340ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes            WindowToken wtoken = mTokenMap.remove(token);
334134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes            if (wtoken != null) {
33424dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes                boolean delayed = false;
3343e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                if (!wtoken.hidden) {
334479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                    final int N = wtoken.windows.size();
334579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                    boolean changed = false;
33461f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier
33471f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier                    for (int i=0; i<N; i++) {
33481f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier                        WindowState win = wtoken.windows.get(i);
3349eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                        displayContent = win.mDisplayContent;
335079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
33517935372ab784477db452d11112cd60d26be87093Elliott Hughes                        if (win.mWinAnimator.isAnimating()) {
33521eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers                            delayed = true;
33537935372ab784477db452d11112cd60d26be87093Elliott Hughes                        }
33541eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers
335575fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom                        if (win.isVisibleNow()) {
335679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                            win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
335779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                                    false);
335879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                            //TODO (multidisplay): Magnification is supported only for the default
335979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                            if (mDisplayMagnifier != null && win.isDefaultDisplay()) {
336079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                                mDisplayMagnifier.onWindowTransitionLocked(win,
336179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                                        WindowManagerPolicy.TRANSIT_EXIT);
33627935372ab784477db452d11112cd60d26be87093Elliott Hughes                            }
33637935372ab784477db452d11112cd60d26be87093Elliott Hughes                            changed = true;
3364cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                            displayContent.layoutNeeded = true;
33657935372ab784477db452d11112cd60d26be87093Elliott Hughes                        }
336675fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom                    }
336779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                    wtoken.hidden = true;
33697935372ab784477db452d11112cd60d26be87093Elliott Hughes
33707935372ab784477db452d11112cd60d26be87093Elliott Hughes                    if (changed) {
337179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                        performLayoutAndPlaceSurfacesLocked();
337279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                        updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
3373e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                false /*updateInputWindows*/);
337479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                    }
3375e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier
33766c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers                    if (delayed) {
337779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                        displayContent.mExitingTokens.add(wtoken);
3378c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier                    } else if (wtoken.windowType == TYPE_WALLPAPER) {
3379c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier                        mWallpaperTokens.remove(wtoken);
3380c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier                    }
338179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes                }
338279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3383b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers                mInputMonitor.updateInputWindowsLw(true /*force*/);
3384cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes            } else {
3385161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom                Slog.w(TAG, "Attempted to remove non-existing token: " + token);
3386161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom            }
338750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers        }
3388161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom        Binder.restoreCallingIdentity(origId);
338950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    }
3390161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
3391161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom    private Task createTask(int taskId, int stackId, int userId, AppWindowToken atoken) {
339262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        final TaskStack stack = mStackIdToStack.get(stackId);
3393e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        if (stack == null) {
339462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers            throw new IllegalArgumentException("addAppToken: invalid stackId=" + stackId);
339562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        }
3396161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom        EventLog.writeEvent(EventLogTags.WM_TASK_CREATED, taskId, stackId);
3397161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom        Task task = new Task(atoken, stack, userId);
3398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        mTaskIdToTask.put(taskId, task);
3399cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        stack.addTask(task, true);
340083c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier        return task;
3401810b1d704f2db0d935bf5dddae3545f79cabd435Mathieu Chartier    }
3402810b1d704f2db0d935bf5dddae3545f79cabd435Mathieu Chartier
3403196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi    @Override
34046aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier    public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId,
340583c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier            int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId,
34066aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier            int configChanges) {
34076aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
34086aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier                "addAppToken()")) {
34096aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
34106aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier        }
34116aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier
34126aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier        // Get the dispatching timeout here while we are not holding any locks so that it
341383c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier        // can be cached by the AppWindowToken.  The timeout value is used later by the
341450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers        // input dispatcher in code that does hold locks.  If we did not cache the value
3415410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes        // here we would run the chance of introducing a deadlock between the window manager
3416b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers        // (which holds locks while updating the input dispatcher state) and the activity manager
341712f7423a2bb4bfab76700d84eb6d4338d211983aMathieu Chartier        // (which holds locks while querying the application token).
3418410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes        long inputDispatchingTimeoutNanos;
3419410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes        try {
34208f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier            inputDispatchingTimeoutNanos = token.getKeyDispatchingTimeout() * 1000000L;
34218f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier        } catch (RemoteException ex) {
342283c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier            Slog.w(TAG, "Could not get dispatching timeout.", ex);
34238f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier            inputDispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
3424410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes        }
3425410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
3426410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes        synchronized(mWindowMap) {
3427c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            AppWindowToken atoken = findAppWindowToken(token.asBinder());
3428bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            if (atoken != null) {
3429c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes                Slog.w(TAG, "Attempted to add existing app token: " + token);
3430e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                return;
3431c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            }
3432c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            atoken = new AppWindowToken(this, token);
3433c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
3434c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            atoken.groupId = taskId;
3435c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes            atoken.appFullscreen = fullscreen;
3436df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers            atoken.showWhenLocked = showWhenLocked;
3437b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            atoken.requestedOrientation = requestedOrientation;
3438b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            atoken.layoutConfigChanges = (configChanges &
3439b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                    (ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_ORIENTATION)) != 0;
3440b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + atoken
3441b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                    + " to stack=" + stackId + " task=" + taskId + " at " + addPos);
3442b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
3443b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            Task task = mTaskIdToTask.get(taskId);
3444b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            if (task == null) {
3445b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                task = createTask(taskId, stackId, userId, atoken);
3446b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            } else {
3447b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes                task.addAppToken(addPos, atoken);
3448b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            }
3449b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
3450b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            mTokenMap.put(token.asBinder(), atoken);
3451b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
34522e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom            // Application tokens start out hidden.
345324782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao            atoken.hidden = true;
34542e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom            atoken.hiddenRequested = true;
3455b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
3456b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes            //dump();
3457        }
3458    }
3459
3460    @Override
3461    public void setAppGroupId(IBinder token, int groupId) {
3462        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3463                "setAppGroupId()")) {
3464            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3465        }
3466
3467        synchronized(mWindowMap) {
3468            final AppWindowToken atoken = findAppWindowToken(token);
3469            if (atoken == null) {
3470                Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token);
3471                return;
3472            }
3473            Task oldTask = mTaskIdToTask.get(atoken.groupId);
3474            oldTask.removeAppToken(atoken);
3475
3476            atoken.groupId = groupId;
3477            Task newTask = mTaskIdToTask.get(groupId);
3478            if (newTask == null) {
3479                newTask = createTask(groupId, oldTask.mStack.mStackId, oldTask.mUserId, atoken);
3480            }
3481            newTask.mAppTokens.add(atoken);
3482        }
3483    }
3484
3485    public int getOrientationFromWindowsLocked() {
3486        if (mDisplayFrozen || mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
3487            // If the display is frozen, some activities may be in the middle
3488            // of restarting, and thus have removed their old window.  If the
3489            // window has the flag to hide the lock screen, then the lock screen
3490            // can re-appear and inflict its own orientation on us.  Keep the
3491            // orientation stable until this all settles down.
3492            return mLastWindowForcedOrientation;
3493        }
3494
3495        // TODO(multidisplay): Change to the correct display.
3496        final WindowList windows = getDefaultWindowListLocked();
3497        int pos = windows.size() - 1;
3498        while (pos >= 0) {
3499            WindowState win = windows.get(pos);
3500            pos--;
3501            if (win.mAppToken != null) {
3502                // We hit an application window. so the orientation will be determined by the
3503                // app window. No point in continuing further.
3504                return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
3505            }
3506            if (!win.isVisibleLw() || !win.mPolicyVisibilityAfterAnim) {
3507                continue;
3508            }
3509            int req = win.mAttrs.screenOrientation;
3510            if((req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) ||
3511                    (req == ActivityInfo.SCREEN_ORIENTATION_BEHIND)){
3512                continue;
3513            }
3514
3515            if (DEBUG_ORIENTATION) Slog.v(TAG, win + " forcing orientation to " + req);
3516            return (mLastWindowForcedOrientation=req);
3517        }
3518        return (mLastWindowForcedOrientation=ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
3519    }
3520
3521    public int getOrientationFromAppTokensLocked() {
3522        int lastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3523        boolean findingBehind = false;
3524        boolean lastFullscreen = false;
3525        // TODO: Multi window.
3526        DisplayContent displayContent = getDefaultDisplayContentLocked();
3527        final ArrayList<Task> tasks = displayContent.getTasks();
3528        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
3529            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
3530            final int firstToken = tokens.size() - 1;
3531            for (int tokenNdx = firstToken; tokenNdx >= 0; --tokenNdx) {
3532                final AppWindowToken atoken = tokens.get(tokenNdx);
3533
3534                if (DEBUG_APP_ORIENTATION) Slog.v(TAG, "Checking app orientation: " + atoken);
3535
3536                // if we're about to tear down this window and not seek for
3537                // the behind activity, don't use it for orientation
3538                if (!findingBehind
3539                        && (!atoken.hidden && atoken.hiddenRequested)) {
3540                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3541                            + " -- going to hide");
3542                    continue;
3543                }
3544
3545                if (tokenNdx == firstToken) {
3546                    // If we have hit a new Task, and the bottom
3547                    // of the previous group didn't explicitly say to use
3548                    // the orientation behind it, and the last app was
3549                    // full screen, then we'll stick with the
3550                    // user's orientation.
3551                    if (lastOrientation != ActivityInfo.SCREEN_ORIENTATION_BEHIND
3552                            && lastFullscreen) {
3553                        if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3554                                + " -- end of group, return " + lastOrientation);
3555                        return lastOrientation;
3556                    }
3557                }
3558
3559                // We ignore any hidden applications on the top.
3560                if (atoken.hiddenRequested || atoken.willBeHidden) {
3561                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping " + atoken
3562                            + " -- hidden on top");
3563                    continue;
3564                }
3565
3566                if (tokenNdx == 0) {
3567                    // Last token in this task.
3568                    lastOrientation = atoken.requestedOrientation;
3569                }
3570
3571                int or = atoken.requestedOrientation;
3572                // If this application is fullscreen, and didn't explicitly say
3573                // to use the orientation behind it, then just take whatever
3574                // orientation it has and ignores whatever is under it.
3575                lastFullscreen = atoken.appFullscreen;
3576                if (lastFullscreen
3577                        && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3578                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3579                            + " -- full screen, return " + or);
3580                    return or;
3581                }
3582                // If this application has requested an explicit orientation,
3583                // then use it.
3584                if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
3585                        && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
3586                    if (DEBUG_ORIENTATION) Slog.v(TAG, "Done at " + atoken
3587                            + " -- explicitly set, return " + or);
3588                    return or;
3589                }
3590                findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
3591            }
3592        }
3593        if (DEBUG_ORIENTATION) Slog.v(TAG, "No app is requesting an orientation");
3594        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3595    }
3596
3597    @Override
3598    public Configuration updateOrientationFromAppTokens(
3599            Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3600        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3601                "updateOrientationFromAppTokens()")) {
3602            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3603        }
3604
3605        Configuration config = null;
3606        long ident = Binder.clearCallingIdentity();
3607
3608        synchronized(mWindowMap) {
3609            config = updateOrientationFromAppTokensLocked(currentConfig,
3610                    freezeThisOneIfNeeded);
3611        }
3612
3613        Binder.restoreCallingIdentity(ident);
3614        return config;
3615    }
3616
3617    private Configuration updateOrientationFromAppTokensLocked(
3618            Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
3619        Configuration config = null;
3620
3621        if (updateOrientationFromAppTokensLocked(false)) {
3622            if (freezeThisOneIfNeeded != null) {
3623                AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
3624                if (atoken != null) {
3625                    startAppFreezingScreenLocked(atoken, ActivityInfo.CONFIG_ORIENTATION);
3626                }
3627            }
3628            config = computeNewConfigurationLocked();
3629
3630        } else if (currentConfig != null) {
3631            // No obvious action we need to take, but if our current
3632            // state mismatches the activity manager's, update it,
3633            // disregarding font scale, which should remain set to
3634            // the value of the previous configuration.
3635            mTempConfiguration.setToDefaults();
3636            mTempConfiguration.fontScale = currentConfig.fontScale;
3637            if (computeScreenConfigurationLocked(mTempConfiguration)) {
3638                if (currentConfig.diff(mTempConfiguration) != 0) {
3639                    mWaitingForConfig = true;
3640                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
3641                    displayContent.layoutNeeded = true;
3642                    int anim[] = new int[2];
3643                    if (displayContent.isDimming()) {
3644                        anim[0] = anim[1] = 0;
3645                    } else {
3646                        mPolicy.selectRotationAnimationLw(anim);
3647                    }
3648                    startFreezingDisplayLocked(false, anim[0], anim[1]);
3649                    config = new Configuration(mTempConfiguration);
3650                }
3651            }
3652        }
3653
3654        return config;
3655    }
3656
3657    /*
3658     * Determine the new desired orientation of the display, returning
3659     * a non-null new Configuration if it has changed from the current
3660     * orientation.  IF TRUE IS RETURNED SOMEONE MUST CALL
3661     * setNewConfiguration() TO TELL THE WINDOW MANAGER IT CAN UNFREEZE THE
3662     * SCREEN.  This will typically be done for you if you call
3663     * sendNewConfiguration().
3664     *
3665     * The orientation is computed from non-application windows first. If none of
3666     * the non-application windows specify orientation, the orientation is computed from
3667     * application tokens.
3668     * @see android.view.IWindowManager#updateOrientationFromAppTokens(
3669     * android.os.IBinder)
3670     */
3671    boolean updateOrientationFromAppTokensLocked(boolean inTransaction) {
3672        long ident = Binder.clearCallingIdentity();
3673        try {
3674            int req = getOrientationFromWindowsLocked();
3675            if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
3676                req = getOrientationFromAppTokensLocked();
3677            }
3678
3679            if (req != mForcedAppOrientation) {
3680                mForcedAppOrientation = req;
3681                //send a message to Policy indicating orientation change to take
3682                //action like disabling/enabling sensors etc.,
3683                mPolicy.setCurrentOrientationLw(req);
3684                if (updateRotationUncheckedLocked(inTransaction)) {
3685                    // changed
3686                    return true;
3687                }
3688            }
3689
3690            return false;
3691        } finally {
3692            Binder.restoreCallingIdentity(ident);
3693        }
3694    }
3695
3696    @Override
3697    public void setNewConfiguration(Configuration config) {
3698        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3699                "setNewConfiguration()")) {
3700            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3701        }
3702
3703        synchronized(mWindowMap) {
3704            mCurConfiguration = new Configuration(config);
3705            if (mWaitingForConfig) {
3706                mWaitingForConfig = false;
3707                mLastFinishedFreezeSource = "new-config";
3708            }
3709            performLayoutAndPlaceSurfacesLocked();
3710        }
3711    }
3712
3713    @Override
3714    public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
3715        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3716                "setAppOrientation()")) {
3717            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3718        }
3719
3720        synchronized(mWindowMap) {
3721            AppWindowToken atoken = findAppWindowToken(token.asBinder());
3722            if (atoken == null) {
3723                Slog.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
3724                return;
3725            }
3726
3727            atoken.requestedOrientation = requestedOrientation;
3728        }
3729    }
3730
3731    @Override
3732    public int getAppOrientation(IApplicationToken token) {
3733        synchronized(mWindowMap) {
3734            AppWindowToken wtoken = findAppWindowToken(token.asBinder());
3735            if (wtoken == null) {
3736                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3737            }
3738
3739            return wtoken.requestedOrientation;
3740        }
3741    }
3742
3743    /** Call while in a Surface transaction. */
3744    void setFocusedStackLayer() {
3745        mFocusedStackLayer = 0;
3746        if (mFocusedApp != null) {
3747            final WindowList windows = mFocusedApp.allAppWindows;
3748            for (int i = windows.size() - 1; i >= 0; --i) {
3749                final WindowState win = windows.get(i);
3750                final int animLayer = win.mWinAnimator.mAnimLayer;
3751                if (win.mAttachedWindow == null && win.isVisibleLw() &&
3752                        animLayer > mFocusedStackLayer) {
3753                    mFocusedStackLayer = animLayer + LAYER_OFFSET_FOCUSED_STACK;
3754                }
3755            }
3756        }
3757        if (DEBUG_LAYERS) Slog.v(TAG, "Setting FocusedStackFrame to layer=" +
3758                mFocusedStackLayer);
3759        mFocusedStackFrame.setLayer(mFocusedStackLayer);
3760    }
3761
3762    void setFocusedStackFrame() {
3763        final TaskStack stack;
3764        if (mFocusedApp != null) {
3765            Task task = mTaskIdToTask.get(mFocusedApp.groupId);
3766            stack = task.mStack;
3767            task.getDisplayContent().setTouchExcludeRegion(stack);
3768        } else {
3769            stack = null;
3770        }
3771        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setFocusedStackFrame");
3772        SurfaceControl.openTransaction();
3773        try {
3774            if (stack == null) {
3775                mFocusedStackFrame.setVisibility(false);
3776            } else {
3777                mFocusedStackFrame.setBounds(stack);
3778                final boolean multipleStacks = !stack.isFullscreen();
3779                mFocusedStackFrame.setVisibility(multipleStacks);
3780            }
3781        } finally {
3782            SurfaceControl.closeTransaction();
3783            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> CLOSE TRANSACTION setFocusedStackFrame");
3784        }
3785    }
3786
3787    @Override
3788    public void setFocusedApp(IBinder token, boolean moveFocusNow) {
3789        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3790                "setFocusedApp()")) {
3791            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3792        }
3793
3794        synchronized(mWindowMap) {
3795            boolean changed = false;
3796            if (token == null) {
3797                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
3798                changed = mFocusedApp != null;
3799                mFocusedApp = null;
3800                if (changed) {
3801                    mInputMonitor.setFocusedAppLw(null);
3802                }
3803            } else {
3804                AppWindowToken newFocus = findAppWindowToken(token);
3805                if (newFocus == null) {
3806                    Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
3807                    return;
3808                }
3809                changed = mFocusedApp != newFocus;
3810                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
3811                        + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
3812                mFocusedApp = newFocus;
3813                if (changed) {
3814                    mInputMonitor.setFocusedAppLw(newFocus);
3815                }
3816            }
3817
3818            if (moveFocusNow && changed) {
3819                final long origId = Binder.clearCallingIdentity();
3820                updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
3821                Binder.restoreCallingIdentity(origId);
3822            }
3823        }
3824    }
3825
3826    @Override
3827    public void prepareAppTransition(int transit, boolean alwaysKeepCurrent) {
3828        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3829                "prepareAppTransition()")) {
3830            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3831        }
3832
3833        synchronized(mWindowMap) {
3834            if (DEBUG_APP_TRANSITIONS) Slog.v(
3835                    TAG, "Prepare app transition: transit=" + transit
3836                    + " " + mAppTransition
3837                    + " alwaysKeepCurrent=" + alwaysKeepCurrent
3838                    + " Callers=" + Debug.getCallers(3));
3839            if (okToDisplay()) {
3840                if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
3841                    mAppTransition.setAppTransition(transit);
3842                } else if (!alwaysKeepCurrent) {
3843                    if (transit == AppTransition.TRANSIT_TASK_OPEN
3844                            && mAppTransition.isTransitionEqual(
3845                                    AppTransition.TRANSIT_TASK_CLOSE)) {
3846                        // Opening a new task always supersedes a close for the anim.
3847                        mAppTransition.setAppTransition(transit);
3848                    } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3849                            && mAppTransition.isTransitionEqual(
3850                                AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
3851                        // Opening a new activity always supersedes a close for the anim.
3852                        mAppTransition.setAppTransition(transit);
3853                    }
3854                }
3855                mAppTransition.prepare();
3856                mStartingIconInTransition = false;
3857                mSkipAppTransitionAnimation = false;
3858                mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
3859                mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, 5000);
3860            }
3861        }
3862    }
3863
3864    @Override
3865    public int getPendingAppTransition() {
3866        return mAppTransition.getAppTransition();
3867    }
3868
3869    @Override
3870    public void overridePendingAppTransition(String packageName,
3871            int enterAnim, int exitAnim, IRemoteCallback startedCallback) {
3872        synchronized(mWindowMap) {
3873            mAppTransition.overridePendingAppTransition(packageName, enterAnim, exitAnim,
3874                    startedCallback);
3875        }
3876    }
3877
3878    @Override
3879    public void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
3880            int startHeight) {
3881        synchronized(mWindowMap) {
3882            mAppTransition.overridePendingAppTransitionScaleUp(startX, startY, startWidth,
3883                    startHeight);
3884        }
3885    }
3886
3887    @Override
3888    public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
3889            int startY, IRemoteCallback startedCallback, boolean scaleUp) {
3890        synchronized(mWindowMap) {
3891            mAppTransition.overridePendingAppTransitionThumb(srcThumb, startX, startY,
3892                    startedCallback, scaleUp);
3893        }
3894    }
3895
3896    @Override
3897    public void executeAppTransition() {
3898        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3899                "executeAppTransition()")) {
3900            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3901        }
3902
3903        synchronized(mWindowMap) {
3904            if (DEBUG_APP_TRANSITIONS) {
3905                RuntimeException e = new RuntimeException("here");
3906                e.fillInStackTrace();
3907                Slog.w(TAG, "Execute app transition: " + mAppTransition, e);
3908            }
3909            if (mAppTransition.isTransitionSet()) {
3910                mAppTransition.setReady();
3911                final long origId = Binder.clearCallingIdentity();
3912                performLayoutAndPlaceSurfacesLocked();
3913                Binder.restoreCallingIdentity(origId);
3914            }
3915        }
3916    }
3917
3918    @Override
3919    public void setAppStartingWindow(IBinder token, String pkg,
3920            int theme, CompatibilityInfo compatInfo,
3921            CharSequence nonLocalizedLabel, int labelRes, int icon, int logo,
3922            int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
3923        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
3924                "setAppStartingWindow()")) {
3925            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
3926        }
3927
3928        synchronized(mWindowMap) {
3929            if (DEBUG_STARTING_WINDOW) Slog.v(
3930                    TAG, "setAppStartingWindow: token=" + token + " pkg=" + pkg
3931                    + " transferFrom=" + transferFrom);
3932
3933            AppWindowToken wtoken = findAppWindowToken(token);
3934            if (wtoken == null) {
3935                Slog.w(TAG, "Attempted to set icon of non-existing app token: " + token);
3936                return;
3937            }
3938
3939            // If the display is frozen, we won't do anything until the
3940            // actual window is displayed so there is no reason to put in
3941            // the starting window.
3942            if (!okToDisplay()) {
3943                return;
3944            }
3945
3946            if (wtoken.startingData != null) {
3947                return;
3948            }
3949
3950            if (transferFrom != null) {
3951                AppWindowToken ttoken = findAppWindowToken(transferFrom);
3952                if (ttoken != null) {
3953                    WindowState startingWindow = ttoken.startingWindow;
3954                    if (startingWindow != null) {
3955                        if (mStartingIconInTransition) {
3956                            // In this case, the starting icon has already
3957                            // been displayed, so start letting windows get
3958                            // shown immediately without any more transitions.
3959                            mSkipAppTransitionAnimation = true;
3960                        }
3961                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
3962                                "Moving existing starting " + startingWindow + " from " + ttoken
3963                                + " to " + wtoken);
3964                        final long origId = Binder.clearCallingIdentity();
3965
3966                        // Transfer the starting window over to the new
3967                        // token.
3968                        wtoken.startingData = ttoken.startingData;
3969                        wtoken.startingView = ttoken.startingView;
3970                        wtoken.startingDisplayed = ttoken.startingDisplayed;
3971                        ttoken.startingDisplayed = false;
3972                        wtoken.startingWindow = startingWindow;
3973                        wtoken.reportedVisible = ttoken.reportedVisible;
3974                        ttoken.startingData = null;
3975                        ttoken.startingView = null;
3976                        ttoken.startingWindow = null;
3977                        ttoken.startingMoved = true;
3978                        startingWindow.mToken = wtoken;
3979                        startingWindow.mRootToken = wtoken;
3980                        startingWindow.mAppToken = wtoken;
3981                        startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
3982
3983                        if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
3984                            Slog.v(TAG, "Removing starting window: " + startingWindow);
3985                        }
3986                        removeStartingWindowTimeout(ttoken);
3987                        startingWindow.getWindowList().remove(startingWindow);
3988                        mWindowsChanged = true;
3989                        if (DEBUG_ADD_REMOVE) Slog.v(TAG,
3990                                "Removing starting " + startingWindow + " from " + ttoken);
3991                        ttoken.windows.remove(startingWindow);
3992                        ttoken.allAppWindows.remove(startingWindow);
3993                        addWindowToListInOrderLocked(startingWindow, true);
3994
3995                        // Propagate other interesting state between the
3996                        // tokens.  If the old token is displayed, we should
3997                        // immediately force the new one to be displayed.  If
3998                        // it is animating, we need to move that animation to
3999                        // the new one.
4000                        if (ttoken.allDrawn) {
4001                            wtoken.allDrawn = true;
4002                            wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
4003                        }
4004                        if (ttoken.firstWindowDrawn) {
4005                            wtoken.firstWindowDrawn = true;
4006                        }
4007                        if (!ttoken.hidden) {
4008                            wtoken.hidden = false;
4009                            wtoken.hiddenRequested = false;
4010                            wtoken.willBeHidden = false;
4011                        }
4012                        if (wtoken.clientHidden != ttoken.clientHidden) {
4013                            wtoken.clientHidden = ttoken.clientHidden;
4014                            wtoken.sendAppVisibilityToClients();
4015                        }
4016                        final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4017                        final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4018                        if (tAppAnimator.animation != null) {
4019                            wAppAnimator.animation = tAppAnimator.animation;
4020                            wAppAnimator.animating = tAppAnimator.animating;
4021                            wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
4022                            tAppAnimator.animation = null;
4023                            tAppAnimator.animLayerAdjustment = 0;
4024                            wAppAnimator.updateLayers();
4025                            tAppAnimator.updateLayers();
4026                        }
4027
4028                        updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4029                                true /*updateInputWindows*/);
4030                        getDefaultDisplayContentLocked().layoutNeeded = true;
4031                        performLayoutAndPlaceSurfacesLocked();
4032                        Binder.restoreCallingIdentity(origId);
4033                        return;
4034                    } else if (ttoken.startingData != null) {
4035                        // The previous app was getting ready to show a
4036                        // starting window, but hasn't yet done so.  Steal it!
4037                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
4038                                "Moving pending starting from " + ttoken
4039                                + " to " + wtoken);
4040                        wtoken.startingData = ttoken.startingData;
4041                        ttoken.startingData = null;
4042                        ttoken.startingMoved = true;
4043                        Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4044                        // Note: we really want to do sendMessageAtFrontOfQueue() because we
4045                        // want to process the message ASAP, before any other queued
4046                        // messages.
4047                        mH.sendMessageAtFrontOfQueue(m);
4048                        return;
4049                    }
4050                    final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
4051                    final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
4052                    if (tAppAnimator.thumbnail != null) {
4053                        // The old token is animating with a thumbnail, transfer
4054                        // that to the new token.
4055                        if (wAppAnimator.thumbnail != null) {
4056                            wAppAnimator.thumbnail.destroy();
4057                        }
4058                        wAppAnimator.thumbnail = tAppAnimator.thumbnail;
4059                        wAppAnimator.thumbnailX = tAppAnimator.thumbnailX;
4060                        wAppAnimator.thumbnailY = tAppAnimator.thumbnailY;
4061                        wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
4062                        wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
4063                        tAppAnimator.thumbnail = null;
4064                    }
4065                }
4066            }
4067
4068            // There is no existing starting window, and the caller doesn't
4069            // want us to create one, so that's it!
4070            if (!createIfNeeded) {
4071                return;
4072            }
4073
4074            // If this is a translucent window, then don't
4075            // show a starting window -- the current effect (a full-screen
4076            // opaque starting window that fades away to the real contents
4077            // when it is ready) does not work for this.
4078            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
4079                    + Integer.toHexString(theme));
4080            if (theme != 0) {
4081                AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
4082                        com.android.internal.R.styleable.Window, mCurrentUserId);
4083                if (ent == null) {
4084                    // Whoops!  App doesn't exist.  Um.  Okay.  We'll just
4085                    // pretend like we didn't see that.
4086                    return;
4087                }
4088                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
4089                        + ent.array.getBoolean(
4090                                com.android.internal.R.styleable.Window_windowIsTranslucent, false)
4091                        + " Floating="
4092                        + ent.array.getBoolean(
4093                                com.android.internal.R.styleable.Window_windowIsFloating, false)
4094                        + " ShowWallpaper="
4095                        + ent.array.getBoolean(
4096                                com.android.internal.R.styleable.Window_windowShowWallpaper, false));
4097                if (ent.array.getBoolean(
4098                        com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
4099                    return;
4100                }
4101                if (ent.array.getBoolean(
4102                        com.android.internal.R.styleable.Window_windowIsFloating, false)) {
4103                    return;
4104                }
4105                if (ent.array.getBoolean(
4106                        com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
4107                    if (mWallpaperTarget == null) {
4108                        // If this theme is requesting a wallpaper, and the wallpaper
4109                        // is not curently visible, then this effectively serves as
4110                        // an opaque window and our starting window transition animation
4111                        // can still work.  We just need to make sure the starting window
4112                        // is also showing the wallpaper.
4113                        windowFlags |= FLAG_SHOW_WALLPAPER;
4114                    } else {
4115                        return;
4116                    }
4117                }
4118            }
4119
4120            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
4121            mStartingIconInTransition = true;
4122            wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
4123                    labelRes, icon, logo, windowFlags);
4124            Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
4125            // Note: we really want to do sendMessageAtFrontOfQueue() because we
4126            // want to process the message ASAP, before any other queued
4127            // messages.
4128            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
4129            mH.sendMessageAtFrontOfQueue(m);
4130        }
4131    }
4132
4133    @Override
4134    public void setAppWillBeHidden(IBinder token) {
4135        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4136                "setAppWillBeHidden()")) {
4137            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4138        }
4139
4140        AppWindowToken wtoken;
4141
4142        synchronized(mWindowMap) {
4143            wtoken = findAppWindowToken(token);
4144            if (wtoken == null) {
4145                Slog.w(TAG, "Attempted to set will be hidden of non-existing app token: " + token);
4146                return;
4147            }
4148            wtoken.willBeHidden = true;
4149        }
4150    }
4151
4152    public void setAppFullscreen(IBinder token, boolean toOpaque) {
4153        AppWindowToken atoken = findAppWindowToken(token);
4154        if (atoken != null) {
4155            atoken.appFullscreen = toOpaque;
4156            requestTraversal();
4157        }
4158    }
4159
4160    boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
4161            boolean visible, int transit, boolean performLayout) {
4162        boolean delayed = false;
4163
4164        if (wtoken.clientHidden == visible) {
4165            wtoken.clientHidden = !visible;
4166            wtoken.sendAppVisibilityToClients();
4167        }
4168
4169        wtoken.willBeHidden = false;
4170        if (wtoken.hidden == visible) {
4171            boolean changed = false;
4172            if (DEBUG_APP_TRANSITIONS) Slog.v(
4173                TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
4174                + " performLayout=" + performLayout);
4175
4176            boolean runningAppAnimation = false;
4177
4178            if (transit != AppTransition.TRANSIT_UNSET) {
4179                if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
4180                    wtoken.mAppAnimator.animation = null;
4181                }
4182                if (applyAnimationLocked(wtoken, lp, transit, visible)) {
4183                    delayed = runningAppAnimation = true;
4184                }
4185                WindowState window = wtoken.findMainWindow();
4186                //TODO (multidisplay): Magnification is supported only for the default display.
4187                if (window != null && mDisplayMagnifier != null
4188                        && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
4189                    mDisplayMagnifier.onAppWindowTransitionLocked(window, transit);
4190                }
4191                changed = true;
4192            }
4193
4194            final int N = wtoken.allAppWindows.size();
4195            for (int i=0; i<N; i++) {
4196                WindowState win = wtoken.allAppWindows.get(i);
4197                if (win == wtoken.startingWindow) {
4198                    continue;
4199                }
4200
4201                //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
4202                //win.dump("  ");
4203                if (visible) {
4204                    if (!win.isVisibleNow()) {
4205                        if (!runningAppAnimation) {
4206                            win.mWinAnimator.applyAnimationLocked(
4207                                    WindowManagerPolicy.TRANSIT_ENTER, true);
4208                            //TODO (multidisplay): Magnification is supported only for the default
4209                            if (mDisplayMagnifier != null
4210                                    && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4211                                mDisplayMagnifier.onWindowTransitionLocked(win,
4212                                        WindowManagerPolicy.TRANSIT_ENTER);
4213                            }
4214                        }
4215                        changed = true;
4216                        win.mDisplayContent.layoutNeeded = true;
4217                    }
4218                } else if (win.isVisibleNow()) {
4219                    if (!runningAppAnimation) {
4220                        win.mWinAnimator.applyAnimationLocked(
4221                                WindowManagerPolicy.TRANSIT_EXIT, false);
4222                        //TODO (multidisplay): Magnification is supported only for the default
4223                        if (mDisplayMagnifier != null
4224                                && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
4225                            mDisplayMagnifier.onWindowTransitionLocked(win,
4226                                    WindowManagerPolicy.TRANSIT_EXIT);
4227                        }
4228                    }
4229                    changed = true;
4230                    win.mDisplayContent.layoutNeeded = true;
4231                }
4232            }
4233
4234            wtoken.hidden = wtoken.hiddenRequested = !visible;
4235            if (!visible) {
4236                unsetAppFreezingScreenLocked(wtoken, true, true);
4237            } else {
4238                // If we are being set visible, and the starting window is
4239                // not yet displayed, then make sure it doesn't get displayed.
4240                WindowState swin = wtoken.startingWindow;
4241                if (swin != null && !swin.isDrawnLw()) {
4242                    swin.mPolicyVisibility = false;
4243                    swin.mPolicyVisibilityAfterAnim = false;
4244                 }
4245            }
4246
4247            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "setTokenVisibilityLocked: " + wtoken
4248                      + ": hidden=" + wtoken.hidden + " hiddenRequested="
4249                      + wtoken.hiddenRequested);
4250
4251            if (changed) {
4252                mInputMonitor.setUpdateInputWindowsNeededLw();
4253                if (performLayout) {
4254                    updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4255                            false /*updateInputWindows*/);
4256                    performLayoutAndPlaceSurfacesLocked();
4257                }
4258                mInputMonitor.updateInputWindowsLw(false /*force*/);
4259            }
4260        }
4261
4262        if (wtoken.mAppAnimator.animation != null) {
4263            delayed = true;
4264        }
4265
4266        for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
4267            if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
4268                delayed = true;
4269            }
4270        }
4271
4272        return delayed;
4273    }
4274
4275    @Override
4276    public void setAppVisibility(IBinder token, boolean visible) {
4277        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4278                "setAppVisibility()")) {
4279            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4280        }
4281
4282        AppWindowToken wtoken;
4283
4284        synchronized(mWindowMap) {
4285            wtoken = findAppWindowToken(token);
4286            if (wtoken == null) {
4287                Slog.w(TAG, "Attempted to set visibility of non-existing app token: " + token);
4288                return;
4289            }
4290
4291            if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) {
4292                RuntimeException e = null;
4293                if (!HIDE_STACK_CRAWLS) {
4294                    e = new RuntimeException();
4295                    e.fillInStackTrace();
4296                }
4297                Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
4298                        + "): " + mAppTransition
4299                        + " hidden=" + wtoken.hidden
4300                        + " hiddenRequested=" + wtoken.hiddenRequested, e);
4301            }
4302
4303            // If we are preparing an app transition, then delay changing
4304            // the visibility of this token until we execute that transition.
4305            if (okToDisplay() && mAppTransition.isTransitionSet()) {
4306                wtoken.hiddenRequested = !visible;
4307
4308                if (!wtoken.startingDisplayed) {
4309                    if (DEBUG_APP_TRANSITIONS) Slog.v(
4310                            TAG, "Setting dummy animation on: " + wtoken);
4311                    wtoken.mAppAnimator.setDummyAnimation();
4312                }
4313                mOpeningApps.remove(wtoken);
4314                mClosingApps.remove(wtoken);
4315                wtoken.waitingToShow = wtoken.waitingToHide = false;
4316                wtoken.inPendingTransaction = true;
4317                if (visible) {
4318                    mOpeningApps.add(wtoken);
4319                    wtoken.startingMoved = false;
4320
4321                    // If the token is currently hidden (should be the
4322                    // common case), then we need to set up to wait for
4323                    // its windows to be ready.
4324                    if (wtoken.hidden) {
4325                        wtoken.allDrawn = false;
4326                        wtoken.deferClearAllDrawn = false;
4327                        wtoken.waitingToShow = true;
4328
4329                        if (wtoken.clientHidden) {
4330                            // In the case where we are making an app visible
4331                            // but holding off for a transition, we still need
4332                            // to tell the client to make its windows visible so
4333                            // they get drawn.  Otherwise, we will wait on
4334                            // performing the transition until all windows have
4335                            // been drawn, they never will be, and we are sad.
4336                            wtoken.clientHidden = false;
4337                            wtoken.sendAppVisibilityToClients();
4338                        }
4339                    }
4340                } else {
4341                    mClosingApps.add(wtoken);
4342
4343                    // If the token is currently visible (should be the
4344                    // common case), then set up to wait for it to be hidden.
4345                    if (!wtoken.hidden) {
4346                        wtoken.waitingToHide = true;
4347                    }
4348                }
4349                return;
4350            }
4351
4352            final long origId = Binder.clearCallingIdentity();
4353            setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
4354                    true);
4355            wtoken.updateReportedVisibilityLocked();
4356            Binder.restoreCallingIdentity(origId);
4357        }
4358    }
4359
4360    void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
4361            boolean unfreezeSurfaceNow, boolean force) {
4362        if (wtoken.mAppAnimator.freezingScreen) {
4363            if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + wtoken
4364                    + " force=" + force);
4365            final int N = wtoken.allAppWindows.size();
4366            boolean unfrozeWindows = false;
4367            for (int i=0; i<N; i++) {
4368                WindowState w = wtoken.allAppWindows.get(i);
4369                if (w.mAppFreezing) {
4370                    w.mAppFreezing = false;
4371                    if (w.mHasSurface && !w.mOrientationChanging) {
4372                        if (DEBUG_ORIENTATION) Slog.v(TAG, "set mOrientationChanging of " + w);
4373                        w.mOrientationChanging = true;
4374                        mInnerFields.mOrientationChangeComplete = false;
4375                    }
4376                    w.mLastFreezeDuration = 0;
4377                    unfrozeWindows = true;
4378                    w.mDisplayContent.layoutNeeded = true;
4379                }
4380            }
4381            if (force || unfrozeWindows) {
4382                if (DEBUG_ORIENTATION) Slog.v(TAG, "No longer freezing: " + wtoken);
4383                wtoken.mAppAnimator.freezingScreen = false;
4384                wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
4385                        - mDisplayFreezeTime);
4386                mAppsFreezingScreen--;
4387                mLastFinishedFreezeSource = wtoken;
4388            }
4389            if (unfreezeSurfaceNow) {
4390                if (unfrozeWindows) {
4391                    performLayoutAndPlaceSurfacesLocked();
4392                }
4393                stopFreezingDisplayLocked();
4394            }
4395        }
4396    }
4397
4398    public void startAppFreezingScreenLocked(AppWindowToken wtoken,
4399            int configChanges) {
4400        if (DEBUG_ORIENTATION) {
4401            RuntimeException e = null;
4402            if (!HIDE_STACK_CRAWLS) {
4403                e = new RuntimeException();
4404                e.fillInStackTrace();
4405            }
4406            Slog.i(TAG, "Set freezing of " + wtoken.appToken
4407                    + ": hidden=" + wtoken.hidden + " freezing="
4408                    + wtoken.mAppAnimator.freezingScreen, e);
4409        }
4410        if (!wtoken.hiddenRequested) {
4411            if (!wtoken.mAppAnimator.freezingScreen) {
4412                wtoken.mAppAnimator.freezingScreen = true;
4413                wtoken.mAppAnimator.lastFreezeDuration = 0;
4414                mAppsFreezingScreen++;
4415                if (mAppsFreezingScreen == 1) {
4416                    startFreezingDisplayLocked(false, 0, 0);
4417                    mH.removeMessages(H.APP_FREEZE_TIMEOUT);
4418                    mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 5000);
4419                }
4420            }
4421            final int N = wtoken.allAppWindows.size();
4422            for (int i=0; i<N; i++) {
4423                WindowState w = wtoken.allAppWindows.get(i);
4424                w.mAppFreezing = true;
4425            }
4426        }
4427    }
4428
4429    @Override
4430    public void startAppFreezingScreen(IBinder token, int configChanges) {
4431        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4432                "setAppFreezingScreen()")) {
4433            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4434        }
4435
4436        synchronized(mWindowMap) {
4437            if (configChanges == 0 && okToDisplay()) {
4438                if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
4439                return;
4440            }
4441
4442            AppWindowToken wtoken = findAppWindowToken(token);
4443            if (wtoken == null || wtoken.appToken == null) {
4444                Slog.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
4445                return;
4446            }
4447            final long origId = Binder.clearCallingIdentity();
4448            startAppFreezingScreenLocked(wtoken, configChanges);
4449            Binder.restoreCallingIdentity(origId);
4450        }
4451    }
4452
4453    @Override
4454    public void stopAppFreezingScreen(IBinder token, boolean force) {
4455        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4456                "setAppFreezingScreen()")) {
4457            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4458        }
4459
4460        synchronized(mWindowMap) {
4461            AppWindowToken wtoken = findAppWindowToken(token);
4462            if (wtoken == null || wtoken.appToken == null) {
4463                return;
4464            }
4465            final long origId = Binder.clearCallingIdentity();
4466            if (DEBUG_ORIENTATION) Slog.v(TAG, "Clear freezing of " + token
4467                    + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
4468            unsetAppFreezingScreenLocked(wtoken, true, force);
4469            Binder.restoreCallingIdentity(origId);
4470        }
4471    }
4472
4473    @Override
4474    public void removeAppToken(IBinder token) {
4475        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
4476                "removeAppToken()")) {
4477            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4478        }
4479
4480        AppWindowToken wtoken = null;
4481        AppWindowToken startingToken = null;
4482        boolean delayed = false;
4483
4484        final long origId = Binder.clearCallingIdentity();
4485        synchronized(mWindowMap) {
4486            WindowToken basewtoken = mTokenMap.remove(token);
4487            if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
4488                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken);
4489                delayed = setTokenVisibilityLocked(wtoken, null, false,
4490                        AppTransition.TRANSIT_UNSET, true);
4491                wtoken.inPendingTransaction = false;
4492                mOpeningApps.remove(wtoken);
4493                wtoken.waitingToShow = false;
4494                if (mClosingApps.contains(wtoken)) {
4495                    delayed = true;
4496                } else if (mAppTransition.isTransitionSet()) {
4497                    mClosingApps.add(wtoken);
4498                    wtoken.waitingToHide = true;
4499                    delayed = true;
4500                }
4501                if (DEBUG_APP_TRANSITIONS) Slog.v(
4502                        TAG, "Removing app " + wtoken + " delayed=" + delayed
4503                        + " animation=" + wtoken.mAppAnimator.animation
4504                        + " animating=" + wtoken.mAppAnimator.animating);
4505                final Task task = mTaskIdToTask.get(wtoken.groupId);
4506                DisplayContent displayContent = task.getDisplayContent();
4507                if (delayed) {
4508                    // set the token aside because it has an active animation to be finished
4509                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4510                            "removeAppToken make exiting: " + wtoken);
4511                    displayContent.mExitingAppTokens.add(wtoken);
4512                } else {
4513                    // Make sure there is no animation running on this token,
4514                    // so any windows associated with it will be removed as
4515                    // soon as their animations are complete
4516                    wtoken.mAppAnimator.clearAnimation();
4517                    wtoken.mAppAnimator.animating = false;
4518                }
4519                if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
4520                        "removeAppToken: " + wtoken);
4521
4522                if (task.removeAppToken(wtoken)) {
4523                    mTaskIdToTask.delete(wtoken.groupId);
4524                }
4525                wtoken.removed = true;
4526                if (wtoken.startingData != null) {
4527                    startingToken = wtoken;
4528                }
4529                unsetAppFreezingScreenLocked(wtoken, true, true);
4530                if (mFocusedApp == wtoken) {
4531                    if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Removing focused app token:" + wtoken);
4532                    mFocusedApp = null;
4533                    updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
4534                    mInputMonitor.setFocusedAppLw(null);
4535                }
4536            } else {
4537                Slog.w(TAG, "Attempted to remove non-existing app token: " + token);
4538            }
4539
4540            if (!delayed && wtoken != null) {
4541                wtoken.updateReportedVisibilityLocked();
4542            }
4543        }
4544        Binder.restoreCallingIdentity(origId);
4545
4546        // Will only remove if startingToken non null.
4547        scheduleRemoveStartingWindow(startingToken);
4548    }
4549
4550    void removeStartingWindowTimeout(AppWindowToken wtoken) {
4551        if (wtoken != null) {
4552            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
4553                    ": Remove starting window timeout " + wtoken + (wtoken != null ?
4554                    " startingWindow=" + wtoken.startingWindow : ""));
4555            mH.removeMessages(H.REMOVE_STARTING_TIMEOUT, wtoken);
4556        }
4557    }
4558
4559    void scheduleRemoveStartingWindow(AppWindowToken wtoken) {
4560        if (wtoken != null && wtoken.startingWindow != null) {
4561            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
4562                    ": Schedule remove starting " + wtoken + (wtoken != null ?
4563                    " startingWindow=" + wtoken.startingWindow : ""));
4564            removeStartingWindowTimeout(wtoken);
4565            Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken);
4566            mH.sendMessage(m);
4567        }
4568    }
4569    private boolean tmpRemoveAppWindowsLocked(WindowToken token) {
4570        final int NW = token.windows.size();
4571        if (NW > 0) {
4572            mWindowsChanged = true;
4573        }
4574        for (int i=0; i<NW; i++) {
4575            WindowState win = token.windows.get(i);
4576            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win);
4577            win.getWindowList().remove(win);
4578            int j = win.mChildWindows.size();
4579            while (j > 0) {
4580                j--;
4581                WindowState cwin = win.mChildWindows.get(j);
4582                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
4583                        "Tmp removing child window " + cwin);
4584                cwin.getWindowList().remove(cwin);
4585            }
4586        }
4587        return NW > 0;
4588    }
4589
4590    void dumpAppTokensLocked() {
4591        final int numDisplays = mDisplayContents.size();
4592        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4593            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
4594            Slog.v(TAG, "  Display " + displayContent.getDisplayId());
4595            final ArrayList<Task> tasks = displayContent.getTasks();
4596            int i = displayContent.numTokens();
4597            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
4598                AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4599                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4600                    final AppWindowToken wtoken = tokens.get(tokenNdx);
4601                    Slog.v(TAG, "  #" + --i + ": " + wtoken.token);
4602                }
4603            }
4604        }
4605    }
4606
4607    void dumpWindowsLocked() {
4608        int i = 0;
4609        final int numDisplays = mDisplayContents.size();
4610        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4611            final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
4612            for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
4613                Slog.v(TAG, "  #" + i++ + ": " + windows.get(winNdx));
4614            }
4615        }
4616    }
4617
4618    private int findAppWindowInsertionPointLocked(AppWindowToken target) {
4619        final int taskId = target.groupId;
4620        Task targetTask = mTaskIdToTask.get(taskId);
4621        if (targetTask == null) {
4622            Slog.w(TAG, "findAppWindowInsertionPointLocked: no Task for " + target + " taskId="
4623                    + taskId);
4624            return 0;
4625        }
4626        DisplayContent displayContent = targetTask.getDisplayContent();
4627        if (displayContent == null) {
4628            Slog.w(TAG, "findAppWindowInsertionPointLocked: no DisplayContent for " + target);
4629            return 0;
4630        }
4631        final WindowList windows = displayContent.getWindowList();
4632        final int NW = windows.size();
4633
4634        boolean found = false;
4635        final ArrayList<Task> tasks = displayContent.getTasks();
4636        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
4637            final Task task = tasks.get(taskNdx);
4638            if (!found && task.taskId != taskId) {
4639                continue;
4640            }
4641            AppTokenList tokens = task.mAppTokens;
4642            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
4643                final AppWindowToken wtoken = tokens.get(tokenNdx);
4644                if (!found && wtoken == target) {
4645                    found = true;
4646                }
4647                if (found) {
4648                    // Find the first app token below the new position that has
4649                    // a window displayed.
4650                    if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token);
4651                    if (wtoken.sendingToBottom) {
4652                        if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom");
4653                        continue;
4654                    }
4655                    for (int i = wtoken.windows.size() - 1; i >= 0; --i) {
4656                        WindowState win = wtoken.windows.get(i);
4657                        for (int j = win.mChildWindows.size() - 1; j >= 0; --j) {
4658                            WindowState cwin = win.mChildWindows.get(j);
4659                            if (cwin.mSubLayer >= 0) {
4660                                for (int pos = NW - 1; pos >= 0; pos--) {
4661                                    if (windows.get(pos) == cwin) {
4662                                        if (DEBUG_REORDER) Slog.v(TAG,
4663                                                "Found child win @" + (pos + 1));
4664                                        return pos + 1;
4665                                    }
4666                                }
4667                            }
4668                        }
4669                        for (int pos = NW - 1; pos >= 0; pos--) {
4670                            if (windows.get(pos) == win) {
4671                                if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1));
4672                                return pos + 1;
4673                            }
4674                        }
4675                    }
4676                }
4677            }
4678        }
4679        // Never put an app window underneath wallpaper.
4680        for (int pos = NW - 1; pos >= 0; pos--) {
4681            if (windows.get(pos).mIsWallpaper) {
4682                if (DEBUG_REORDER) Slog.v(TAG, "Found wallpaper @" + pos);
4683                return pos + 1;
4684            }
4685        }
4686        return 0;
4687    }
4688
4689    private final int reAddWindowLocked(int index, WindowState win) {
4690        final WindowList windows = win.getWindowList();
4691        final int NCW = win.mChildWindows.size();
4692        boolean added = false;
4693        for (int j=0; j<NCW; j++) {
4694            WindowState cwin = win.mChildWindows.get(j);
4695            if (!added && cwin.mSubLayer >= 0) {
4696                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding child window at "
4697                        + index + ": " + cwin);
4698                win.mRebuilding = false;
4699                windows.add(index, win);
4700                index++;
4701                added = true;
4702            }
4703            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
4704                    + index + ": " + cwin);
4705            cwin.mRebuilding = false;
4706            windows.add(index, cwin);
4707            index++;
4708        }
4709        if (!added) {
4710            if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Re-adding window at "
4711                    + index + ": " + win);
4712            win.mRebuilding = false;
4713            windows.add(index, win);
4714            index++;
4715        }
4716        mWindowsChanged = true;
4717        return index;
4718    }
4719
4720    private final int reAddAppWindowsLocked(final DisplayContent displayContent, int index,
4721                                            WindowToken token) {
4722        final int NW = token.windows.size();
4723        for (int i=0; i<NW; i++) {
4724            final WindowState win = token.windows.get(i);
4725            if (win.mDisplayContent == displayContent) {
4726                index = reAddWindowLocked(index, win);
4727            }
4728        }
4729        return index;
4730    }
4731
4732    void moveStackWindowsLocked(DisplayContent displayContent) {
4733        // First remove all of the windows from the list.
4734        final ArrayList<Task> tasks = displayContent.getTasks();
4735        final int numTasks = tasks.size();
4736        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4737            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4738            final int numTokens = tokens.size();
4739            for (int tokenNdx = numTokens - 1; tokenNdx >= 0; --tokenNdx) {
4740                tmpRemoveAppWindowsLocked(tokens.get(tokenNdx));
4741            }
4742        }
4743
4744        // And now add them back at the correct place.
4745        // Where to start adding?
4746        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
4747            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
4748            int pos = findAppWindowInsertionPointLocked(tokens.get(0));
4749            final int numTokens = tokens.size();
4750            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
4751                final AppWindowToken wtoken = tokens.get(tokenNdx);
4752                if (wtoken != null) {
4753                    final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken);
4754                    if (newPos != pos) {
4755                        displayContent.layoutNeeded = true;
4756                    }
4757                    pos = newPos;
4758                }
4759            }
4760        }
4761
4762        if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
4763                false /*updateInputWindows*/)) {
4764            assignLayersLocked(displayContent.getWindowList());
4765        }
4766
4767        mInputMonitor.setUpdateInputWindowsNeededLw();
4768        performLayoutAndPlaceSurfacesLocked();
4769        mInputMonitor.updateInputWindowsLw(false /*force*/);
4770
4771        //dump();
4772    }
4773
4774    public void moveTaskToTop(int taskId) {
4775        final long origId = Binder.clearCallingIdentity();
4776        try {
4777            synchronized(mWindowMap) {
4778                Task task = mTaskIdToTask.get(taskId);
4779                if (task == null) {
4780                    // Normal behavior, addAppToken will be called next and task will be created.
4781                    return;
4782                }
4783                final TaskStack stack = task.mStack;
4784                final DisplayContent displayContent = task.getDisplayContent();
4785                displayContent.moveStack(stack, true);
4786                if (displayContent.isDefaultDisplay) {
4787                    final TaskStack homeStack = displayContent.getHomeStack();
4788                    if (homeStack != stack) {
4789                        // When a non-home stack moves to the top, the home stack moves to the
4790                        // bottom.
4791                        displayContent.moveStack(homeStack, false);
4792                    }
4793                }
4794                stack.moveTaskToTop(task);
4795            }
4796        } finally {
4797            Binder.restoreCallingIdentity(origId);
4798        }
4799    }
4800
4801    public void moveTaskToBottom(int taskId) {
4802        final long origId = Binder.clearCallingIdentity();
4803        try {
4804            synchronized(mWindowMap) {
4805                Task task = mTaskIdToTask.get(taskId);
4806                if (task == null) {
4807                    Slog.e(TAG, "moveTaskToBottom: taskId=" + taskId
4808                            + " not found in mTaskIdToTask");
4809                    return;
4810                }
4811                final TaskStack stack = task.mStack;
4812                stack.moveTaskToBottom(task);
4813                moveStackWindowsLocked(stack.getDisplayContent());
4814            }
4815        } finally {
4816            Binder.restoreCallingIdentity(origId);
4817        }
4818    }
4819
4820    /**
4821     * Create a new TaskStack and place it next to an existing stack.
4822     * @param stackId The unique identifier of the new stack.
4823     */
4824    public void createStack(int stackId, int displayId) {
4825        synchronized (mWindowMap) {
4826            final int numDisplays = mDisplayContents.size();
4827            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
4828                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
4829                if (displayContent.getDisplayId() == displayId) {
4830                    TaskStack stack = displayContent.createStack(stackId);
4831                    mStackIdToStack.put(stackId, stack);
4832                    performLayoutAndPlaceSurfacesLocked();
4833                    return;
4834                }
4835            }
4836        }
4837    }
4838
4839    public int removeStack(int stackId) {
4840        synchronized (mWindowMap) {
4841            final TaskStack stack = mStackIdToStack.get(stackId);
4842            if (stack != null) {
4843                mStackIdToStack.delete(stackId);
4844                int nextStackId = stack.remove();
4845                stack.getDisplayContent().layoutNeeded = true;
4846                requestTraversalLocked();
4847                if (nextStackId > HOME_STACK_ID) {
4848                    return nextStackId;
4849                }
4850            }
4851            if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId);
4852        }
4853        return HOME_STACK_ID;
4854    }
4855
4856    public void removeTask(int taskId) {
4857        synchronized (mWindowMap) {
4858            Task task = mTaskIdToTask.get(taskId);
4859            if (task == null) {
4860                if (DEBUG_STACK) Slog.i(TAG, "removeTask: could not find taskId=" + taskId);
4861                return;
4862            }
4863            final TaskStack stack = task.mStack;
4864            EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, taskId, "removeTask");
4865            stack.removeTask(task);
4866            stack.getDisplayContent().layoutNeeded = true;
4867        }
4868    }
4869
4870    public void addTask(int taskId, int stackId, boolean toTop) {
4871        synchronized (mWindowMap) {
4872            Task task = mTaskIdToTask.get(taskId);
4873            if (task == null) {
4874                return;
4875            }
4876            TaskStack stack = mStackIdToStack.get(stackId);
4877            stack.addTask(task, toTop);
4878            final DisplayContent displayContent = stack.getDisplayContent();
4879            displayContent.layoutNeeded = true;
4880            performLayoutAndPlaceSurfacesLocked();
4881        }
4882    }
4883
4884    public void resizeStack(int stackId, Rect bounds) {
4885        synchronized (mWindowMap) {
4886            final TaskStack stack = mStackIdToStack.get(stackId);
4887            if (stack == null) {
4888                throw new IllegalArgumentException("resizeStack: stackId " + stackId
4889                        + " not found.");
4890            }
4891            if (stack.setBounds(bounds)) {
4892                stack.getDisplayContent().layoutNeeded = true;
4893                performLayoutAndPlaceSurfacesLocked();
4894            }
4895        }
4896    }
4897
4898    public void getStackBounds(int stackId, Rect bounds) {
4899        final TaskStack stack = mStackIdToStack.get(stackId);
4900        if (stack != null) {
4901            stack.getBounds(bounds);
4902            return;
4903        }
4904        bounds.setEmpty();
4905    }
4906
4907    // -------------------------------------------------------------
4908    // Misc IWindowSession methods
4909    // -------------------------------------------------------------
4910
4911    @Override
4912    public void startFreezingScreen(int exitAnim, int enterAnim) {
4913        if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4914                "startFreezingScreen()")) {
4915            throw new SecurityException("Requires FREEZE_SCREEN permission");
4916        }
4917
4918        synchronized(mWindowMap) {
4919            if (!mClientFreezingScreen) {
4920                mClientFreezingScreen = true;
4921                final long origId = Binder.clearCallingIdentity();
4922                try {
4923                    startFreezingDisplayLocked(false, exitAnim, enterAnim);
4924                    mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
4925                    mH.sendEmptyMessageDelayed(H.CLIENT_FREEZE_TIMEOUT, 5000);
4926                } finally {
4927                    Binder.restoreCallingIdentity(origId);
4928                }
4929            }
4930        }
4931    }
4932
4933    @Override
4934    public void stopFreezingScreen() {
4935        if (!checkCallingPermission(android.Manifest.permission.FREEZE_SCREEN,
4936                "stopFreezingScreen()")) {
4937            throw new SecurityException("Requires FREEZE_SCREEN permission");
4938        }
4939
4940        synchronized(mWindowMap) {
4941            if (mClientFreezingScreen) {
4942                mClientFreezingScreen = false;
4943                mLastFinishedFreezeSource = "client";
4944                final long origId = Binder.clearCallingIdentity();
4945                try {
4946                    stopFreezingDisplayLocked();
4947                } finally {
4948                    Binder.restoreCallingIdentity(origId);
4949                }
4950            }
4951        }
4952    }
4953
4954    @Override
4955    public void disableKeyguard(IBinder token, String tag) {
4956        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
4957            != PackageManager.PERMISSION_GRANTED) {
4958            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4959        }
4960
4961        mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
4962                KeyguardDisableHandler.KEYGUARD_DISABLE, new Pair<IBinder, String>(token, tag)));
4963    }
4964
4965    @Override
4966    public void reenableKeyguard(IBinder token) {
4967        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
4968            != PackageManager.PERMISSION_GRANTED) {
4969            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4970        }
4971
4972        mKeyguardDisableHandler.sendMessage(mKeyguardDisableHandler.obtainMessage(
4973                KeyguardDisableHandler.KEYGUARD_REENABLE, token));
4974    }
4975
4976    /**
4977     * @see android.app.KeyguardManager#exitKeyguardSecurely
4978     */
4979    @Override
4980    public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
4981        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
4982            != PackageManager.PERMISSION_GRANTED) {
4983            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
4984        }
4985        mPolicy.exitKeyguardSecurely(new WindowManagerPolicy.OnKeyguardExitResult() {
4986            @Override
4987            public void onKeyguardExitResult(boolean success) {
4988                try {
4989                    callback.onKeyguardExitResult(success);
4990                } catch (RemoteException e) {
4991                    // Client has died, we don't care.
4992                }
4993            }
4994        });
4995    }
4996
4997    @Override
4998    public boolean inKeyguardRestrictedInputMode() {
4999        return mPolicy.inKeyguardRestrictedKeyInputMode();
5000    }
5001
5002    @Override
5003    public boolean isKeyguardLocked() {
5004        return mPolicy.isKeyguardLocked();
5005    }
5006
5007    @Override
5008    public boolean isKeyguardSecure() {
5009        return mPolicy.isKeyguardSecure();
5010    }
5011
5012    @Override
5013    public void dismissKeyguard() {
5014        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
5015                != PackageManager.PERMISSION_GRANTED) {
5016            throw new SecurityException("Requires DISABLE_KEYGUARD permission");
5017        }
5018        synchronized(mWindowMap) {
5019            mPolicy.dismissKeyguardLw();
5020        }
5021    }
5022
5023    @Override
5024    public void closeSystemDialogs(String reason) {
5025        synchronized(mWindowMap) {
5026            final int numDisplays = mDisplayContents.size();
5027            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5028                final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5029                final int numWindows = windows.size();
5030                for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5031                    final WindowState w = windows.get(winNdx);
5032                    if (w.mHasSurface) {
5033                        try {
5034                            w.mClient.closeSystemDialogs(reason);
5035                        } catch (RemoteException e) {
5036                        }
5037                    }
5038                }
5039            }
5040        }
5041    }
5042
5043    static float fixScale(float scale) {
5044        if (scale < 0) scale = 0;
5045        else if (scale > 20) scale = 20;
5046        return Math.abs(scale);
5047    }
5048
5049    @Override
5050    public void setAnimationScale(int which, float scale) {
5051        if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5052                "setAnimationScale()")) {
5053            throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
5054        }
5055
5056        scale = fixScale(scale);
5057        switch (which) {
5058            case 0: mWindowAnimationScale = scale; break;
5059            case 1: mTransitionAnimationScale = scale; break;
5060            case 2: mAnimatorDurationScale = scale; break;
5061        }
5062
5063        // Persist setting
5064        mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
5065    }
5066
5067    @Override
5068    public void setAnimationScales(float[] scales) {
5069        if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
5070                "setAnimationScale()")) {
5071            throw new SecurityException("Requires SET_ANIMATION_SCALE permission");
5072        }
5073
5074        if (scales != null) {
5075            if (scales.length >= 1) {
5076                mWindowAnimationScale = fixScale(scales[0]);
5077            }
5078            if (scales.length >= 2) {
5079                mTransitionAnimationScale = fixScale(scales[1]);
5080            }
5081            if (scales.length >= 3) {
5082                setAnimatorDurationScale(fixScale(scales[2]));
5083            }
5084        }
5085
5086        // Persist setting
5087        mH.sendEmptyMessage(H.PERSIST_ANIMATION_SCALE);
5088    }
5089
5090    private void setAnimatorDurationScale(float scale) {
5091        mAnimatorDurationScale = scale;
5092        ValueAnimator.setDurationScale(scale);
5093    }
5094
5095    @Override
5096    public float getAnimationScale(int which) {
5097        switch (which) {
5098            case 0: return mWindowAnimationScale;
5099            case 1: return mTransitionAnimationScale;
5100            case 2: return mAnimatorDurationScale;
5101        }
5102        return 0;
5103    }
5104
5105    @Override
5106    public float[] getAnimationScales() {
5107        return new float[] { mWindowAnimationScale, mTransitionAnimationScale,
5108                mAnimatorDurationScale };
5109    }
5110
5111    @Override
5112    public void registerPointerEventListener(PointerEventListener listener) {
5113        mPointerEventDispatcher.registerInputEventListener(listener);
5114    }
5115
5116    @Override
5117    public void unregisterPointerEventListener(PointerEventListener listener) {
5118        mPointerEventDispatcher.unregisterInputEventListener(listener);
5119    }
5120
5121    // Called by window manager policy. Not exposed externally.
5122    @Override
5123    public int getLidState() {
5124        int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY,
5125                InputManagerService.SW_LID);
5126        if (sw > 0) {
5127            // Switch state: AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL.
5128            return LID_CLOSED;
5129        } else if (sw == 0) {
5130            // Switch state: AKEY_STATE_UP.
5131            return LID_OPEN;
5132        } else {
5133            // Switch state: AKEY_STATE_UNKNOWN.
5134            return LID_ABSENT;
5135        }
5136    }
5137
5138    // Called by window manager policy.  Not exposed externally.
5139    @Override
5140    public void switchKeyboardLayout(int deviceId, int direction) {
5141        mInputManager.switchKeyboardLayout(deviceId, direction);
5142    }
5143
5144    // Called by window manager policy.  Not exposed externally.
5145    @Override
5146    public void shutdown(boolean confirm) {
5147        ShutdownThread.shutdown(mContext, confirm);
5148    }
5149
5150    // Called by window manager policy.  Not exposed externally.
5151    @Override
5152    public void rebootSafeMode(boolean confirm) {
5153        ShutdownThread.rebootSafeMode(mContext, confirm);
5154    }
5155
5156    @Override
5157    public void setInputFilter(IInputFilter filter) {
5158        if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
5159            throw new SecurityException("Requires FILTER_EVENTS permission");
5160        }
5161        mInputManager.setInputFilter(filter);
5162    }
5163
5164    @Override
5165    public void setTouchExplorationEnabled(boolean enabled) {
5166        mPolicy.setTouchExplorationEnabled(enabled);
5167    }
5168
5169    public void setCurrentUser(final int newUserId) {
5170        synchronized (mWindowMap) {
5171            int oldUserId = mCurrentUserId;
5172            mCurrentUserId = newUserId;
5173            mAppTransition.setCurrentUser(newUserId);
5174            mPolicy.setCurrentUserLw(newUserId);
5175
5176            // Hide windows that should not be seen by the new user.
5177            final int numDisplays = mDisplayContents.size();
5178            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5179                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
5180                displayContent.switchUserStacks(oldUserId, newUserId);
5181                rebuildAppWindowListLocked(displayContent);
5182            }
5183            performLayoutAndPlaceSurfacesLocked();
5184        }
5185    }
5186
5187    public void enableScreenAfterBoot() {
5188        synchronized(mWindowMap) {
5189            if (DEBUG_BOOT) {
5190                RuntimeException here = new RuntimeException("here");
5191                here.fillInStackTrace();
5192                Slog.i(TAG, "enableScreenAfterBoot: mDisplayEnabled=" + mDisplayEnabled
5193                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
5194                        + " mShowingBootMessages=" + mShowingBootMessages
5195                        + " mSystemBooted=" + mSystemBooted, here);
5196            }
5197            if (mSystemBooted) {
5198                return;
5199            }
5200            mSystemBooted = true;
5201            hideBootMessagesLocked();
5202            // If the screen still doesn't come up after 30 seconds, give
5203            // up and turn it on.
5204            mH.sendEmptyMessageDelayed(H.BOOT_TIMEOUT, 30*1000);
5205        }
5206
5207        mPolicy.systemBooted();
5208
5209        performEnableScreen();
5210    }
5211
5212    void enableScreenIfNeededLocked() {
5213        if (DEBUG_BOOT) {
5214            RuntimeException here = new RuntimeException("here");
5215            here.fillInStackTrace();
5216            Slog.i(TAG, "enableScreenIfNeededLocked: mDisplayEnabled=" + mDisplayEnabled
5217                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
5218                    + " mShowingBootMessages=" + mShowingBootMessages
5219                    + " mSystemBooted=" + mSystemBooted, here);
5220        }
5221        if (mDisplayEnabled) {
5222            return;
5223        }
5224        if (!mSystemBooted && !mShowingBootMessages) {
5225            return;
5226        }
5227        mH.sendEmptyMessage(H.ENABLE_SCREEN);
5228    }
5229
5230    public void performBootTimeout() {
5231        synchronized(mWindowMap) {
5232            if (mDisplayEnabled) {
5233                return;
5234            }
5235            Slog.w(TAG, "***** BOOT TIMEOUT: forcing display enabled");
5236            mForceDisplayEnabled = true;
5237        }
5238        performEnableScreen();
5239    }
5240
5241    public void performEnableScreen() {
5242        synchronized(mWindowMap) {
5243            if (DEBUG_BOOT) {
5244                RuntimeException here = new RuntimeException("here");
5245                here.fillInStackTrace();
5246                Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
5247                        + " mForceDisplayEnabled=" + mForceDisplayEnabled
5248                        + " mShowingBootMessages=" + mShowingBootMessages
5249                        + " mSystemBooted=" + mSystemBooted
5250                        + " mOnlyCore=" + mOnlyCore, here);
5251            }
5252            if (mDisplayEnabled) {
5253                return;
5254            }
5255            if (!mSystemBooted && !mShowingBootMessages) {
5256                return;
5257            }
5258
5259            if (!mForceDisplayEnabled) {
5260                // Don't enable the screen until all existing windows
5261                // have been drawn.
5262                boolean haveBootMsg = false;
5263                boolean haveApp = false;
5264                // if the wallpaper service is disabled on the device, we're never going to have
5265                // wallpaper, don't bother waiting for it
5266                boolean haveWallpaper = false;
5267                boolean wallpaperEnabled = mContext.getResources().getBoolean(
5268                        com.android.internal.R.bool.config_enableWallpaperService)
5269                        && !mOnlyCore;
5270                boolean haveKeyguard = true;
5271                // TODO(multidisplay): Expand to all displays?
5272                final WindowList windows = getDefaultWindowListLocked();
5273                final int N = windows.size();
5274                for (int i=0; i<N; i++) {
5275                    WindowState w = windows.get(i);
5276                    if (w.mAttrs.type == TYPE_KEYGUARD) {
5277                        // Only if there is a keyguard attached to the window manager
5278                        // will we consider ourselves as having a keyguard.  If it
5279                        // isn't attached, we don't know if it wants to be shown or
5280                        // hidden.  If it is attached, we will say we have a keyguard
5281                        // if the window doesn't want to be visible, because in that
5282                        // case it explicitly doesn't want to be shown so we should
5283                        // not delay turning the screen on for it.
5284                        boolean vis = w.mViewVisibility == View.VISIBLE
5285                                && w.mPolicyVisibility;
5286                        haveKeyguard = !vis;
5287                    }
5288                    if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
5289                        return;
5290                    }
5291                    if (w.isDrawnLw()) {
5292                        if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
5293                            haveBootMsg = true;
5294                        } else if (w.mAttrs.type == TYPE_APPLICATION) {
5295                            haveApp = true;
5296                        } else if (w.mAttrs.type == TYPE_WALLPAPER) {
5297                            haveWallpaper = true;
5298                        } else if (w.mAttrs.type == TYPE_KEYGUARD) {
5299                            haveKeyguard = true;
5300                        }
5301                    }
5302                }
5303
5304                if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
5305                    Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
5306                            + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
5307                            + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
5308                            + " haveKeyguard=" + haveKeyguard);
5309                }
5310
5311                // If we are turning on the screen to show the boot message,
5312                // don't do it until the boot message is actually displayed.
5313                if (!mSystemBooted && !haveBootMsg) {
5314                    return;
5315                }
5316
5317                // If we are turning on the screen after the boot is completed
5318                // normally, don't do so until we have the application and
5319                // wallpaper.
5320                if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
5321                        (wallpaperEnabled && !haveWallpaper))) {
5322                    return;
5323                }
5324            }
5325
5326            mDisplayEnabled = true;
5327            if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
5328            if (false) {
5329                StringWriter sw = new StringWriter();
5330                PrintWriter pw = new FastPrintWriter(sw, false, 1024);
5331                this.dump(null, pw, null);
5332                pw.flush();
5333                Slog.i(TAG, sw.toString());
5334            }
5335            try {
5336                IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
5337                if (surfaceFlinger != null) {
5338                    //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
5339                    Parcel data = Parcel.obtain();
5340                    data.writeInterfaceToken("android.ui.ISurfaceComposer");
5341                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
5342                                            data, null, 0);
5343                    data.recycle();
5344                }
5345            } catch (RemoteException ex) {
5346                Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
5347            }
5348
5349            // Enable input dispatch.
5350            mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
5351        }
5352
5353        mPolicy.enableScreenAfterBoot();
5354
5355        // Make sure the last requested orientation has been applied.
5356        updateRotationUnchecked(false, false);
5357    }
5358
5359    public void showBootMessage(final CharSequence msg, final boolean always) {
5360        boolean first = false;
5361        synchronized(mWindowMap) {
5362            if (DEBUG_BOOT) {
5363                RuntimeException here = new RuntimeException("here");
5364                here.fillInStackTrace();
5365                Slog.i(TAG, "showBootMessage: msg=" + msg + " always=" + always
5366                        + " mAllowBootMessages=" + mAllowBootMessages
5367                        + " mShowingBootMessages=" + mShowingBootMessages
5368                        + " mSystemBooted=" + mSystemBooted, here);
5369            }
5370            if (!mAllowBootMessages) {
5371                return;
5372            }
5373            if (!mShowingBootMessages) {
5374                if (!always) {
5375                    return;
5376                }
5377                first = true;
5378            }
5379            if (mSystemBooted) {
5380                return;
5381            }
5382            mShowingBootMessages = true;
5383            mPolicy.showBootMessage(msg, always);
5384        }
5385        if (first) {
5386            performEnableScreen();
5387        }
5388    }
5389
5390    public void hideBootMessagesLocked() {
5391        if (DEBUG_BOOT) {
5392            RuntimeException here = new RuntimeException("here");
5393            here.fillInStackTrace();
5394            Slog.i(TAG, "hideBootMessagesLocked: mDisplayEnabled=" + mDisplayEnabled
5395                    + " mForceDisplayEnabled=" + mForceDisplayEnabled
5396                    + " mShowingBootMessages=" + mShowingBootMessages
5397                    + " mSystemBooted=" + mSystemBooted, here);
5398        }
5399        if (mShowingBootMessages) {
5400            mShowingBootMessages = false;
5401            mPolicy.hideBootMessages();
5402        }
5403    }
5404
5405    @Override
5406    public void setInTouchMode(boolean mode) {
5407        synchronized(mWindowMap) {
5408            mInTouchMode = mode;
5409        }
5410    }
5411
5412    // TODO: more accounting of which pid(s) turned it on, keep count,
5413    // only allow disables from pids which have count on, etc.
5414    @Override
5415    public void showStrictModeViolation(boolean on) {
5416        int pid = Binder.getCallingPid();
5417        mH.sendMessage(mH.obtainMessage(H.SHOW_STRICT_MODE_VIOLATION, on ? 1 : 0, pid));
5418    }
5419
5420    private void showStrictModeViolation(int arg, int pid) {
5421        final boolean on = arg != 0;
5422        synchronized(mWindowMap) {
5423            // Ignoring requests to enable the red border from clients
5424            // which aren't on screen.  (e.g. Broadcast Receivers in
5425            // the background..)
5426            if (on) {
5427                boolean isVisible = false;
5428                final int numDisplays = mDisplayContents.size();
5429                for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
5430                    final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
5431                    final int numWindows = windows.size();
5432                    for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
5433                        final WindowState ws = windows.get(winNdx);
5434                        if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
5435                            isVisible = true;
5436                            break;
5437                        }
5438                    }
5439                }
5440                if (!isVisible) {
5441                    return;
5442                }
5443            }
5444
5445            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5446                    ">>> OPEN TRANSACTION showStrictModeViolation");
5447            SurfaceControl.openTransaction();
5448            try {
5449                // TODO(multi-display): support multiple displays
5450                if (mStrictModeFlash == null) {
5451                    mStrictModeFlash = new StrictModeFlash(
5452                            getDefaultDisplayContentLocked().getDisplay(), mFxSession);
5453                }
5454                mStrictModeFlash.setVisibility(on);
5455            } finally {
5456                SurfaceControl.closeTransaction();
5457                if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
5458                        "<<< CLOSE TRANSACTION showStrictModeViolation");
5459            }
5460        }
5461    }
5462
5463    @Override
5464    public void setStrictModeVisualIndicatorPreference(String value) {
5465        SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
5466    }
5467
5468    /**
5469     * Takes a snapshot of the screen.  In landscape mode this grabs the whole screen.
5470     * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
5471     * of the target image.
5472     *
5473     * @param displayId the Display to take a screenshot of.
5474     * @param width the width of the target bitmap
5475     * @param height the height of the target bitmap
5476     * @param force565 if true the returned bitmap will be RGB_565, otherwise it
5477     *                 will be the same config as the surface
5478     */
5479    @Override
5480    public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
5481            int height, boolean force565) {
5482        if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5483                "screenshotApplications()")) {
5484            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
5485        }
5486
5487        Bitmap rawss = null;
5488
5489        int maxLayer = 0;
5490        final Rect frame = new Rect();
5491
5492        float scale = 0;
5493        int dw, dh;
5494        int rot = Surface.ROTATION_0;
5495
5496        boolean screenshotReady;
5497        int minLayer;
5498        if (appToken == null) {
5499            screenshotReady = true;
5500            minLayer = 0;
5501        } else {
5502            screenshotReady = false;
5503            minLayer = Integer.MAX_VALUE;
5504        }
5505
5506        int retryCount = 0;
5507        WindowState appWin = null;
5508
5509        do {
5510            if (retryCount++ > 0) {
5511                try {
5512                    Thread.sleep(100);
5513                } catch (InterruptedException e) {
5514                }
5515            }
5516            synchronized(mWindowMap) {
5517                final DisplayContent displayContent = getDisplayContentLocked(displayId);
5518                if (displayContent == null) {
5519                    return null;
5520                }
5521                final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5522                dw = displayInfo.logicalWidth;
5523                dh = displayInfo.logicalHeight;
5524
5525                int aboveAppLayer = mPolicy.windowTypeToLayerLw(TYPE_APPLICATION)
5526                        * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
5527                aboveAppLayer += TYPE_LAYER_MULTIPLIER;
5528
5529                boolean isImeTarget = mInputMethodTarget != null
5530                        && mInputMethodTarget.mAppToken != null
5531                        && mInputMethodTarget.mAppToken.appToken != null
5532                        && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
5533
5534                // Figure out the part of the screen that is actually the app.
5535                boolean including = false;
5536                appWin = null;
5537                final WindowList windows = displayContent.getWindowList();
5538                final Rect stackBounds = new Rect();
5539                for (int i = windows.size() - 1; i >= 0; i--) {
5540                    WindowState ws = windows.get(i);
5541                    if (!ws.mHasSurface) {
5542                        continue;
5543                    }
5544                    if (ws.mLayer >= aboveAppLayer) {
5545                        continue;
5546                    }
5547                    // When we will skip windows: when we are not including
5548                    // ones behind a window we didn't skip, and we are actually
5549                    // taking a screenshot of a specific app.
5550                    if (!including && appToken != null) {
5551                        // Also, we can possibly skip this window if it is not
5552                        // an IME target or the application for the screenshot
5553                        // is not the current IME target.
5554                        if (!ws.mIsImWindow || !isImeTarget) {
5555                            // And finally, this window is of no interest if it
5556                            // is not associated with the screenshot app.
5557                            if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
5558                                continue;
5559                            }
5560                            appWin = ws;
5561                            ws.getStackBounds(stackBounds);
5562                        }
5563                    }
5564
5565                    // We keep on including windows until we go past a full-screen
5566                    // window.
5567                    including = !ws.mIsImWindow && !ws.isFullscreen(dw, dh);
5568
5569                    final WindowStateAnimator winAnim = ws.mWinAnimator;
5570                    if (maxLayer < winAnim.mSurfaceLayer) {
5571                        maxLayer = winAnim.mSurfaceLayer;
5572                    }
5573                    if (minLayer > winAnim.mSurfaceLayer) {
5574                        minLayer = winAnim.mSurfaceLayer;
5575                    }
5576
5577                    // Don't include wallpaper in bounds calculation
5578                    if (!ws.mIsWallpaper) {
5579                        final Rect wf = ws.mFrame;
5580                        final Rect cr = ws.mContentInsets;
5581                        int left = wf.left + cr.left;
5582                        int top = wf.top + cr.top;
5583                        int right = wf.right - cr.right;
5584                        int bottom = wf.bottom - cr.bottom;
5585                        frame.union(left, top, right, bottom);
5586                        frame.intersect(stackBounds);
5587                    }
5588
5589                    if (ws.mAppToken != null && ws.mAppToken.token == appToken &&
5590                            ws.isDisplayedLw()) {
5591                        screenshotReady = true;
5592                    }
5593                }
5594
5595                if (appToken != null && appWin == null) {
5596                    // Can't find a window to snapshot.
5597                    if (DEBUG_SCREENSHOT) Slog.i(TAG,
5598                            "Screenshot: Couldn't find a surface matching " + appToken);
5599                    return null;
5600                }
5601                if (!screenshotReady) {
5602                    // Delay and hope that window gets drawn.
5603                    if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot: No image ready for " + appToken
5604                            + ", " + appWin + " drawState=" + appWin.mWinAnimator.mDrawState);
5605                    continue;
5606                }
5607
5608                // Constrain frame to the screen size.
5609                frame.intersect(0, 0, dw, dh);
5610
5611                if (frame.isEmpty() || maxLayer == 0) {
5612                    if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
5613                            + ": returning null frame=" + frame.toShortString() + " maxLayer="
5614                            + maxLayer);
5615                    return null;
5616                }
5617
5618                // The screenshot API does not apply the current screen rotation.
5619                rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
5620                int fw = frame.width();
5621                int fh = frame.height();
5622
5623                // Constrain thumbnail to smaller of screen width or height. Assumes aspect
5624                // of thumbnail is the same as the screen (in landscape) or square.
5625                scale = Math.max(width / (float) fw, height / (float) fh);
5626                /*
5627                float targetWidthScale = width / (float) fw;
5628                float targetHeightScale = height / (float) fh;
5629                if (fw <= fh) {
5630                    scale = targetWidthScale;
5631                    // If aspect of thumbnail is the same as the screen (in landscape),
5632                    // select the slightly larger value so we fill the entire bitmap
5633                    if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
5634                        scale = targetHeightScale;
5635                    }
5636                } else {
5637                    scale = targetHeightScale;
5638                    // If aspect of thumbnail is the same as the screen (in landscape),
5639                    // select the slightly larger value so we fill the entire bitmap
5640                    if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
5641                        scale = targetWidthScale;
5642                    }
5643                }
5644                */
5645
5646                // The screen shot will contain the entire screen.
5647                dw = (int)(dw*scale);
5648                dh = (int)(dh*scale);
5649                if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
5650                    int tmp = dw;
5651                    dw = dh;
5652                    dh = tmp;
5653                    rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
5654                }
5655                if (DEBUG_SCREENSHOT) {
5656                    Slog.i(TAG, "Screenshot: " + dw + "x" + dh + " from " + minLayer + " to "
5657                            + maxLayer + " appToken=" + appToken);
5658                    for (int i = 0; i < windows.size(); i++) {
5659                        WindowState win = windows.get(i);
5660                        Slog.i(TAG, win + ": " + win.mLayer
5661                                + " animLayer=" + win.mWinAnimator.mAnimLayer
5662                                + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
5663                    }
5664                }
5665                rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
5666            }
5667        } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
5668        if (retryCount > MAX_SCREENSHOT_RETRIES)  Slog.i(TAG, "Screenshot max retries " +
5669                retryCount + " of " + appToken + " appWin=" + (appWin == null ?
5670                        "null" : (appWin + " drawState=" + appWin.mWinAnimator.mDrawState)));
5671
5672        if (rawss == null) {
5673            Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
5674                    + ") to layer " + maxLayer);
5675            return null;
5676        }
5677
5678        Bitmap bm = Bitmap.createBitmap(width, height, force565 ? Config.RGB_565 : rawss.getConfig());
5679        frame.scale(scale);
5680        Matrix matrix = new Matrix();
5681        ScreenRotationAnimation.createRotationMatrix(rot, dw, dh, matrix);
5682        // TODO: Test for RTL vs. LTR and use frame.right-width instead of -frame.left
5683        matrix.postTranslate(-FloatMath.ceil(frame.left), -FloatMath.ceil(frame.top));
5684        Canvas canvas = new Canvas(bm);
5685        canvas.drawColor(0xFF000000);
5686        canvas.drawBitmap(rawss, matrix, null);
5687        canvas.setBitmap(null);
5688
5689        if (DEBUG_SCREENSHOT) {
5690            // TEST IF IT's ALL BLACK
5691            int[] buffer = new int[bm.getWidth() * bm.getHeight()];
5692            bm.getPixels(buffer, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());
5693            boolean allBlack = true;
5694            final int firstColor = buffer[0];
5695            for (int i = 0; i < buffer.length; i++) {
5696                if (buffer[i] != firstColor) {
5697                    allBlack = false;
5698                    break;
5699                }
5700            }
5701            if (allBlack) {
5702                Slog.i(TAG, "Screenshot " + appWin + " was monochrome(" +
5703                        Integer.toHexString(firstColor) + ")! mSurfaceLayer=" +
5704                        (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "null") +
5705                        " minLayer=" + minLayer + " maxLayer=" + maxLayer);
5706            }
5707        }
5708
5709        rawss.recycle();
5710        return bm;
5711    }
5712
5713    /**
5714     * Freeze rotation changes.  (Enable "rotation lock".)
5715     * Persists across reboots.
5716     * @param rotation The desired rotation to freeze to, or -1 to use the
5717     * current rotation.
5718     */
5719    @Override
5720    public void freezeRotation(int rotation) {
5721        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5722                "freezeRotation()")) {
5723            throw new SecurityException("Requires SET_ORIENTATION permission");
5724        }
5725        if (rotation < -1 || rotation > Surface.ROTATION_270) {
5726            throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
5727                    + "rotation constant.");
5728        }
5729
5730        if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
5731
5732        long origId = Binder.clearCallingIdentity();
5733        try {
5734            mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
5735                    rotation == -1 ? mRotation : rotation);
5736        } finally {
5737            Binder.restoreCallingIdentity(origId);
5738        }
5739
5740        updateRotationUnchecked(false, false);
5741    }
5742
5743    /**
5744     * Thaw rotation changes.  (Disable "rotation lock".)
5745     * Persists across reboots.
5746     */
5747    @Override
5748    public void thawRotation() {
5749        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
5750                "thawRotation()")) {
5751            throw new SecurityException("Requires SET_ORIENTATION permission");
5752        }
5753
5754        if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
5755
5756        long origId = Binder.clearCallingIdentity();
5757        try {
5758            mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
5759                    777); // rot not used
5760        } finally {
5761            Binder.restoreCallingIdentity(origId);
5762        }
5763
5764        updateRotationUnchecked(false, false);
5765    }
5766
5767    /**
5768     * Recalculate the current rotation.
5769     *
5770     * Called by the window manager policy whenever the state of the system changes
5771     * such that the current rotation might need to be updated, such as when the
5772     * device is docked or rotated into a new posture.
5773     */
5774    @Override
5775    public void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
5776        updateRotationUnchecked(alwaysSendConfiguration, forceRelayout);
5777    }
5778
5779    /**
5780     * Temporarily pauses rotation changes until resumed.
5781     *
5782     * This can be used to prevent rotation changes from occurring while the user is
5783     * performing certain operations, such as drag and drop.
5784     *
5785     * This call nests and must be matched by an equal number of calls to
5786     * {@link #resumeRotationLocked}.
5787     */
5788    void pauseRotationLocked() {
5789        mDeferredRotationPauseCount += 1;
5790    }
5791
5792    /**
5793     * Resumes normal rotation changes after being paused.
5794     */
5795    void resumeRotationLocked() {
5796        if (mDeferredRotationPauseCount > 0) {
5797            mDeferredRotationPauseCount -= 1;
5798            if (mDeferredRotationPauseCount == 0) {
5799                boolean changed = updateRotationUncheckedLocked(false);
5800                if (changed) {
5801                    mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
5802                }
5803            }
5804        }
5805    }
5806
5807    public void updateRotationUnchecked(boolean alwaysSendConfiguration, boolean forceRelayout) {
5808        if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
5809                   + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
5810
5811        long origId = Binder.clearCallingIdentity();
5812        boolean changed;
5813        synchronized(mWindowMap) {
5814            changed = updateRotationUncheckedLocked(false);
5815            if (!changed || forceRelayout) {
5816                getDefaultDisplayContentLocked().layoutNeeded = true;
5817                performLayoutAndPlaceSurfacesLocked();
5818            }
5819        }
5820
5821        if (changed || alwaysSendConfiguration) {
5822            sendNewConfiguration();
5823        }
5824
5825        Binder.restoreCallingIdentity(origId);
5826    }
5827
5828    // TODO(multidisplay): Rotate any display?
5829    /**
5830     * Updates the current rotation.
5831     *
5832     * Returns true if the rotation has been changed.  In this case YOU
5833     * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
5834     */
5835    public boolean updateRotationUncheckedLocked(boolean inTransaction) {
5836        if (mDeferredRotationPauseCount > 0) {
5837            // Rotation updates have been paused temporarily.  Defer the update until
5838            // updates have been resumed.
5839            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
5840            return false;
5841        }
5842
5843        ScreenRotationAnimation screenRotationAnimation =
5844                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5845        if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
5846            // Rotation updates cannot be performed while the previous rotation change
5847            // animation is still in progress.  Skip this update.  We will try updating
5848            // again after the animation is finished and the display is unfrozen.
5849            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
5850            return false;
5851        }
5852
5853        if (!mDisplayEnabled) {
5854            // No point choosing a rotation if the display is not enabled.
5855            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
5856            return false;
5857        }
5858
5859        // TODO: Implement forced rotation changes.
5860        //       Set mAltOrientation to indicate that the application is receiving
5861        //       an orientation that has different metrics than it expected.
5862        //       eg. Portrait instead of Landscape.
5863
5864        int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
5865        boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
5866                mForcedAppOrientation, rotation);
5867
5868        if (DEBUG_ORIENTATION) {
5869            Slog.v(TAG, "Application requested orientation "
5870                    + mForcedAppOrientation + ", got rotation " + rotation
5871                    + " which has " + (altOrientation ? "incompatible" : "compatible")
5872                    + " metrics");
5873        }
5874
5875        if (mRotation == rotation && mAltOrientation == altOrientation) {
5876            // No change.
5877            return false;
5878        }
5879
5880        if (DEBUG_ORIENTATION) {
5881            Slog.v(TAG,
5882                "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
5883                + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
5884                + ", forceApp=" + mForcedAppOrientation);
5885        }
5886
5887        mRotation = rotation;
5888        mAltOrientation = altOrientation;
5889        mPolicy.setRotationLw(mRotation);
5890
5891        mWindowsFreezingScreen = true;
5892        mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
5893        mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
5894        mWaitingForConfig = true;
5895        final DisplayContent displayContent = getDefaultDisplayContentLocked();
5896        displayContent.layoutNeeded = true;
5897        final int[] anim = new int[2];
5898        if (displayContent.isDimming()) {
5899            anim[0] = anim[1] = 0;
5900        } else {
5901            mPolicy.selectRotationAnimationLw(anim);
5902        }
5903        startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
5904        // startFreezingDisplayLocked can reset the ScreenRotationAnimation.
5905        screenRotationAnimation =
5906                mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
5907
5908        // We need to update our screen size information to match the new
5909        // rotation.  Note that this is redundant with the later call to
5910        // sendNewConfiguration() that must be called after this function
5911        // returns...  however we need to do the screen size part of that
5912        // before then so we have the correct size to use when initializing
5913        // the rotation animation for the new rotation.
5914        computeScreenConfigurationLocked(null);
5915
5916        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
5917        if (!inTransaction) {
5918            if (SHOW_TRANSACTIONS) {
5919                Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked");
5920            }
5921            SurfaceControl.openTransaction();
5922        }
5923        try {
5924            // NOTE: We disable the rotation in the emulator because
5925            //       it doesn't support hardware OpenGL emulation yet.
5926            if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
5927                    && screenRotationAnimation.hasScreenshot()) {
5928                if (screenRotationAnimation.setRotationInTransaction(
5929                        rotation, mFxSession,
5930                        MAX_ANIMATION_DURATION, mTransitionAnimationScale,
5931                        displayInfo.logicalWidth, displayInfo.logicalHeight)) {
5932                    scheduleAnimationLocked();
5933                }
5934            }
5935
5936            mDisplayManagerService.performTraversalInTransactionFromWindowManager();
5937        } finally {
5938            if (!inTransaction) {
5939                SurfaceControl.closeTransaction();
5940                if (SHOW_LIGHT_TRANSACTIONS) {
5941                    Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked");
5942                }
5943            }
5944        }
5945
5946        final WindowList windows = displayContent.getWindowList();
5947        for (int i = windows.size() - 1; i >= 0; i--) {
5948            WindowState w = windows.get(i);
5949            if (w.mHasSurface) {
5950                if (DEBUG_ORIENTATION) Slog.v(TAG, "Set mOrientationChanging of " + w);
5951                w.mOrientationChanging = true;
5952                mInnerFields.mOrientationChangeComplete = false;
5953            }
5954            w.mLastFreezeDuration = 0;
5955        }
5956
5957        for (int i=mRotationWatchers.size()-1; i>=0; i--) {
5958            try {
5959                mRotationWatchers.get(i).onRotationChanged(rotation);
5960            } catch (RemoteException e) {
5961            }
5962        }
5963
5964        //TODO (multidisplay): Magnification is supported only for the default display.
5965        if (mDisplayMagnifier != null
5966                && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
5967            mDisplayMagnifier.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
5968        }
5969
5970        return true;
5971    }
5972
5973    @Override
5974    public int getRotation() {
5975        return mRotation;
5976    }
5977
5978    @Override
5979    public boolean isRotationFrozen() {
5980        return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
5981    }
5982
5983    @Override
5984    public int watchRotation(IRotationWatcher watcher) {
5985        final IBinder watcherBinder = watcher.asBinder();
5986        IBinder.DeathRecipient dr = new IBinder.DeathRecipient() {
5987            @Override
5988            public void binderDied() {
5989                synchronized (mWindowMap) {
5990                    for (int i=0; i<mRotationWatchers.size(); i++) {
5991                        if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
5992                            IRotationWatcher removed = mRotationWatchers.remove(i);
5993                            if (removed != null) {
5994                                removed.asBinder().unlinkToDeath(this, 0);
5995                            }
5996                            i--;
5997                        }
5998                    }
5999                }
6000            }
6001        };
6002
6003        synchronized (mWindowMap) {
6004            try {
6005                watcher.asBinder().linkToDeath(dr, 0);
6006                mRotationWatchers.add(watcher);
6007            } catch (RemoteException e) {
6008                // Client died, no cleanup needed.
6009            }
6010
6011            return mRotation;
6012        }
6013    }
6014
6015    @Override
6016    public void removeRotationWatcher(IRotationWatcher watcher) {
6017        final IBinder watcherBinder = watcher.asBinder();
6018        synchronized (mWindowMap) {
6019            for (int i=0; i<mRotationWatchers.size(); i++) {
6020                if (watcherBinder == mRotationWatchers.get(i).asBinder()) {
6021                    mRotationWatchers.remove(i);
6022                    i--;
6023                }
6024            }
6025        }
6026    }
6027
6028    /**
6029     * Apps that use the compact menu panel (as controlled by the panelMenuIsCompact
6030     * theme attribute) on devices that feature a physical options menu key attempt to position
6031     * their menu panel window along the edge of the screen nearest the physical menu key.
6032     * This lowers the travel distance between invoking the menu panel and selecting
6033     * a menu option.
6034     *
6035     * This method helps control where that menu is placed. Its current implementation makes
6036     * assumptions about the menu key and its relationship to the screen based on whether
6037     * the device's natural orientation is portrait (width < height) or landscape.
6038     *
6039     * The menu key is assumed to be located along the bottom edge of natural-portrait
6040     * devices and along the right edge of natural-landscape devices. If these assumptions
6041     * do not hold for the target device, this method should be changed to reflect that.
6042     *
6043     * @return A {@link Gravity} value for placing the options menu window
6044     */
6045    @Override
6046    public int getPreferredOptionsPanelGravity() {
6047        synchronized (mWindowMap) {
6048            final int rotation = getRotation();
6049
6050            // TODO(multidisplay): Assume that such devices physical keys are on the main screen.
6051            final DisplayContent displayContent = getDefaultDisplayContentLocked();
6052            if (displayContent.mInitialDisplayWidth < displayContent.mInitialDisplayHeight) {
6053                // On devices with a natural orientation of portrait
6054                switch (rotation) {
6055                    default:
6056                    case Surface.ROTATION_0:
6057                        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6058                    case Surface.ROTATION_90:
6059                        return Gravity.RIGHT | Gravity.BOTTOM;
6060                    case Surface.ROTATION_180:
6061                        return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6062                    case Surface.ROTATION_270:
6063                        return Gravity.START | Gravity.BOTTOM;
6064                }
6065            }
6066
6067            // On devices with a natural orientation of landscape
6068            switch (rotation) {
6069                default:
6070                case Surface.ROTATION_0:
6071                    return Gravity.RIGHT | Gravity.BOTTOM;
6072                case Surface.ROTATION_90:
6073                    return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6074                case Surface.ROTATION_180:
6075                    return Gravity.START | Gravity.BOTTOM;
6076                case Surface.ROTATION_270:
6077                    return Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
6078            }
6079        }
6080    }
6081
6082    /**
6083     * Starts the view server on the specified port.
6084     *
6085     * @param port The port to listener to.
6086     *
6087     * @return True if the server was successfully started, false otherwise.
6088     *
6089     * @see com.android.server.wm.ViewServer
6090     * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
6091     */
6092    @Override
6093    public boolean startViewServer(int port) {
6094        if (isSystemSecure()) {
6095            return false;
6096        }
6097
6098        if (!checkCallingPermission(Manifest.permission.DUMP, "startViewServer")) {
6099            return false;
6100        }
6101
6102        if (port < 1024) {
6103            return false;
6104        }
6105
6106        if (mViewServer != null) {
6107            if (!mViewServer.isRunning()) {
6108                try {
6109                    return mViewServer.start();
6110                } catch (IOException e) {
6111                    Slog.w(TAG, "View server did not start");
6112                }
6113            }
6114            return false;
6115        }
6116
6117        try {
6118            mViewServer = new ViewServer(this, port);
6119            return mViewServer.start();
6120        } catch (IOException e) {
6121            Slog.w(TAG, "View server did not start");
6122        }
6123        return false;
6124    }
6125
6126    private boolean isSystemSecure() {
6127        return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
6128                "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6129    }
6130
6131    /**
6132     * Stops the view server if it exists.
6133     *
6134     * @return True if the server stopped, false if it wasn't started or
6135     *         couldn't be stopped.
6136     *
6137     * @see com.android.server.wm.ViewServer
6138     */
6139    @Override
6140    public boolean stopViewServer() {
6141        if (isSystemSecure()) {
6142            return false;
6143        }
6144
6145        if (!checkCallingPermission(Manifest.permission.DUMP, "stopViewServer")) {
6146            return false;
6147        }
6148
6149        if (mViewServer != null) {
6150            return mViewServer.stop();
6151        }
6152        return false;
6153    }
6154
6155    /**
6156     * Indicates whether the view server is running.
6157     *
6158     * @return True if the server is running, false otherwise.
6159     *
6160     * @see com.android.server.wm.ViewServer
6161     */
6162    @Override
6163    public boolean isViewServerRunning() {
6164        if (isSystemSecure()) {
6165            return false;
6166        }
6167
6168        if (!checkCallingPermission(Manifest.permission.DUMP, "isViewServerRunning")) {
6169            return false;
6170        }
6171
6172        return mViewServer != null && mViewServer.isRunning();
6173    }
6174
6175    /**
6176     * Lists all availble windows in the system. The listing is written in the
6177     * specified Socket's output stream with the following syntax:
6178     * windowHashCodeInHexadecimal windowName
6179     * Each line of the ouput represents a different window.
6180     *
6181     * @param client The remote client to send the listing to.
6182     * @return False if an error occured, true otherwise.
6183     */
6184    boolean viewServerListWindows(Socket client) {
6185        if (isSystemSecure()) {
6186            return false;
6187        }
6188
6189        boolean result = true;
6190
6191        WindowList windows = new WindowList();
6192        synchronized (mWindowMap) {
6193            //noinspection unchecked
6194            final int numDisplays = mDisplayContents.size();
6195            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6196                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
6197                windows.addAll(displayContent.getWindowList());
6198            }
6199        }
6200
6201        BufferedWriter out = null;
6202
6203        // Any uncaught exception will crash the system process
6204        try {
6205            OutputStream clientStream = client.getOutputStream();
6206            out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6207
6208            final int count = windows.size();
6209            for (int i = 0; i < count; i++) {
6210                final WindowState w = windows.get(i);
6211                out.write(Integer.toHexString(System.identityHashCode(w)));
6212                out.write(' ');
6213                out.append(w.mAttrs.getTitle());
6214                out.write('\n');
6215            }
6216
6217            out.write("DONE.\n");
6218            out.flush();
6219        } catch (Exception e) {
6220            result = false;
6221        } finally {
6222            if (out != null) {
6223                try {
6224                    out.close();
6225                } catch (IOException e) {
6226                    result = false;
6227                }
6228            }
6229        }
6230
6231        return result;
6232    }
6233
6234    // TODO(multidisplay): Extend to multiple displays.
6235    /**
6236     * Returns the focused window in the following format:
6237     * windowHashCodeInHexadecimal windowName
6238     *
6239     * @param client The remote client to send the listing to.
6240     * @return False if an error occurred, true otherwise.
6241     */
6242    boolean viewServerGetFocusedWindow(Socket client) {
6243        if (isSystemSecure()) {
6244            return false;
6245        }
6246
6247        boolean result = true;
6248
6249        WindowState focusedWindow = getFocusedWindow();
6250
6251        BufferedWriter out = null;
6252
6253        // Any uncaught exception will crash the system process
6254        try {
6255            OutputStream clientStream = client.getOutputStream();
6256            out = new BufferedWriter(new OutputStreamWriter(clientStream), 8 * 1024);
6257
6258            if(focusedWindow != null) {
6259                out.write(Integer.toHexString(System.identityHashCode(focusedWindow)));
6260                out.write(' ');
6261                out.append(focusedWindow.mAttrs.getTitle());
6262            }
6263            out.write('\n');
6264            out.flush();
6265        } catch (Exception e) {
6266            result = false;
6267        } finally {
6268            if (out != null) {
6269                try {
6270                    out.close();
6271                } catch (IOException e) {
6272                    result = false;
6273                }
6274            }
6275        }
6276
6277        return result;
6278    }
6279
6280    /**
6281     * Sends a command to a target window. The result of the command, if any, will be
6282     * written in the output stream of the specified socket.
6283     *
6284     * The parameters must follow this syntax:
6285     * windowHashcode extra
6286     *
6287     * Where XX is the length in characeters of the windowTitle.
6288     *
6289     * The first parameter is the target window. The window with the specified hashcode
6290     * will be the target. If no target can be found, nothing happens. The extra parameters
6291     * will be delivered to the target window and as parameters to the command itself.
6292     *
6293     * @param client The remote client to sent the result, if any, to.
6294     * @param command The command to execute.
6295     * @param parameters The command parameters.
6296     *
6297     * @return True if the command was successfully delivered, false otherwise. This does
6298     *         not indicate whether the command itself was successful.
6299     */
6300    boolean viewServerWindowCommand(Socket client, String command, String parameters) {
6301        if (isSystemSecure()) {
6302            return false;
6303        }
6304
6305        boolean success = true;
6306        Parcel data = null;
6307        Parcel reply = null;
6308
6309        BufferedWriter out = null;
6310
6311        // Any uncaught exception will crash the system process
6312        try {
6313            // Find the hashcode of the window
6314            int index = parameters.indexOf(' ');
6315            if (index == -1) {
6316                index = parameters.length();
6317            }
6318            final String code = parameters.substring(0, index);
6319            int hashCode = (int) Long.parseLong(code, 16);
6320
6321            // Extract the command's parameter after the window description
6322            if (index < parameters.length()) {
6323                parameters = parameters.substring(index + 1);
6324            } else {
6325                parameters = "";
6326            }
6327
6328            final WindowState window = findWindow(hashCode);
6329            if (window == null) {
6330                return false;
6331            }
6332
6333            data = Parcel.obtain();
6334            data.writeInterfaceToken("android.view.IWindow");
6335            data.writeString(command);
6336            data.writeString(parameters);
6337            data.writeInt(1);
6338            ParcelFileDescriptor.fromSocket(client).writeToParcel(data, 0);
6339
6340            reply = Parcel.obtain();
6341
6342            final IBinder binder = window.mClient.asBinder();
6343            // TODO: GET THE TRANSACTION CODE IN A SAFER MANNER
6344            binder.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
6345
6346            reply.readException();
6347
6348            if (!client.isOutputShutdown()) {
6349                out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
6350                out.write("DONE\n");
6351                out.flush();
6352            }
6353
6354        } catch (Exception e) {
6355            Slog.w(TAG, "Could not send command " + command + " with parameters " + parameters, e);
6356            success = false;
6357        } finally {
6358            if (data != null) {
6359                data.recycle();
6360            }
6361            if (reply != null) {
6362                reply.recycle();
6363            }
6364            if (out != null) {
6365                try {
6366                    out.close();
6367                } catch (IOException e) {
6368
6369                }
6370            }
6371        }
6372
6373        return success;
6374    }
6375
6376    public void addWindowChangeListener(WindowChangeListener listener) {
6377        synchronized(mWindowMap) {
6378            mWindowChangeListeners.add(listener);
6379        }
6380    }
6381
6382    public void removeWindowChangeListener(WindowChangeListener listener) {
6383        synchronized(mWindowMap) {
6384            mWindowChangeListeners.remove(listener);
6385        }
6386    }
6387
6388    private void notifyWindowsChanged() {
6389        WindowChangeListener[] windowChangeListeners;
6390        synchronized(mWindowMap) {
6391            if(mWindowChangeListeners.isEmpty()) {
6392                return;
6393            }
6394            windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6395            windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6396        }
6397        int N = windowChangeListeners.length;
6398        for(int i = 0; i < N; i++) {
6399            windowChangeListeners[i].windowsChanged();
6400        }
6401    }
6402
6403    private void notifyFocusChanged() {
6404        WindowChangeListener[] windowChangeListeners;
6405        synchronized(mWindowMap) {
6406            if(mWindowChangeListeners.isEmpty()) {
6407                return;
6408            }
6409            windowChangeListeners = new WindowChangeListener[mWindowChangeListeners.size()];
6410            windowChangeListeners = mWindowChangeListeners.toArray(windowChangeListeners);
6411        }
6412        int N = windowChangeListeners.length;
6413        for(int i = 0; i < N; i++) {
6414            windowChangeListeners[i].focusChanged();
6415        }
6416    }
6417
6418    private WindowState findWindow(int hashCode) {
6419        if (hashCode == -1) {
6420            // TODO(multidisplay): Extend to multiple displays.
6421            return getFocusedWindow();
6422        }
6423
6424        synchronized (mWindowMap) {
6425            final int numDisplays = mDisplayContents.size();
6426            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6427                final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6428                final int numWindows = windows.size();
6429                for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6430                    final WindowState w = windows.get(winNdx);
6431                    if (System.identityHashCode(w) == hashCode) {
6432                        return w;
6433                    }
6434                }
6435            }
6436        }
6437
6438        return null;
6439    }
6440
6441    /*
6442     * Instruct the Activity Manager to fetch the current configuration and broadcast
6443     * that to config-changed listeners if appropriate.
6444     */
6445    void sendNewConfiguration() {
6446        try {
6447            mActivityManager.updateConfiguration(null);
6448        } catch (RemoteException e) {
6449        }
6450    }
6451
6452    public Configuration computeNewConfiguration() {
6453        synchronized (mWindowMap) {
6454            Configuration config = computeNewConfigurationLocked();
6455            if (config == null && mWaitingForConfig) {
6456                // Nothing changed but we are waiting for something... stop that!
6457                mWaitingForConfig = false;
6458                mLastFinishedFreezeSource = "new-config";
6459                performLayoutAndPlaceSurfacesLocked();
6460            }
6461            return config;
6462        }
6463    }
6464
6465    Configuration computeNewConfigurationLocked() {
6466        Configuration config = new Configuration();
6467        config.fontScale = 0;
6468        if (!computeScreenConfigurationLocked(config)) {
6469            return null;
6470        }
6471        return config;
6472    }
6473
6474    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
6475        // TODO: Multidisplay: for now only use with default display.
6476        final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
6477        if (width < displayInfo.smallestNominalAppWidth) {
6478            displayInfo.smallestNominalAppWidth = width;
6479        }
6480        if (width > displayInfo.largestNominalAppWidth) {
6481            displayInfo.largestNominalAppWidth = width;
6482        }
6483        final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
6484        if (height < displayInfo.smallestNominalAppHeight) {
6485            displayInfo.smallestNominalAppHeight = height;
6486        }
6487        if (height > displayInfo.largestNominalAppHeight) {
6488            displayInfo.largestNominalAppHeight = height;
6489        }
6490    }
6491
6492    private int reduceConfigLayout(int curLayout, int rotation, float density,
6493            int dw, int dh) {
6494        // TODO: Multidisplay: for now only use with default display.
6495        // Get the app screen size at this rotation.
6496        int w = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6497        int h = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6498
6499        // Compute the screen layout size class for this rotation.
6500        int longSize = w;
6501        int shortSize = h;
6502        if (longSize < shortSize) {
6503            int tmp = longSize;
6504            longSize = shortSize;
6505            shortSize = tmp;
6506        }
6507        longSize = (int)(longSize/density);
6508        shortSize = (int)(shortSize/density);
6509        return Configuration.reduceScreenLayout(curLayout, longSize, shortSize);
6510    }
6511
6512    private void computeSizeRangesAndScreenLayout(DisplayInfo displayInfo, boolean rotated,
6513                  int dw, int dh, float density, Configuration outConfig) {
6514        // TODO: Multidisplay: for now only use with default display.
6515
6516        // We need to determine the smallest width that will occur under normal
6517        // operation.  To this, start with the base screen size and compute the
6518        // width under the different possible rotations.  We need to un-rotate
6519        // the current screen dimensions before doing this.
6520        int unrotDw, unrotDh;
6521        if (rotated) {
6522            unrotDw = dh;
6523            unrotDh = dw;
6524        } else {
6525            unrotDw = dw;
6526            unrotDh = dh;
6527        }
6528        displayInfo.smallestNominalAppWidth = 1<<30;
6529        displayInfo.smallestNominalAppHeight = 1<<30;
6530        displayInfo.largestNominalAppWidth = 0;
6531        displayInfo.largestNominalAppHeight = 0;
6532        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
6533        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
6534        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
6535        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
6536        int sl = Configuration.resetScreenLayout(outConfig.screenLayout);
6537        sl = reduceConfigLayout(sl, Surface.ROTATION_0, density, unrotDw, unrotDh);
6538        sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
6539        sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
6540        sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
6541        outConfig.smallestScreenWidthDp = (int)(displayInfo.smallestNominalAppWidth / density);
6542        outConfig.screenLayout = sl;
6543    }
6544
6545    private int reduceCompatConfigWidthSize(int curSize, int rotation, DisplayMetrics dm,
6546            int dw, int dh) {
6547        // TODO: Multidisplay: for now only use with default display.
6548        dm.noncompatWidthPixels = mPolicy.getNonDecorDisplayWidth(dw, dh, rotation);
6549        dm.noncompatHeightPixels = mPolicy.getNonDecorDisplayHeight(dw, dh, rotation);
6550        float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
6551        int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
6552        if (curSize == 0 || size < curSize) {
6553            curSize = size;
6554        }
6555        return curSize;
6556    }
6557
6558    private int computeCompatSmallestWidth(boolean rotated, DisplayMetrics dm, int dw, int dh) {
6559        // TODO: Multidisplay: for now only use with default display.
6560        mTmpDisplayMetrics.setTo(dm);
6561        final DisplayMetrics tmpDm = mTmpDisplayMetrics;
6562        final int unrotDw, unrotDh;
6563        if (rotated) {
6564            unrotDw = dh;
6565            unrotDh = dw;
6566        } else {
6567            unrotDw = dw;
6568            unrotDh = dh;
6569        }
6570        int sw = reduceCompatConfigWidthSize(0, Surface.ROTATION_0, tmpDm, unrotDw, unrotDh);
6571        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_90, tmpDm, unrotDh, unrotDw);
6572        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_180, tmpDm, unrotDw, unrotDh);
6573        sw = reduceCompatConfigWidthSize(sw, Surface.ROTATION_270, tmpDm, unrotDh, unrotDw);
6574        return sw;
6575    }
6576
6577    boolean computeScreenConfigurationLocked(Configuration config) {
6578        if (!mDisplayReady) {
6579            return false;
6580        }
6581
6582        // TODO(multidisplay): For now, apply Configuration to main screen only.
6583        final DisplayContent displayContent = getDefaultDisplayContentLocked();
6584
6585        // Use the effective "visual" dimensions based on current rotation
6586        final boolean rotated = (mRotation == Surface.ROTATION_90
6587                || mRotation == Surface.ROTATION_270);
6588        final int realdw = rotated ?
6589                displayContent.mBaseDisplayHeight : displayContent.mBaseDisplayWidth;
6590        final int realdh = rotated ?
6591                displayContent.mBaseDisplayWidth : displayContent.mBaseDisplayHeight;
6592        int dw = realdw;
6593        int dh = realdh;
6594
6595        if (mAltOrientation) {
6596            if (realdw > realdh) {
6597                // Turn landscape into portrait.
6598                int maxw = (int)(realdh/1.3f);
6599                if (maxw < realdw) {
6600                    dw = maxw;
6601                }
6602            } else {
6603                // Turn portrait into landscape.
6604                int maxh = (int)(realdw/1.3f);
6605                if (maxh < realdh) {
6606                    dh = maxh;
6607                }
6608            }
6609        }
6610
6611        if (config != null) {
6612            config.orientation = (dw <= dh) ? Configuration.ORIENTATION_PORTRAIT :
6613                    Configuration.ORIENTATION_LANDSCAPE;
6614        }
6615
6616        // Update application display metrics.
6617        final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
6618        final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
6619        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6620        synchronized(displayContent.mDisplaySizeLock) {
6621            displayInfo.rotation = mRotation;
6622            displayInfo.logicalWidth = dw;
6623            displayInfo.logicalHeight = dh;
6624            displayInfo.logicalDensityDpi = displayContent.mBaseDisplayDensity;
6625            displayInfo.appWidth = appWidth;
6626            displayInfo.appHeight = appHeight;
6627            displayInfo.getLogicalMetrics(mRealDisplayMetrics,
6628                    CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
6629            displayInfo.getAppMetrics(mDisplayMetrics);
6630            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
6631                    displayContent.getDisplayId(), displayInfo);
6632        }
6633        if (false) {
6634            Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
6635        }
6636
6637        final DisplayMetrics dm = mDisplayMetrics;
6638        mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
6639                mCompatDisplayMetrics);
6640
6641        if (config != null) {
6642            config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation)
6643                    / dm.density);
6644            config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation)
6645                    / dm.density);
6646            computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, dm.density, config);
6647
6648            config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
6649            config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
6650            config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh);
6651            config.densityDpi = displayContent.mBaseDisplayDensity;
6652
6653            // Update the configuration based on available input devices, lid switch,
6654            // and platform configuration.
6655            config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6656            config.keyboard = Configuration.KEYBOARD_NOKEYS;
6657            config.navigation = Configuration.NAVIGATION_NONAV;
6658
6659            int keyboardPresence = 0;
6660            int navigationPresence = 0;
6661            final InputDevice[] devices = mInputManager.getInputDevices();
6662            final int len = devices.length;
6663            for (int i = 0; i < len; i++) {
6664                InputDevice device = devices[i];
6665                if (!device.isVirtual()) {
6666                    final int sources = device.getSources();
6667                    final int presenceFlag = device.isExternal() ?
6668                            WindowManagerPolicy.PRESENCE_EXTERNAL :
6669                                    WindowManagerPolicy.PRESENCE_INTERNAL;
6670
6671                    if (mIsTouchDevice) {
6672                        if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
6673                                InputDevice.SOURCE_TOUCHSCREEN) {
6674                            config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
6675                        }
6676                    } else {
6677                        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
6678                    }
6679
6680                    if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
6681                        config.navigation = Configuration.NAVIGATION_TRACKBALL;
6682                        navigationPresence |= presenceFlag;
6683                    } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
6684                            && config.navigation == Configuration.NAVIGATION_NONAV) {
6685                        config.navigation = Configuration.NAVIGATION_DPAD;
6686                        navigationPresence |= presenceFlag;
6687                    }
6688
6689                    if (device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
6690                        config.keyboard = Configuration.KEYBOARD_QWERTY;
6691                        keyboardPresence |= presenceFlag;
6692                    }
6693                }
6694            }
6695
6696            // Determine whether a hard keyboard is available and enabled.
6697            boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS;
6698            if (hardKeyboardAvailable != mHardKeyboardAvailable) {
6699                mHardKeyboardAvailable = hardKeyboardAvailable;
6700                mHardKeyboardEnabled = hardKeyboardAvailable;
6701                mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6702                mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE);
6703            }
6704            if (!mHardKeyboardEnabled) {
6705                config.keyboard = Configuration.KEYBOARD_NOKEYS;
6706            }
6707
6708            // Let the policy update hidden states.
6709            config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO;
6710            config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO;
6711            config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO;
6712            mPolicy.adjustConfigurationLw(config, keyboardPresence, navigationPresence);
6713        }
6714
6715        return true;
6716    }
6717
6718    public boolean isHardKeyboardAvailable() {
6719        synchronized (mWindowMap) {
6720            return mHardKeyboardAvailable;
6721        }
6722    }
6723
6724    public boolean isHardKeyboardEnabled() {
6725        synchronized (mWindowMap) {
6726            return mHardKeyboardEnabled;
6727        }
6728    }
6729
6730    public void setHardKeyboardEnabled(boolean enabled) {
6731        synchronized (mWindowMap) {
6732            if (mHardKeyboardEnabled != enabled) {
6733                mHardKeyboardEnabled = enabled;
6734                mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
6735            }
6736        }
6737    }
6738
6739    public void setOnHardKeyboardStatusChangeListener(
6740            OnHardKeyboardStatusChangeListener listener) {
6741        synchronized (mWindowMap) {
6742            mHardKeyboardStatusChangeListener = listener;
6743        }
6744    }
6745
6746    void notifyHardKeyboardStatusChange() {
6747        final boolean available, enabled;
6748        final OnHardKeyboardStatusChangeListener listener;
6749        synchronized (mWindowMap) {
6750            listener = mHardKeyboardStatusChangeListener;
6751            available = mHardKeyboardAvailable;
6752            enabled = mHardKeyboardEnabled;
6753        }
6754        if (listener != null) {
6755            listener.onHardKeyboardStatusChange(available, enabled);
6756        }
6757    }
6758
6759    // -------------------------------------------------------------
6760    // Drag and drop
6761    // -------------------------------------------------------------
6762
6763    IBinder prepareDragSurface(IWindow window, SurfaceSession session,
6764            int flags, int width, int height, Surface outSurface) {
6765        if (DEBUG_DRAG) {
6766            Slog.d(TAG, "prepare drag surface: w=" + width + " h=" + height
6767                    + " flags=" + Integer.toHexString(flags) + " win=" + window
6768                    + " asbinder=" + window.asBinder());
6769        }
6770
6771        final int callerPid = Binder.getCallingPid();
6772        final long origId = Binder.clearCallingIdentity();
6773        IBinder token = null;
6774
6775        try {
6776            synchronized (mWindowMap) {
6777                try {
6778                    if (mDragState == null) {
6779                        // TODO(multi-display): support other displays
6780                        final DisplayContent displayContent = getDefaultDisplayContentLocked();
6781                        final Display display = displayContent.getDisplay();
6782                        SurfaceControl surface = new SurfaceControl(session, "drag surface",
6783                                width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
6784                        surface.setLayerStack(display.getLayerStack());
6785                        if (SHOW_TRANSACTIONS) Slog.i(TAG, "  DRAG "
6786                                + surface + ": CREATE");
6787                        outSurface.copyFrom(surface);
6788                        final IBinder winBinder = window.asBinder();
6789                        token = new Binder();
6790                        mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
6791                        token = mDragState.mToken = new Binder();
6792
6793                        // 5 second timeout for this window to actually begin the drag
6794                        mH.removeMessages(H.DRAG_START_TIMEOUT, winBinder);
6795                        Message msg = mH.obtainMessage(H.DRAG_START_TIMEOUT, winBinder);
6796                        mH.sendMessageDelayed(msg, 5000);
6797                    } else {
6798                        Slog.w(TAG, "Drag already in progress");
6799                    }
6800                } catch (OutOfResourcesException e) {
6801                    Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e);
6802                    if (mDragState != null) {
6803                        mDragState.reset();
6804                        mDragState = null;
6805                    }
6806                }
6807            }
6808        } finally {
6809            Binder.restoreCallingIdentity(origId);
6810        }
6811
6812        return token;
6813    }
6814
6815    // -------------------------------------------------------------
6816    // Input Events and Focus Management
6817    // -------------------------------------------------------------
6818
6819    final InputMonitor mInputMonitor = new InputMonitor(this);
6820    private boolean mEventDispatchingEnabled;
6821
6822    @Override
6823    public void pauseKeyDispatching(IBinder _token) {
6824        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6825                "pauseKeyDispatching()")) {
6826            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
6827        }
6828
6829        synchronized (mWindowMap) {
6830            WindowToken token = mTokenMap.get(_token);
6831            if (token != null) {
6832                mInputMonitor.pauseDispatchingLw(token);
6833            }
6834        }
6835    }
6836
6837    @Override
6838    public void resumeKeyDispatching(IBinder _token) {
6839        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6840                "resumeKeyDispatching()")) {
6841            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
6842        }
6843
6844        synchronized (mWindowMap) {
6845            WindowToken token = mTokenMap.get(_token);
6846            if (token != null) {
6847                mInputMonitor.resumeDispatchingLw(token);
6848            }
6849        }
6850    }
6851
6852    @Override
6853    public void setEventDispatching(boolean enabled) {
6854        if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
6855                "setEventDispatching()")) {
6856            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
6857        }
6858
6859        synchronized (mWindowMap) {
6860            mEventDispatchingEnabled = enabled;
6861            if (mDisplayEnabled) {
6862                mInputMonitor.setEventDispatchingLw(enabled);
6863            }
6864            sendScreenStatusToClientsLocked();
6865        }
6866    }
6867
6868    @Override
6869    public IBinder getFocusedWindowToken() {
6870        if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
6871                "getFocusedWindowToken()")) {
6872            throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
6873        }
6874        synchronized (mWindowMap) {
6875            WindowState windowState = getFocusedWindowLocked();
6876            if (windowState != null) {
6877                return windowState.mClient.asBinder();
6878            }
6879            return null;
6880        }
6881    }
6882
6883    private WindowState getFocusedWindow() {
6884        synchronized (mWindowMap) {
6885            return getFocusedWindowLocked();
6886        }
6887    }
6888
6889    private WindowState getFocusedWindowLocked() {
6890        return mCurrentFocus;
6891    }
6892
6893    public boolean detectSafeMode() {
6894        if (!mInputMonitor.waitForInputDevicesReady(
6895                INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
6896            Slog.w(TAG, "Devices still not ready after waiting "
6897                   + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
6898                   + " milliseconds before attempting to detect safe mode.");
6899        }
6900
6901        int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6902                KeyEvent.KEYCODE_MENU);
6903        int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
6904        int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
6905                KeyEvent.KEYCODE_DPAD_CENTER);
6906        int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
6907                InputManagerService.BTN_MOUSE);
6908        int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
6909                KeyEvent.KEYCODE_VOLUME_DOWN);
6910        mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
6911                || volumeDownState > 0;
6912        try {
6913            if (SystemProperties.getInt(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, 0) != 0) {
6914                mSafeMode = true;
6915                SystemProperties.set(ShutdownThread.REBOOT_SAFEMODE_PROPERTY, "");
6916            }
6917        } catch (IllegalArgumentException e) {
6918        }
6919        if (mSafeMode) {
6920            Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
6921                    + " dpad=" + dpadState + " trackball=" + trackballState + ")");
6922        } else {
6923            Log.i(TAG, "SAFE MODE not enabled");
6924        }
6925        mPolicy.setSafeMode(mSafeMode);
6926        return mSafeMode;
6927    }
6928
6929    public void displayReady() {
6930        displayReady(Display.DEFAULT_DISPLAY);
6931
6932        synchronized(mWindowMap) {
6933            final DisplayContent displayContent = getDefaultDisplayContentLocked();
6934            readForcedDisplaySizeAndDensityLocked(displayContent);
6935            mDisplayReady = true;
6936        }
6937
6938        try {
6939            mActivityManager.updateConfiguration(null);
6940        } catch (RemoteException e) {
6941        }
6942
6943        synchronized(mWindowMap) {
6944            mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
6945                    PackageManager.FEATURE_TOUCHSCREEN);
6946            configureDisplayPolicyLocked(getDefaultDisplayContentLocked());
6947        }
6948
6949        try {
6950            mActivityManager.updateConfiguration(null);
6951        } catch (RemoteException e) {
6952        }
6953    }
6954
6955    private void displayReady(int displayId) {
6956        synchronized(mWindowMap) {
6957            final DisplayContent displayContent = getDisplayContentLocked(displayId);
6958            if (displayContent != null) {
6959                mAnimator.addDisplayLocked(displayId);
6960                synchronized(displayContent.mDisplaySizeLock) {
6961                    // Bootstrap the default logical display from the display manager.
6962                    final DisplayInfo displayInfo = displayContent.getDisplayInfo();
6963                    DisplayInfo newDisplayInfo = mDisplayManagerService.getDisplayInfo(displayId);
6964                    if (newDisplayInfo != null) {
6965                        displayInfo.copyFrom(newDisplayInfo);
6966                    }
6967                    displayContent.mInitialDisplayWidth = displayInfo.logicalWidth;
6968                    displayContent.mInitialDisplayHeight = displayInfo.logicalHeight;
6969                    displayContent.mInitialDisplayDensity = displayInfo.logicalDensityDpi;
6970                    displayContent.mBaseDisplayWidth = displayContent.mInitialDisplayWidth;
6971                    displayContent.mBaseDisplayHeight = displayContent.mInitialDisplayHeight;
6972                    displayContent.mBaseDisplayDensity = displayContent.mInitialDisplayDensity;
6973                    displayContent.mBaseDisplayRect.set(0, 0,
6974                            displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight);
6975                }
6976            }
6977        }
6978    }
6979
6980    public void systemReady() {
6981        mPolicy.systemReady();
6982    }
6983
6984    // TODO(multidisplay): Call isScreenOn for each display.
6985    private void sendScreenStatusToClientsLocked() {
6986        final boolean on = mPowerManager.isScreenOn();
6987        final int numDisplays = mDisplayContents.size();
6988        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
6989            final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
6990            final int numWindows = windows.size();
6991            for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
6992                try {
6993                    windows.get(winNdx).mClient.dispatchScreenState(on);
6994                } catch (RemoteException e) {
6995                    // Ignored
6996                }
6997            }
6998        }
6999    }
7000
7001    // -------------------------------------------------------------
7002    // Async Handler
7003    // -------------------------------------------------------------
7004
7005    final class H extends Handler {
7006        public static final int REPORT_FOCUS_CHANGE = 2;
7007        public static final int REPORT_LOSING_FOCUS = 3;
7008        public static final int DO_TRAVERSAL = 4;
7009        public static final int ADD_STARTING = 5;
7010        public static final int REMOVE_STARTING = 6;
7011        public static final int FINISHED_STARTING = 7;
7012        public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
7013        public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
7014        public static final int WINDOW_FREEZE_TIMEOUT = 11;
7015
7016        public static final int APP_TRANSITION_TIMEOUT = 13;
7017        public static final int PERSIST_ANIMATION_SCALE = 14;
7018        public static final int FORCE_GC = 15;
7019        public static final int ENABLE_SCREEN = 16;
7020        public static final int APP_FREEZE_TIMEOUT = 17;
7021        public static final int SEND_NEW_CONFIGURATION = 18;
7022        public static final int REPORT_WINDOWS_CHANGE = 19;
7023        public static final int DRAG_START_TIMEOUT = 20;
7024        public static final int DRAG_END_TIMEOUT = 21;
7025        public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
7026        public static final int BOOT_TIMEOUT = 23;
7027        public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
7028        public static final int SHOW_STRICT_MODE_VIOLATION = 25;
7029        public static final int DO_ANIMATION_CALLBACK = 26;
7030
7031        public static final int DO_DISPLAY_ADDED = 27;
7032        public static final int DO_DISPLAY_REMOVED = 28;
7033        public static final int DO_DISPLAY_CHANGED = 29;
7034
7035        public static final int CLIENT_FREEZE_TIMEOUT = 30;
7036        public static final int TAP_OUTSIDE_STACK = 31;
7037        public static final int NOTIFY_ACTIVITY_DRAWN = 32;
7038
7039        public static final int REMOVE_STARTING_TIMEOUT = 33;
7040
7041        @Override
7042        public void handleMessage(Message msg) {
7043            if (DEBUG_WINDOW_TRACE) {
7044                Slog.v(TAG, "handleMessage: entry what=" + msg.what);
7045            }
7046            switch (msg.what) {
7047                case REPORT_FOCUS_CHANGE: {
7048                    WindowState lastFocus;
7049                    WindowState newFocus;
7050
7051                    synchronized(mWindowMap) {
7052                        lastFocus = mLastFocus;
7053                        newFocus = mCurrentFocus;
7054                        if (lastFocus == newFocus) {
7055                            // Focus is not changing, so nothing to do.
7056                            return;
7057                        }
7058                        mLastFocus = newFocus;
7059                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Focus moving from " + lastFocus +
7060                                " to " + newFocus);
7061                        if (newFocus != null && lastFocus != null
7062                                && !newFocus.isDisplayedLw()) {
7063                            //Slog.i(TAG, "Delaying loss of focus...");
7064                            mLosingFocus.add(lastFocus);
7065                            lastFocus = null;
7066                        }
7067                    }
7068
7069                    //System.out.println("Changing focus from " + lastFocus
7070                    //                   + " to " + newFocus);
7071                    if (newFocus != null) {
7072                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Gaining focus: " + newFocus);
7073                        newFocus.reportFocusChangedSerialized(true, mInTouchMode);
7074                        notifyFocusChanged();
7075                    }
7076
7077                    if (lastFocus != null) {
7078                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing focus: " + lastFocus);
7079                        lastFocus.reportFocusChangedSerialized(false, mInTouchMode);
7080                    }
7081                } break;
7082
7083                case REPORT_LOSING_FOCUS: {
7084                    ArrayList<WindowState> losers;
7085
7086                    synchronized(mWindowMap) {
7087                        losers = mLosingFocus;
7088                        mLosingFocus = new ArrayList<WindowState>();
7089                    }
7090
7091                    final int N = losers.size();
7092                    for (int i=0; i<N; i++) {
7093                        if (DEBUG_FOCUS_LIGHT) Slog.i(TAG, "Losing delayed focus: " +
7094                                losers.get(i));
7095                        losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
7096                    }
7097                } break;
7098
7099                case DO_TRAVERSAL: {
7100                    synchronized(mWindowMap) {
7101                        mTraversalScheduled = false;
7102                        performLayoutAndPlaceSurfacesLocked();
7103                    }
7104                } break;
7105
7106                case ADD_STARTING: {
7107                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7108                    final StartingData sd = wtoken.startingData;
7109
7110                    if (sd == null) {
7111                        // Animation has been canceled... do nothing.
7112                        return;
7113                    }
7114
7115                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Add starting "
7116                            + wtoken + ": pkg=" + sd.pkg);
7117
7118                    View view = null;
7119                    try {
7120                        view = mPolicy.addStartingWindow(
7121                            wtoken.token, sd.pkg, sd.theme, sd.compatInfo,
7122                            sd.nonLocalizedLabel, sd.labelRes, sd.icon, sd.logo, sd.windowFlags);
7123                    } catch (Exception e) {
7124                        Slog.w(TAG, "Exception when adding starting window", e);
7125                    }
7126
7127                    if (view != null) {
7128                        boolean abort = false;
7129
7130                        synchronized(mWindowMap) {
7131                            if (wtoken.removed || wtoken.startingData == null) {
7132                                // If the window was successfully added, then
7133                                // we need to remove it.
7134                                if (wtoken.startingWindow != null) {
7135                                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
7136                                            "Aborted starting " + wtoken
7137                                            + ": removed=" + wtoken.removed
7138                                            + " startingData=" + wtoken.startingData);
7139                                    removeStartingWindowTimeout(wtoken);
7140                                    wtoken.startingWindow = null;
7141                                    wtoken.startingData = null;
7142                                    abort = true;
7143                                }
7144                            } else {
7145                                wtoken.startingView = view;
7146                            }
7147                            if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG,
7148                                    "Added starting " + wtoken
7149                                    + ": startingWindow="
7150                                    + wtoken.startingWindow + " startingView="
7151                                    + wtoken.startingView);
7152                        }
7153
7154                        if (abort) {
7155                            try {
7156                                mPolicy.removeStartingWindow(wtoken.token, view);
7157                            } catch (Exception e) {
7158                                Slog.w(TAG, "Exception when removing starting window", e);
7159                            }
7160                        }
7161                    }
7162                } break;
7163
7164                case REMOVE_STARTING_TIMEOUT: {
7165                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7166                    Slog.e(TAG, "Starting window " + wtoken + " timed out");
7167                    // Fall through.
7168                }
7169                case REMOVE_STARTING: {
7170                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7171                    IBinder token = null;
7172                    View view = null;
7173                    synchronized (mWindowMap) {
7174                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Remove starting "
7175                                + wtoken + ": startingWindow="
7176                                + wtoken.startingWindow + " startingView="
7177                                + wtoken.startingView);
7178                        if (wtoken.startingWindow != null) {
7179                            view = wtoken.startingView;
7180                            token = wtoken.token;
7181                            wtoken.startingData = null;
7182                            wtoken.startingView = null;
7183                            wtoken.startingWindow = null;
7184                            wtoken.startingDisplayed = false;
7185                        }
7186                    }
7187                    if (view != null) {
7188                        try {
7189                            mPolicy.removeStartingWindow(token, view);
7190                        } catch (Exception e) {
7191                            Slog.w(TAG, "Exception when removing starting window", e);
7192                        }
7193                    }
7194                } break;
7195
7196                case FINISHED_STARTING: {
7197                    IBinder token = null;
7198                    View view = null;
7199                    while (true) {
7200                        synchronized (mWindowMap) {
7201                            final int N = mFinishedStarting.size();
7202                            if (N <= 0) {
7203                                break;
7204                            }
7205                            AppWindowToken wtoken = mFinishedStarting.remove(N-1);
7206
7207                            if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
7208                                    "Finished starting " + wtoken
7209                                    + ": startingWindow=" + wtoken.startingWindow
7210                                    + " startingView=" + wtoken.startingView);
7211
7212                            if (wtoken.startingWindow == null) {
7213                                continue;
7214                            }
7215
7216                            view = wtoken.startingView;
7217                            token = wtoken.token;
7218                            wtoken.startingData = null;
7219                            wtoken.startingView = null;
7220                            wtoken.startingWindow = null;
7221                            wtoken.startingDisplayed = false;
7222                        }
7223
7224                        try {
7225                            mPolicy.removeStartingWindow(token, view);
7226                        } catch (Exception e) {
7227                            Slog.w(TAG, "Exception when removing starting window", e);
7228                        }
7229                    }
7230                } break;
7231
7232                case REPORT_APPLICATION_TOKEN_DRAWN: {
7233                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7234
7235                    try {
7236                        if (DEBUG_VISIBILITY) Slog.v(
7237                                TAG, "Reporting drawn in " + wtoken);
7238                        wtoken.appToken.windowsDrawn();
7239                    } catch (RemoteException ex) {
7240                    }
7241                } break;
7242
7243                case REPORT_APPLICATION_TOKEN_WINDOWS: {
7244                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
7245
7246                    boolean nowVisible = msg.arg1 != 0;
7247                    boolean nowGone = msg.arg2 != 0;
7248
7249                    try {
7250                        if (DEBUG_VISIBILITY) Slog.v(
7251                                TAG, "Reporting visible in " + wtoken
7252                                + " visible=" + nowVisible
7253                                + " gone=" + nowGone);
7254                        if (nowVisible) {
7255                            wtoken.appToken.windowsVisible();
7256                        } else {
7257                            wtoken.appToken.windowsGone();
7258                        }
7259                    } catch (RemoteException ex) {
7260                    }
7261                } break;
7262
7263                case WINDOW_FREEZE_TIMEOUT: {
7264                    // TODO(multidisplay): Can non-default displays rotate?
7265                    synchronized (mWindowMap) {
7266                        Slog.w(TAG, "Window freeze timeout expired.");
7267                        final WindowList windows = getDefaultWindowListLocked();
7268                        int i = windows.size();
7269                        while (i > 0) {
7270                            i--;
7271                            WindowState w = windows.get(i);
7272                            if (w.mOrientationChanging) {
7273                                w.mOrientationChanging = false;
7274                                w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
7275                                        - mDisplayFreezeTime);
7276                                Slog.w(TAG, "Force clearing orientation change: " + w);
7277                            }
7278                        }
7279                        performLayoutAndPlaceSurfacesLocked();
7280                    }
7281                    break;
7282                }
7283
7284                case APP_TRANSITION_TIMEOUT: {
7285                    synchronized (mWindowMap) {
7286                        if (mAppTransition.isTransitionSet()) {
7287                            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** APP TRANSITION TIMEOUT");
7288                            mAppTransition.setTimeout();
7289                            performLayoutAndPlaceSurfacesLocked();
7290                        }
7291                    }
7292                    break;
7293                }
7294
7295                case PERSIST_ANIMATION_SCALE: {
7296                    Settings.Global.putFloat(mContext.getContentResolver(),
7297                            Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
7298                    Settings.Global.putFloat(mContext.getContentResolver(),
7299                            Settings.Global.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
7300                    Settings.Global.putFloat(mContext.getContentResolver(),
7301                            Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScale);
7302                    break;
7303                }
7304
7305                case FORCE_GC: {
7306                    synchronized (mWindowMap) {
7307                        // Since we're holding both mWindowMap and mAnimator we don't need to
7308                        // hold mAnimator.mLayoutToAnim.
7309                        if (mAnimator.mAnimating || mAnimationScheduled) {
7310                            // If we are animating, don't do the gc now but
7311                            // delay a bit so we don't interrupt the animation.
7312                            sendEmptyMessageDelayed(H.FORCE_GC, 2000);
7313                            return;
7314                        }
7315                        // If we are currently rotating the display, it will
7316                        // schedule a new message when done.
7317                        if (mDisplayFrozen) {
7318                            return;
7319                        }
7320                    }
7321                    Runtime.getRuntime().gc();
7322                    break;
7323                }
7324
7325                case ENABLE_SCREEN: {
7326                    performEnableScreen();
7327                    break;
7328                }
7329
7330                case APP_FREEZE_TIMEOUT: {
7331                    synchronized (mWindowMap) {
7332                        Slog.w(TAG, "App freeze timeout expired.");
7333                        DisplayContent displayContent = getDefaultDisplayContentLocked();
7334                        final ArrayList<Task> tasks = displayContent.getTasks();
7335                        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
7336                            AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
7337                            for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
7338                                AppWindowToken tok = tokens.get(tokenNdx);
7339                                if (tok.mAppAnimator.freezingScreen) {
7340                                    Slog.w(TAG, "Force clearing freeze: " + tok);
7341                                    unsetAppFreezingScreenLocked(tok, true, true);
7342                                }
7343                            }
7344                        }
7345                    }
7346                    break;
7347                }
7348
7349                case CLIENT_FREEZE_TIMEOUT: {
7350                    synchronized (mWindowMap) {
7351                        if (mClientFreezingScreen) {
7352                            mClientFreezingScreen = false;
7353                            mLastFinishedFreezeSource = "client-timeout";
7354                            stopFreezingDisplayLocked();
7355                        }
7356                    }
7357                    break;
7358                }
7359
7360                case SEND_NEW_CONFIGURATION: {
7361                    removeMessages(SEND_NEW_CONFIGURATION);
7362                    sendNewConfiguration();
7363                    break;
7364                }
7365
7366                case REPORT_WINDOWS_CHANGE: {
7367                    if (mWindowsChanged) {
7368                        synchronized (mWindowMap) {
7369                            mWindowsChanged = false;
7370                        }
7371                        notifyWindowsChanged();
7372                    }
7373                    break;
7374                }
7375
7376                case DRAG_START_TIMEOUT: {
7377                    IBinder win = (IBinder)msg.obj;
7378                    if (DEBUG_DRAG) {
7379                        Slog.w(TAG, "Timeout starting drag by win " + win);
7380                    }
7381                    synchronized (mWindowMap) {
7382                        // !!! TODO: ANR the app that has failed to start the drag in time
7383                        if (mDragState != null) {
7384                            mDragState.unregister();
7385                            mInputMonitor.updateInputWindowsLw(true /*force*/);
7386                            mDragState.reset();
7387                            mDragState = null;
7388                        }
7389                    }
7390                    break;
7391                }
7392
7393                case DRAG_END_TIMEOUT: {
7394                    IBinder win = (IBinder)msg.obj;
7395                    if (DEBUG_DRAG) {
7396                        Slog.w(TAG, "Timeout ending drag to win " + win);
7397                    }
7398                    synchronized (mWindowMap) {
7399                        // !!! TODO: ANR the drag-receiving app
7400                        if (mDragState != null) {
7401                            mDragState.mDragResult = false;
7402                            mDragState.endDragLw();
7403                        }
7404                    }
7405                    break;
7406                }
7407
7408                case REPORT_HARD_KEYBOARD_STATUS_CHANGE: {
7409                    notifyHardKeyboardStatusChange();
7410                    break;
7411                }
7412
7413                case BOOT_TIMEOUT: {
7414                    performBootTimeout();
7415                    break;
7416                }
7417
7418                case WAITING_FOR_DRAWN_TIMEOUT: {
7419                    Pair<WindowState, IRemoteCallback> pair;
7420                    synchronized (mWindowMap) {
7421                        pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
7422                        Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
7423                        if (!mWaitingForDrawn.remove(pair)) {
7424                            return;
7425                        }
7426                    }
7427                    try {
7428                        pair.second.sendResult(null);
7429                    } catch (RemoteException e) {
7430                    }
7431                    break;
7432                }
7433
7434                case SHOW_STRICT_MODE_VIOLATION: {
7435                    showStrictModeViolation(msg.arg1, msg.arg2);
7436                    break;
7437                }
7438
7439                case DO_ANIMATION_CALLBACK: {
7440                    try {
7441                        ((IRemoteCallback)msg.obj).sendResult(null);
7442                    } catch (RemoteException e) {
7443                    }
7444                    break;
7445                }
7446
7447                case DO_DISPLAY_ADDED:
7448                    synchronized (mWindowMap) {
7449                        handleDisplayAddedLocked(msg.arg1);
7450                    }
7451                    break;
7452
7453                case DO_DISPLAY_REMOVED:
7454                    synchronized (mWindowMap) {
7455                        handleDisplayRemovedLocked(msg.arg1);
7456                    }
7457                    break;
7458
7459                case DO_DISPLAY_CHANGED:
7460                    synchronized (mWindowMap) {
7461                        handleDisplayChangedLocked(msg.arg1);
7462                    }
7463                    break;
7464
7465                case TAP_OUTSIDE_STACK: {
7466                    int stackId;
7467                    synchronized (mWindowMap) {
7468                        stackId = ((DisplayContent)msg.obj).stackIdFromPoint(msg.arg1, msg.arg2);
7469                    }
7470                    if (stackId >= 0) {
7471                        try {
7472                            mActivityManager.setFocusedStack(stackId);
7473                        } catch (RemoteException e) {
7474                        }
7475                    }
7476                }
7477                break;
7478                case NOTIFY_ACTIVITY_DRAWN:
7479                    try {
7480                        mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
7481                    } catch (RemoteException e) {
7482                    }
7483                    break;
7484            }
7485            if (DEBUG_WINDOW_TRACE) {
7486                Slog.v(TAG, "handleMessage: exit");
7487            }
7488        }
7489    }
7490
7491    // -------------------------------------------------------------
7492    // IWindowManager API
7493    // -------------------------------------------------------------
7494
7495    @Override
7496    public IWindowSession openSession(IInputMethodClient client,
7497            IInputContext inputContext) {
7498        if (client == null) throw new IllegalArgumentException("null client");
7499        if (inputContext == null) throw new IllegalArgumentException("null inputContext");
7500        Session session = new Session(this, client, inputContext);
7501        return session;
7502    }
7503
7504    @Override
7505    public boolean inputMethodClientHasFocus(IInputMethodClient client) {
7506        synchronized (mWindowMap) {
7507            // The focus for the client is the window immediately below
7508            // where we would place the input method window.
7509            int idx = findDesiredInputMethodWindowIndexLocked(false);
7510            if (idx > 0) {
7511                // TODO(multidisplay): IMEs are only supported on the default display.
7512                WindowState imFocus = getDefaultWindowListLocked().get(idx-1);
7513                if (DEBUG_INPUT_METHOD) {
7514                    Slog.i(TAG, "Desired input method target: " + imFocus);
7515                    Slog.i(TAG, "Current focus: " + mCurrentFocus);
7516                    Slog.i(TAG, "Last focus: " + mLastFocus);
7517                }
7518                if (imFocus != null) {
7519                    // This may be a starting window, in which case we still want
7520                    // to count it as okay.
7521                    if (imFocus.mAttrs.type == LayoutParams.TYPE_APPLICATION_STARTING
7522                            && imFocus.mAppToken != null) {
7523                        // The client has definitely started, so it really should
7524                        // have a window in this app token.  Let's look for it.
7525                        for (int i=0; i<imFocus.mAppToken.windows.size(); i++) {
7526                            WindowState w = imFocus.mAppToken.windows.get(i);
7527                            if (w != imFocus) {
7528                                Log.i(TAG, "Switching to real app window: " + w);
7529                                imFocus = w;
7530                                break;
7531                            }
7532                        }
7533                    }
7534                    if (DEBUG_INPUT_METHOD) {
7535                        Slog.i(TAG, "IM target client: " + imFocus.mSession.mClient);
7536                        if (imFocus.mSession.mClient != null) {
7537                            Slog.i(TAG, "IM target client binder: "
7538                                    + imFocus.mSession.mClient.asBinder());
7539                            Slog.i(TAG, "Requesting client binder: " + client.asBinder());
7540                        }
7541                    }
7542                    if (imFocus.mSession.mClient != null &&
7543                            imFocus.mSession.mClient.asBinder() == client.asBinder()) {
7544                        return true;
7545                    }
7546                }
7547            }
7548
7549            // Okay, how about this...  what is the current focus?
7550            // It seems in some cases we may not have moved the IM
7551            // target window, such as when it was in a pop-up window,
7552            // so let's also look at the current focus.  (An example:
7553            // go to Gmail, start searching so the keyboard goes up,
7554            // press home.  Sometimes the IME won't go down.)
7555            // Would be nice to fix this more correctly, but it's
7556            // way at the end of a release, and this should be good enough.
7557            if (mCurrentFocus != null && mCurrentFocus.mSession.mClient != null
7558                    && mCurrentFocus.mSession.mClient.asBinder() == client.asBinder()) {
7559                return true;
7560            }
7561        }
7562        return false;
7563    }
7564
7565    @Override
7566    public void getInitialDisplaySize(int displayId, Point size) {
7567        synchronized (mWindowMap) {
7568            final DisplayContent displayContent = getDisplayContentLocked(displayId);
7569            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
7570                synchronized(displayContent.mDisplaySizeLock) {
7571                    size.x = displayContent.mInitialDisplayWidth;
7572                    size.y = displayContent.mInitialDisplayHeight;
7573                }
7574            }
7575        }
7576    }
7577
7578    @Override
7579    public void getBaseDisplaySize(int displayId, Point size) {
7580        synchronized (mWindowMap) {
7581            final DisplayContent displayContent = getDisplayContentLocked(displayId);
7582            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
7583                synchronized(displayContent.mDisplaySizeLock) {
7584                    size.x = displayContent.mBaseDisplayWidth;
7585                    size.y = displayContent.mBaseDisplayHeight;
7586                }
7587            }
7588        }
7589    }
7590
7591    @Override
7592    public void setForcedDisplaySize(int displayId, int width, int height) {
7593        if (mContext.checkCallingOrSelfPermission(
7594                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7595                PackageManager.PERMISSION_GRANTED) {
7596            throw new SecurityException("Must hold permission " +
7597                    android.Manifest.permission.WRITE_SECURE_SETTINGS);
7598        }
7599        if (displayId != Display.DEFAULT_DISPLAY) {
7600            throw new IllegalArgumentException("Can only set the default display");
7601        }
7602        final long ident = Binder.clearCallingIdentity();
7603        try {
7604            synchronized(mWindowMap) {
7605                // Set some sort of reasonable bounds on the size of the display that we
7606                // will try to emulate.
7607                final int MIN_WIDTH = 200;
7608                final int MIN_HEIGHT = 200;
7609                final int MAX_SCALE = 2;
7610                final DisplayContent displayContent = getDisplayContentLocked(displayId);
7611                if (displayContent != null) {
7612                    width = Math.min(Math.max(width, MIN_WIDTH),
7613                            displayContent.mInitialDisplayWidth * MAX_SCALE);
7614                    height = Math.min(Math.max(height, MIN_HEIGHT),
7615                            displayContent.mInitialDisplayHeight * MAX_SCALE);
7616                    setForcedDisplaySizeLocked(displayContent, width, height);
7617                    Settings.Global.putString(mContext.getContentResolver(),
7618                            Settings.Global.DISPLAY_SIZE_FORCED, width + "," + height);
7619                }
7620            }
7621        } finally {
7622            Binder.restoreCallingIdentity(ident);
7623        }
7624    }
7625
7626    private void readForcedDisplaySizeAndDensityLocked(final DisplayContent displayContent) {
7627        String sizeStr = Settings.Global.getString(mContext.getContentResolver(),
7628                Settings.Global.DISPLAY_SIZE_FORCED);
7629        if (sizeStr == null || sizeStr.length() == 0) {
7630            sizeStr = SystemProperties.get(SIZE_OVERRIDE, null);
7631        }
7632        if (sizeStr != null && sizeStr.length() > 0) {
7633            final int pos = sizeStr.indexOf(',');
7634            if (pos > 0 && sizeStr.lastIndexOf(',') == pos) {
7635                int width, height;
7636                try {
7637                    width = Integer.parseInt(sizeStr.substring(0, pos));
7638                    height = Integer.parseInt(sizeStr.substring(pos+1));
7639                    synchronized(displayContent.mDisplaySizeLock) {
7640                        if (displayContent.mBaseDisplayWidth != width
7641                                || displayContent.mBaseDisplayHeight != height) {
7642                            Slog.i(TAG, "FORCED DISPLAY SIZE: " + width + "x" + height);
7643                            displayContent.mBaseDisplayWidth = width;
7644                            displayContent.mBaseDisplayHeight = height;
7645                        }
7646                    }
7647                } catch (NumberFormatException ex) {
7648                }
7649            }
7650        }
7651        String densityStr = Settings.Global.getString(mContext.getContentResolver(),
7652                Settings.Global.DISPLAY_DENSITY_FORCED);
7653        if (densityStr == null || densityStr.length() == 0) {
7654            densityStr = SystemProperties.get(DENSITY_OVERRIDE, null);
7655        }
7656        if (densityStr != null && densityStr.length() > 0) {
7657            int density;
7658            try {
7659                density = Integer.parseInt(densityStr);
7660                synchronized(displayContent.mDisplaySizeLock) {
7661                    if (displayContent.mBaseDisplayDensity != density) {
7662                        Slog.i(TAG, "FORCED DISPLAY DENSITY: " + density);
7663                        displayContent.mBaseDisplayDensity = density;
7664                    }
7665                }
7666            } catch (NumberFormatException ex) {
7667            }
7668        }
7669    }
7670
7671    // displayContent must not be null
7672    private void setForcedDisplaySizeLocked(DisplayContent displayContent, int width, int height) {
7673        Slog.i(TAG, "Using new display size: " + width + "x" + height);
7674
7675        synchronized(displayContent.mDisplaySizeLock) {
7676            displayContent.mBaseDisplayWidth = width;
7677            displayContent.mBaseDisplayHeight = height;
7678        }
7679        reconfigureDisplayLocked(displayContent);
7680    }
7681
7682    @Override
7683    public void clearForcedDisplaySize(int displayId) {
7684        if (mContext.checkCallingOrSelfPermission(
7685                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7686                PackageManager.PERMISSION_GRANTED) {
7687            throw new SecurityException("Must hold permission " +
7688                    android.Manifest.permission.WRITE_SECURE_SETTINGS);
7689        }
7690        if (displayId != Display.DEFAULT_DISPLAY) {
7691            throw new IllegalArgumentException("Can only set the default display");
7692        }
7693        final long ident = Binder.clearCallingIdentity();
7694        try {
7695            synchronized(mWindowMap) {
7696                final DisplayContent displayContent = getDisplayContentLocked(displayId);
7697                if (displayContent != null) {
7698                    setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
7699                            displayContent.mInitialDisplayHeight);
7700                    Settings.Global.putString(mContext.getContentResolver(),
7701                            Settings.Global.DISPLAY_SIZE_FORCED, "");
7702                }
7703            }
7704        } finally {
7705            Binder.restoreCallingIdentity(ident);
7706        }
7707    }
7708
7709    @Override
7710    public int getInitialDisplayDensity(int displayId) {
7711        synchronized (mWindowMap) {
7712            final DisplayContent displayContent = getDisplayContentLocked(displayId);
7713            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
7714                synchronized(displayContent.mDisplaySizeLock) {
7715                    return displayContent.mInitialDisplayDensity;
7716                }
7717            }
7718        }
7719        return -1;
7720    }
7721
7722    @Override
7723    public int getBaseDisplayDensity(int displayId) {
7724        synchronized (mWindowMap) {
7725            final DisplayContent displayContent = getDisplayContentLocked(displayId);
7726            if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
7727                synchronized(displayContent.mDisplaySizeLock) {
7728                    return displayContent.mBaseDisplayDensity;
7729                }
7730            }
7731        }
7732        return -1;
7733    }
7734
7735    @Override
7736    public void setForcedDisplayDensity(int displayId, int density) {
7737        if (mContext.checkCallingOrSelfPermission(
7738                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7739                PackageManager.PERMISSION_GRANTED) {
7740            throw new SecurityException("Must hold permission " +
7741                    android.Manifest.permission.WRITE_SECURE_SETTINGS);
7742        }
7743        if (displayId != Display.DEFAULT_DISPLAY) {
7744            throw new IllegalArgumentException("Can only set the default display");
7745        }
7746        final long ident = Binder.clearCallingIdentity();
7747        try {
7748            synchronized(mWindowMap) {
7749                final DisplayContent displayContent = getDisplayContentLocked(displayId);
7750                if (displayContent != null) {
7751                    setForcedDisplayDensityLocked(displayContent, density);
7752                    Settings.Global.putString(mContext.getContentResolver(),
7753                            Settings.Global.DISPLAY_DENSITY_FORCED, Integer.toString(density));
7754                }
7755            }
7756        } finally {
7757            Binder.restoreCallingIdentity(ident);
7758        }
7759    }
7760
7761    // displayContent must not be null
7762    private void setForcedDisplayDensityLocked(DisplayContent displayContent, int density) {
7763        Slog.i(TAG, "Using new display density: " + density);
7764
7765        synchronized(displayContent.mDisplaySizeLock) {
7766            displayContent.mBaseDisplayDensity = density;
7767        }
7768        reconfigureDisplayLocked(displayContent);
7769    }
7770
7771    @Override
7772    public void clearForcedDisplayDensity(int displayId) {
7773        if (mContext.checkCallingOrSelfPermission(
7774                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7775                PackageManager.PERMISSION_GRANTED) {
7776            throw new SecurityException("Must hold permission " +
7777                    android.Manifest.permission.WRITE_SECURE_SETTINGS);
7778        }
7779        if (displayId != Display.DEFAULT_DISPLAY) {
7780            throw new IllegalArgumentException("Can only set the default display");
7781        }
7782        final long ident = Binder.clearCallingIdentity();
7783        try {
7784            synchronized(mWindowMap) {
7785                final DisplayContent displayContent = getDisplayContentLocked(displayId);
7786                if (displayContent != null) {
7787                    setForcedDisplayDensityLocked(displayContent,
7788                            displayContent.mInitialDisplayDensity);
7789                    Settings.Global.putString(mContext.getContentResolver(),
7790                            Settings.Global.DISPLAY_DENSITY_FORCED, "");
7791                }
7792            }
7793        } finally {
7794            Binder.restoreCallingIdentity(ident);
7795        }
7796    }
7797
7798    // displayContent must not be null
7799    private void reconfigureDisplayLocked(DisplayContent displayContent) {
7800        // TODO: Multidisplay: for now only use with default display.
7801        configureDisplayPolicyLocked(displayContent);
7802        displayContent.layoutNeeded = true;
7803
7804        boolean configChanged = updateOrientationFromAppTokensLocked(false);
7805        mTempConfiguration.setToDefaults();
7806        mTempConfiguration.fontScale = mCurConfiguration.fontScale;
7807        if (computeScreenConfigurationLocked(mTempConfiguration)) {
7808            if (mCurConfiguration.diff(mTempConfiguration) != 0) {
7809                configChanged = true;
7810            }
7811        }
7812
7813        if (configChanged) {
7814            mWaitingForConfig = true;
7815            startFreezingDisplayLocked(false, 0, 0);
7816            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
7817        }
7818
7819        performLayoutAndPlaceSurfacesLocked();
7820    }
7821
7822    private void configureDisplayPolicyLocked(DisplayContent displayContent) {
7823        mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
7824                displayContent.mBaseDisplayWidth,
7825                displayContent.mBaseDisplayHeight,
7826                displayContent.mBaseDisplayDensity);
7827
7828        DisplayInfo displayInfo = displayContent.getDisplayInfo();
7829        mPolicy.setDisplayOverscan(displayContent.getDisplay(),
7830                displayInfo.overscanLeft, displayInfo.overscanTop,
7831                displayInfo.overscanRight, displayInfo.overscanBottom);
7832    }
7833
7834    @Override
7835    public void setOverscan(int displayId, int left, int top, int right, int bottom) {
7836        if (mContext.checkCallingOrSelfPermission(
7837                android.Manifest.permission.WRITE_SECURE_SETTINGS) !=
7838                PackageManager.PERMISSION_GRANTED) {
7839            throw new SecurityException("Must hold permission " +
7840                    android.Manifest.permission.WRITE_SECURE_SETTINGS);
7841        }
7842        final long ident = Binder.clearCallingIdentity();
7843        try {
7844            synchronized(mWindowMap) {
7845                DisplayContent displayContent = getDisplayContentLocked(displayId);
7846                if (displayContent != null) {
7847                    setOverscanLocked(displayContent, left, top, right, bottom);
7848                }
7849            }
7850        } finally {
7851            Binder.restoreCallingIdentity(ident);
7852        }
7853    }
7854
7855    private void setOverscanLocked(DisplayContent displayContent,
7856            int left, int top, int right, int bottom) {
7857        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
7858        synchronized (displayContent.mDisplaySizeLock) {
7859            displayInfo.overscanLeft = left;
7860            displayInfo.overscanTop = top;
7861            displayInfo.overscanRight = right;
7862            displayInfo.overscanBottom = bottom;
7863        }
7864
7865        mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
7866        mDisplaySettings.writeSettingsLocked();
7867
7868        reconfigureDisplayLocked(displayContent);
7869    }
7870
7871    // -------------------------------------------------------------
7872    // Internals
7873    // -------------------------------------------------------------
7874
7875    final WindowState windowForClientLocked(Session session, IWindow client,
7876            boolean throwOnError) {
7877        return windowForClientLocked(session, client.asBinder(), throwOnError);
7878    }
7879
7880    final WindowState windowForClientLocked(Session session, IBinder client,
7881            boolean throwOnError) {
7882        WindowState win = mWindowMap.get(client);
7883        if (localLOGV) Slog.v(
7884            TAG, "Looking up client " + client + ": " + win);
7885        if (win == null) {
7886            RuntimeException ex = new IllegalArgumentException(
7887                    "Requested window " + client + " does not exist");
7888            if (throwOnError) {
7889                throw ex;
7890            }
7891            Slog.w(TAG, "Failed looking up window", ex);
7892            return null;
7893        }
7894        if (session != null && win.mSession != session) {
7895            RuntimeException ex = new IllegalArgumentException(
7896                    "Requested window " + client + " is in session " +
7897                    win.mSession + ", not " + session);
7898            if (throwOnError) {
7899                throw ex;
7900            }
7901            Slog.w(TAG, "Failed looking up window", ex);
7902            return null;
7903        }
7904
7905        return win;
7906    }
7907
7908    final void rebuildAppWindowListLocked() {
7909        // TODO: Multidisplay, when ActivityStacks and tasks exist on more than one display.
7910        rebuildAppWindowListLocked(getDefaultDisplayContentLocked());
7911    }
7912
7913    private void rebuildAppWindowListLocked(final DisplayContent displayContent) {
7914        final WindowList windows = displayContent.getWindowList();
7915        int NW = windows.size();
7916        int i;
7917        int lastBelow = -1;
7918        int numRemoved = 0;
7919
7920        if (mRebuildTmp.length < NW) {
7921            mRebuildTmp = new WindowState[NW+10];
7922        }
7923
7924        // First remove all existing app windows.
7925        i=0;
7926        while (i < NW) {
7927            WindowState w = windows.get(i);
7928            if (w.mAppToken != null) {
7929                WindowState win = windows.remove(i);
7930                win.mRebuilding = true;
7931                mRebuildTmp[numRemoved] = win;
7932                mWindowsChanged = true;
7933                if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Rebuild removing window: " + win);
7934                NW--;
7935                numRemoved++;
7936                continue;
7937            } else if (lastBelow == i-1) {
7938                if (w.mAttrs.type == TYPE_WALLPAPER || w.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
7939                    lastBelow = i;
7940                }
7941            }
7942            i++;
7943        }
7944
7945        // Keep whatever windows were below the app windows still below,
7946        // by skipping them.
7947        lastBelow++;
7948        i = lastBelow;
7949
7950        // First add all of the exiting app tokens...  these are no longer
7951        // in the main app list, but still have windows shown.  We put them
7952        // in the back because now that the animation is over we no longer
7953        // will care about them.
7954        AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
7955        int NT = exitingAppTokens.size();
7956        for (int j=0; j<NT; j++) {
7957            i = reAddAppWindowsLocked(displayContent, i, exitingAppTokens.get(j));
7958        }
7959
7960        // And add in the still active app tokens in Z order.
7961        final ArrayList<Task> tasks = displayContent.getTasks();
7962        final int numTasks = tasks.size();
7963        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
7964            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
7965            final int numTokens = tokens.size();
7966            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
7967                final AppWindowToken wtoken = tokens.get(tokenNdx);
7968                i = reAddAppWindowsLocked(displayContent, i, wtoken);
7969            }
7970        }
7971
7972        i -= lastBelow;
7973        if (i != numRemoved) {
7974            Slog.w(TAG, "Rebuild removed " + numRemoved + " windows but added " + i,
7975                    new RuntimeException("here").fillInStackTrace());
7976            for (i=0; i<numRemoved; i++) {
7977                WindowState ws = mRebuildTmp[i];
7978                if (ws.mRebuilding) {
7979                    StringWriter sw = new StringWriter();
7980                    PrintWriter pw = new FastPrintWriter(sw, false, 1024);
7981                    ws.dump(pw, "", true);
7982                    pw.flush();
7983                    Slog.w(TAG, "This window was lost: " + ws);
7984                    Slog.w(TAG, sw.toString());
7985                    ws.mWinAnimator.destroySurfaceLocked();
7986                }
7987            }
7988            Slog.w(TAG, "Current app token list:");
7989            dumpAppTokensLocked();
7990            Slog.w(TAG, "Final window list:");
7991            dumpWindowsLocked();
7992        }
7993    }
7994
7995    private final void assignLayersLocked(WindowList windows) {
7996        int N = windows.size();
7997        int curBaseLayer = 0;
7998        int curLayer = 0;
7999        int i;
8000
8001        if (DEBUG_LAYERS) Slog.v(TAG, "Assigning layers based on windows=" + windows,
8002                new RuntimeException("here").fillInStackTrace());
8003
8004        boolean anyLayerChanged = false;
8005
8006        for (i=0; i<N; i++) {
8007            final WindowState w = windows.get(i);
8008            final WindowStateAnimator winAnimator = w.mWinAnimator;
8009            boolean layerChanged = false;
8010            int oldLayer = w.mLayer;
8011            if (w.mBaseLayer == curBaseLayer || w.mIsImWindow
8012                    || (i > 0 && w.mIsWallpaper)) {
8013                curLayer += WINDOW_LAYER_MULTIPLIER;
8014                w.mLayer = curLayer;
8015            } else {
8016                curBaseLayer = curLayer = w.mBaseLayer;
8017                w.mLayer = curLayer;
8018            }
8019            if (w.mLayer != oldLayer) {
8020                layerChanged = true;
8021                anyLayerChanged = true;
8022            }
8023            final AppWindowToken wtoken = w.mAppToken;
8024            oldLayer = winAnimator.mAnimLayer;
8025            if (w.mTargetAppToken != null) {
8026                winAnimator.mAnimLayer =
8027                        w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
8028            } else if (wtoken != null) {
8029                winAnimator.mAnimLayer =
8030                        w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
8031            } else {
8032                winAnimator.mAnimLayer = w.mLayer;
8033            }
8034            if (w.mIsImWindow) {
8035                winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
8036            } else if (w.mIsWallpaper) {
8037                winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
8038            }
8039            if (winAnimator.mAnimLayer != oldLayer) {
8040                layerChanged = true;
8041                anyLayerChanged = true;
8042            }
8043            if (layerChanged && w.getStack().isDimming(winAnimator)) {
8044                // Force an animation pass just to update the mDimLayer layer.
8045                scheduleAnimationLocked();
8046            }
8047            if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": "
8048                    + "mBase=" + w.mBaseLayer
8049                    + " mLayer=" + w.mLayer
8050                    + (wtoken == null ?
8051                            "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment)
8052                    + " =mAnimLayer=" + winAnimator.mAnimLayer);
8053            //System.out.println(
8054            //    "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
8055        }
8056
8057        //TODO (multidisplay): Magnification is supported only for the default display.
8058        if (mDisplayMagnifier != null && anyLayerChanged
8059                && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
8060            mDisplayMagnifier.onWindowLayersChangedLocked();
8061        }
8062    }
8063
8064    private final void performLayoutAndPlaceSurfacesLocked() {
8065        int loopCount = 6;
8066        do {
8067            mTraversalScheduled = false;
8068            performLayoutAndPlaceSurfacesLockedLoop();
8069            mH.removeMessages(H.DO_TRAVERSAL);
8070            loopCount--;
8071        } while (mTraversalScheduled && loopCount > 0);
8072        mInnerFields.mWallpaperActionPending = false;
8073    }
8074
8075    private boolean mInLayout = false;
8076    private final void performLayoutAndPlaceSurfacesLockedLoop() {
8077        if (mInLayout) {
8078            if (DEBUG) {
8079                throw new RuntimeException("Recursive call!");
8080            }
8081            Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
8082                    + Debug.getCallers(3));
8083            return;
8084        }
8085
8086        if (mWaitingForConfig) {
8087            // Our configuration has changed (most likely rotation), but we
8088            // don't yet have the complete configuration to report to
8089            // applications.  Don't do any window layout until we have it.
8090            return;
8091        }
8092
8093        if (!mDisplayReady) {
8094            // Not yet initialized, nothing to do.
8095            return;
8096        }
8097
8098        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
8099        mInLayout = true;
8100        boolean recoveringMemory = false;
8101
8102        try {
8103            if (mForceRemoves != null) {
8104                recoveringMemory = true;
8105                // Wait a little bit for things to settle down, and off we go.
8106                for (int i=0; i<mForceRemoves.size(); i++) {
8107                    WindowState ws = mForceRemoves.get(i);
8108                    Slog.i(TAG, "Force removing: " + ws);
8109                    removeWindowInnerLocked(ws.mSession, ws);
8110                }
8111                mForceRemoves = null;
8112                Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
8113                Object tmp = new Object();
8114                synchronized (tmp) {
8115                    try {
8116                        tmp.wait(250);
8117                    } catch (InterruptedException e) {
8118                    }
8119                }
8120            }
8121        } catch (RuntimeException e) {
8122            Log.wtf(TAG, "Unhandled exception while force removing for memory", e);
8123        }
8124
8125        try {
8126            performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
8127
8128            mInLayout = false;
8129
8130            if (needsLayout()) {
8131                if (++mLayoutRepeatCount < 6) {
8132                    requestTraversalLocked();
8133                } else {
8134                    Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
8135                    mLayoutRepeatCount = 0;
8136                }
8137            } else {
8138                mLayoutRepeatCount = 0;
8139            }
8140
8141            if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
8142                mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
8143                mH.sendEmptyMessage(H.REPORT_WINDOWS_CHANGE);
8144            }
8145        } catch (RuntimeException e) {
8146            mInLayout = false;
8147            Log.wtf(TAG, "Unhandled exception while laying out windows", e);
8148        }
8149
8150        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
8151    }
8152
8153    private final void performLayoutLockedInner(final DisplayContent displayContent,
8154                                    boolean initial, boolean updateInputWindows) {
8155        if (!displayContent.layoutNeeded) {
8156            return;
8157        }
8158        displayContent.layoutNeeded = false;
8159        WindowList windows = displayContent.getWindowList();
8160        boolean isDefaultDisplay = displayContent.isDefaultDisplay;
8161
8162        DisplayInfo displayInfo = displayContent.getDisplayInfo();
8163        final int dw = displayInfo.logicalWidth;
8164        final int dh = displayInfo.logicalHeight;
8165
8166        final int NFW = mFakeWindows.size();
8167        for (int i=0; i<NFW; i++) {
8168            mFakeWindows.get(i).layout(dw, dh);
8169        }
8170
8171        final int N = windows.size();
8172        int i;
8173
8174        if (DEBUG_LAYOUT) {
8175            Slog.v(TAG, "-------------------------------------");
8176            Slog.v(TAG, "performLayout: needed="
8177                    + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
8178        }
8179
8180        WindowStateAnimator universeBackground = null;
8181
8182        mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mRotation);
8183        if (isDefaultDisplay) {
8184            // Not needed on non-default displays.
8185            mSystemDecorLayer = mPolicy.getSystemDecorLayerLw();
8186            mScreenRect.set(0, 0, dw, dh);
8187        }
8188
8189        mPolicy.getContentRectLw(mTmpContentRect);
8190        displayContent.resize(mTmpContentRect);
8191
8192        int seq = mLayoutSeq+1;
8193        if (seq < 0) seq = 0;
8194        mLayoutSeq = seq;
8195
8196        boolean behindDream = false;
8197
8198        // First perform layout of any root windows (not attached
8199        // to another window).
8200        int topAttached = -1;
8201        for (i = N-1; i >= 0; i--) {
8202            final WindowState win = windows.get(i);
8203
8204            // Don't do layout of a window if it is not visible, or
8205            // soon won't be visible, to avoid wasting time and funky
8206            // changes while a window is animating away.
8207            final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs))
8208                    || win.isGoneForLayoutLw();
8209
8210            if (DEBUG_LAYOUT && !win.mLayoutAttached) {
8211                Slog.v(TAG, "1ST PASS " + win
8212                        + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
8213                        + " mLayoutAttached=" + win.mLayoutAttached
8214                        + " screen changed=" + win.isConfigChanged());
8215                final AppWindowToken atoken = win.mAppToken;
8216                if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
8217                        + win.mViewVisibility + " mRelayoutCalled="
8218                        + win.mRelayoutCalled + " hidden="
8219                        + win.mRootToken.hidden + " hiddenRequested="
8220                        + (atoken != null && atoken.hiddenRequested)
8221                        + " mAttachedHidden=" + win.mAttachedHidden);
8222                else Slog.v(TAG, "  VIS: mViewVisibility="
8223                        + win.mViewVisibility + " mRelayoutCalled="
8224                        + win.mRelayoutCalled + " hidden="
8225                        + win.mRootToken.hidden + " hiddenRequested="
8226                        + (atoken != null && atoken.hiddenRequested)
8227                        + " mAttachedHidden=" + win.mAttachedHidden);
8228            }
8229
8230            // If this view is GONE, then skip it -- keep the current
8231            // frame, and let the caller know so they can ignore it
8232            // if they want.  (We do the normal layout for INVISIBLE
8233            // windows, since that means "perform layout as normal,
8234            // just don't display").
8235            if (!gone || !win.mHaveFrame || win.mLayoutNeeded
8236                    || ((win.isConfigChanged() || win.setInsetsChanged()) &&
8237                            (win.mAttrs.type == TYPE_KEYGUARD ||
8238                            win.mAppToken != null && win.mAppToken.layoutConfigChanges))
8239                    || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
8240                if (!win.mLayoutAttached) {
8241                    if (initial) {
8242                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
8243                        win.mContentChanged = false;
8244                    }
8245                    if (win.mAttrs.type == TYPE_DREAM) {
8246                        // Don't layout windows behind a dream, so that if it
8247                        // does stuff like hide the status bar we won't get a
8248                        // bad transition when it goes away.
8249                        behindDream = true;
8250                    }
8251                    win.mLayoutNeeded = false;
8252                    win.prelayout();
8253                    mPolicy.layoutWindowLw(win, win.mAttrs, null);
8254                    win.mLayoutSeq = seq;
8255                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
8256                            + win.mFrame + " mContainingFrame="
8257                            + win.mContainingFrame + " mDisplayFrame="
8258                            + win.mDisplayFrame);
8259                } else {
8260                    if (topAttached < 0) topAttached = i;
8261                }
8262            }
8263            if (win.mViewVisibility == View.VISIBLE
8264                    && win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND
8265                    && universeBackground == null) {
8266                universeBackground = win.mWinAnimator;
8267            }
8268        }
8269
8270        if (mAnimator.mUniverseBackground  != universeBackground) {
8271            mFocusMayChange = true;
8272            mAnimator.mUniverseBackground = universeBackground;
8273        }
8274
8275        boolean attachedBehindDream = false;
8276
8277        // Now perform layout of attached windows, which usually
8278        // depend on the position of the window they are attached to.
8279        // XXX does not deal with windows that are attached to windows
8280        // that are themselves attached.
8281        for (i = topAttached; i >= 0; i--) {
8282            final WindowState win = windows.get(i);
8283
8284            if (win.mLayoutAttached) {
8285                if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + win
8286                        + " mHaveFrame=" + win.mHaveFrame
8287                        + " mViewVisibility=" + win.mViewVisibility
8288                        + " mRelayoutCalled=" + win.mRelayoutCalled);
8289                // If this view is GONE, then skip it -- keep the current
8290                // frame, and let the caller know so they can ignore it
8291                // if they want.  (We do the normal layout for INVISIBLE
8292                // windows, since that means "perform layout as normal,
8293                // just don't display").
8294                if (attachedBehindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) {
8295                    continue;
8296                }
8297                if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
8298                        || !win.mHaveFrame || win.mLayoutNeeded) {
8299                    if (initial) {
8300                        //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
8301                        win.mContentChanged = false;
8302                    }
8303                    win.mLayoutNeeded = false;
8304                    win.prelayout();
8305                    mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
8306                    win.mLayoutSeq = seq;
8307                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
8308                            + win.mFrame + " mContainingFrame="
8309                            + win.mContainingFrame + " mDisplayFrame="
8310                            + win.mDisplayFrame);
8311                }
8312            } else if (win.mAttrs.type == TYPE_DREAM) {
8313                // Don't layout windows behind a dream, so that if it
8314                // does stuff like hide the status bar we won't get a
8315                // bad transition when it goes away.
8316                attachedBehindDream = behindDream;
8317            }
8318        }
8319
8320        // Window frames may have changed.  Tell the input dispatcher about it.
8321        mInputMonitor.setUpdateInputWindowsNeededLw();
8322        if (updateInputWindows) {
8323            mInputMonitor.updateInputWindowsLw(false /*force*/);
8324        }
8325
8326        mPolicy.finishLayoutLw();
8327    }
8328
8329    void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
8330        // If the screen is currently frozen or off, then keep
8331        // it frozen/off until this window draws at its new
8332        // orientation.
8333        if (!okToDisplay()) {
8334            if (DEBUG_ORIENTATION) Slog.v(TAG,
8335                    "Changing surface while display frozen: " + w);
8336            w.mOrientationChanging = true;
8337            w.mLastFreezeDuration = 0;
8338            mInnerFields.mOrientationChangeComplete = false;
8339            if (!mWindowsFreezingScreen) {
8340                mWindowsFreezingScreen = true;
8341                // XXX should probably keep timeout from
8342                // when we first froze the display.
8343                mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
8344                mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT,
8345                        WINDOW_FREEZE_TIMEOUT_DURATION);
8346            }
8347        }
8348    }
8349
8350    /**
8351     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8352     * @param windows List of windows on default display.
8353     * @return bitmap indicating if another pass through layout must be made.
8354     */
8355    public int handleAppTransitionReadyLocked(WindowList windows) {
8356        int changes = 0;
8357        int i;
8358        int NN = mOpeningApps.size();
8359        boolean goodToGo = true;
8360        if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8361                "Checking " + NN + " opening apps (frozen="
8362                + mDisplayFrozen + " timeout="
8363                + mAppTransition.isTimeout() + ")...");
8364        if (!mDisplayFrozen && !mAppTransition.isTimeout()) {
8365            // If the display isn't frozen, wait to do anything until
8366            // all of the apps are ready.  Otherwise just go because
8367            // we'll unfreeze the display when everyone is ready.
8368            for (i=0; i<NN && goodToGo; i++) {
8369                AppWindowToken wtoken = mOpeningApps.get(i);
8370                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8371                        "Check opening app=" + wtoken + ": allDrawn="
8372                        + wtoken.allDrawn + " startingDisplayed="
8373                        + wtoken.startingDisplayed + " startingMoved="
8374                        + wtoken.startingMoved);
8375                if (!wtoken.allDrawn && !wtoken.startingDisplayed
8376                        && !wtoken.startingMoved) {
8377                    goodToGo = false;
8378                }
8379            }
8380        }
8381        if (goodToGo) {
8382            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
8383            int transit = mAppTransition.getAppTransition();
8384            if (mSkipAppTransitionAnimation) {
8385                transit = AppTransition.TRANSIT_UNSET;
8386            }
8387            mAppTransition.goodToGo();
8388            mStartingIconInTransition = false;
8389            mSkipAppTransitionAnimation = false;
8390
8391            mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
8392
8393            rebuildAppWindowListLocked();
8394
8395            // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
8396            WindowState oldWallpaper =
8397                    mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
8398                        && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
8399                    ? null : mWallpaperTarget;
8400
8401            mInnerFields.mWallpaperMayChange = false;
8402
8403            // The top-most window will supply the layout params,
8404            // and we will determine it below.
8405            LayoutParams animLp = null;
8406            int bestAnimLayer = -1;
8407            boolean fullscreenAnim = false;
8408
8409            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8410                    "New wallpaper target=" + mWallpaperTarget
8411                    + ", oldWallpaper=" + oldWallpaper
8412                    + ", lower target=" + mLowerWallpaperTarget
8413                    + ", upper target=" + mUpperWallpaperTarget);
8414
8415            boolean openingAppHasWallpaper = false;
8416            boolean closingAppHasWallpaper = false;
8417            final AppWindowToken lowerWallpaperAppToken;
8418            final AppWindowToken upperWallpaperAppToken;
8419            if (mLowerWallpaperTarget == null) {
8420                lowerWallpaperAppToken = upperWallpaperAppToken = null;
8421            } else {
8422                lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
8423                upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
8424            }
8425
8426            // Do a first pass through the tokens for two
8427            // things:
8428            // (1) Determine if both the closing and opening
8429            // app token sets are wallpaper targets, in which
8430            // case special animations are needed
8431            // (since the wallpaper needs to stay static
8432            // behind them).
8433            // (2) Find the layout params of the top-most
8434            // application window in the tokens, which is
8435            // what will control the animation theme.
8436            final int NC = mClosingApps.size();
8437            NN = NC + mOpeningApps.size();
8438            for (i=0; i<NN; i++) {
8439                final AppWindowToken wtoken;
8440                if (i < NC) {
8441                    wtoken = mClosingApps.get(i);
8442                    if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8443                        closingAppHasWallpaper = true;
8444                    }
8445                } else {
8446                    wtoken = mOpeningApps.get(i - NC);
8447                    if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
8448                        openingAppHasWallpaper = true;
8449                    }
8450                }
8451
8452                if (wtoken.appFullscreen) {
8453                    WindowState ws = wtoken.findMainWindow();
8454                    if (ws != null) {
8455                        animLp = ws.mAttrs;
8456                        bestAnimLayer = ws.mLayer;
8457                        fullscreenAnim = true;
8458                    }
8459                } else if (!fullscreenAnim) {
8460                    WindowState ws = wtoken.findMainWindow();
8461                    if (ws != null) {
8462                        if (ws.mLayer > bestAnimLayer) {
8463                            animLp = ws.mAttrs;
8464                            bestAnimLayer = ws.mLayer;
8465                        }
8466                    }
8467                }
8468            }
8469
8470            mAnimateWallpaperWithTarget = false;
8471            if (closingAppHasWallpaper && openingAppHasWallpaper) {
8472                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
8473                switch (transit) {
8474                    case AppTransition.TRANSIT_ACTIVITY_OPEN:
8475                    case AppTransition.TRANSIT_TASK_OPEN:
8476                    case AppTransition.TRANSIT_TASK_TO_FRONT:
8477                        transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
8478                        break;
8479                    case AppTransition.TRANSIT_ACTIVITY_CLOSE:
8480                    case AppTransition.TRANSIT_TASK_CLOSE:
8481                    case AppTransition.TRANSIT_TASK_TO_BACK:
8482                        transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
8483                        break;
8484                }
8485                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
8486            } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
8487                    && !mOpeningApps.contains(oldWallpaper.mAppToken)) {
8488                // We are transitioning from an activity with
8489                // a wallpaper to one without.
8490                transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
8491                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8492                        "New transit away from wallpaper: " + transit);
8493            } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
8494                // We are transitioning from an activity without
8495                // a wallpaper to now showing the wallpaper
8496                transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
8497                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8498                        "New transit into wallpaper: " + transit);
8499            } else {
8500                mAnimateWallpaperWithTarget = true;
8501            }
8502
8503            // If all closing windows are obscured, then there is
8504            // no need to do an animation.  This is the case, for
8505            // example, when this transition is being done behind
8506            // the lock screen.
8507            if (!mPolicy.allowAppAnimationsLw()) {
8508                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
8509                        "Animations disallowed by keyguard or dream.");
8510                animLp = null;
8511            }
8512
8513            AppWindowToken topOpeningApp = null;
8514            int topOpeningLayer = 0;
8515
8516            NN = mOpeningApps.size();
8517            for (i=0; i<NN; i++) {
8518                AppWindowToken wtoken = mOpeningApps.get(i);
8519                final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
8520                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
8521                appAnimator.clearThumbnail();
8522                wtoken.inPendingTransaction = false;
8523                appAnimator.animation = null;
8524                setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
8525                wtoken.updateReportedVisibilityLocked();
8526                wtoken.waitingToShow = false;
8527
8528                appAnimator.mAllAppWinAnimators.clear();
8529                final int N = wtoken.allAppWindows.size();
8530                for (int j = 0; j < N; j++) {
8531                    appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
8532                }
8533                mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
8534
8535                if (animLp != null) {
8536                    int layer = -1;
8537                    for (int j=0; j<wtoken.windows.size(); j++) {
8538                        WindowState win = wtoken.windows.get(j);
8539                        if (win.mWinAnimator.mAnimLayer > layer) {
8540                            layer = win.mWinAnimator.mAnimLayer;
8541                        }
8542                    }
8543                    if (topOpeningApp == null || layer > topOpeningLayer) {
8544                        topOpeningApp = wtoken;
8545                        topOpeningLayer = layer;
8546                    }
8547                }
8548            }
8549            NN = mClosingApps.size();
8550            for (i=0; i<NN; i++) {
8551                AppWindowToken wtoken = mClosingApps.get(i);
8552                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
8553                wtoken.mAppAnimator.clearThumbnail();
8554                wtoken.inPendingTransaction = false;
8555                wtoken.mAppAnimator.animation = null;
8556                setTokenVisibilityLocked(wtoken, animLp, false, transit, false);
8557                wtoken.updateReportedVisibilityLocked();
8558                wtoken.waitingToHide = false;
8559                // Force the allDrawn flag, because we want to start
8560                // this guy's animations regardless of whether it's
8561                // gotten drawn.
8562                wtoken.allDrawn = true;
8563                wtoken.deferClearAllDrawn = false;
8564            }
8565
8566            AppWindowAnimator appAnimator =
8567                    topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
8568            Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
8569            if (nextAppTransitionThumbnail != null && appAnimator != null
8570                    && appAnimator.animation != null) {
8571                // This thumbnail animation is very special, we need to have
8572                // an extra surface with the thumbnail included with the animation.
8573                Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
8574                        nextAppTransitionThumbnail.getHeight());
8575                try {
8576                    // TODO(multi-display): support other displays
8577                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
8578                    final Display display = displayContent.getDisplay();
8579                    SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
8580                            "thumbnail anim",
8581                            dirty.width(), dirty.height(),
8582                            PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
8583                    surfaceControl.setLayerStack(display.getLayerStack());
8584                    appAnimator.thumbnail = surfaceControl;
8585                    if (SHOW_TRANSACTIONS) Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
8586                    Surface drawSurface = new Surface();
8587                    drawSurface.copyFrom(surfaceControl);
8588                    Canvas c = drawSurface.lockCanvas(dirty);
8589                    c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
8590                    drawSurface.unlockCanvasAndPost(c);
8591                    drawSurface.release();
8592                    appAnimator.thumbnailLayer = topOpeningLayer;
8593                    DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
8594                    Animation anim = mAppTransition.createThumbnailAnimationLocked(
8595                            transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
8596                    appAnimator.thumbnailAnimation = anim;
8597                    anim.restrictDuration(MAX_ANIMATION_DURATION);
8598                    anim.scaleCurrentDuration(mTransitionAnimationScale);
8599                    Point p = new Point();
8600                    mAppTransition.getStartingPoint(p);
8601                    appAnimator.thumbnailX = p.x;
8602                    appAnimator.thumbnailY = p.y;
8603                } catch (OutOfResourcesException e) {
8604                    Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
8605                            + " h=" + dirty.height(), e);
8606                    appAnimator.clearThumbnail();
8607                }
8608            }
8609
8610            mAppTransition.postAnimationCallback();
8611            mAppTransition.clear();
8612
8613            mOpeningApps.clear();
8614            mClosingApps.clear();
8615
8616            // This has changed the visibility of windows, so perform
8617            // a new layout to get them all up-to-date.
8618            changes |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT
8619                    | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
8620            getDefaultDisplayContentLocked().layoutNeeded = true;
8621
8622            // TODO(multidisplay): IMEs are only supported on the default display.
8623            if (windows == getDefaultWindowListLocked()
8624                    && !moveInputMethodWindowsIfNeededLocked(true)) {
8625                assignLayersLocked(windows);
8626            }
8627            updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES, false /*updateInputWindows*/);
8628            mFocusMayChange = false;
8629        }
8630
8631        return changes;
8632    }
8633
8634    /**
8635     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8636     * @return bitmap indicating if another pass through layout must be made.
8637     */
8638    private int handleAnimatingStoppedAndTransitionLocked() {
8639        int changes = 0;
8640
8641        mAppTransition.setIdle();
8642        // Restore window app tokens to the ActivityManager views
8643        final DisplayContent displayContent = getDefaultDisplayContentLocked();
8644        final ArrayList<Task> tasks = displayContent.getTasks();
8645        final int numTasks = tasks.size();
8646        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
8647            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8648            final int numTokens = tokens.size();
8649            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
8650                final AppWindowToken wtoken = tokens.get(tokenNdx);
8651                wtoken.sendingToBottom = false;
8652            }
8653        }
8654        rebuildAppWindowListLocked();
8655
8656        changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT;
8657        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
8658                "Wallpaper layer changed: assigning layers + relayout");
8659        moveInputMethodWindowsIfNeededLocked(true);
8660        mInnerFields.mWallpaperMayChange = true;
8661        // Since the window list has been rebuilt, focus might
8662        // have to be recomputed since the actual order of windows
8663        // might have changed again.
8664        mFocusMayChange = true;
8665
8666        return changes;
8667    }
8668
8669    private void updateResizingWindows(final WindowState w) {
8670        final WindowStateAnimator winAnimator = w.mWinAnimator;
8671        if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq) {
8672            w.setInsetsChanged();
8673            boolean configChanged = w.isConfigChanged();
8674            if (DEBUG_CONFIGURATION && configChanged) {
8675                Slog.v(TAG, "Win " + w + " config changed: "
8676                        + mCurConfiguration);
8677            }
8678            if (localLOGV) Slog.v(TAG, "Resizing " + w
8679                    + ": configChanged=" + configChanged
8680                    + " last=" + w.mLastFrame + " frame=" + w.mFrame);
8681            w.mLastFrame.set(w.mFrame);
8682            if (w.mContentInsetsChanged
8683                    || w.mVisibleInsetsChanged
8684                    || winAnimator.mSurfaceResized
8685                    || configChanged) {
8686                if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
8687                    Slog.v(TAG, "Resize reasons for w=" + w + ": "
8688                            + " contentInsetsChanged=" + w.mContentInsetsChanged
8689                            + " " + w.mContentInsets.toShortString()
8690                            + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
8691                            + " " + w.mVisibleInsets.toShortString()
8692                            + " surfaceResized=" + winAnimator.mSurfaceResized
8693                            + " configChanged=" + configChanged);
8694                }
8695
8696                w.mLastOverscanInsets.set(w.mOverscanInsets);
8697                w.mLastContentInsets.set(w.mContentInsets);
8698                w.mLastVisibleInsets.set(w.mVisibleInsets);
8699                makeWindowFreezingScreenIfNeededLocked(w);
8700                // If the orientation is changing, then we need to
8701                // hold off on unfreezing the display until this
8702                // window has been redrawn; to do that, we need
8703                // to go through the process of getting informed
8704                // by the application when it has finished drawing.
8705                if (w.mOrientationChanging) {
8706                    if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION) Slog.v(TAG,
8707                            "Orientation start waiting for draw mDrawState=DRAW_PENDING in "
8708                            + w + ", surface " + winAnimator.mSurfaceControl);
8709                    winAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
8710                    if (w.mAppToken != null) {
8711                        w.mAppToken.allDrawn = false;
8712                        w.mAppToken.deferClearAllDrawn = false;
8713                    }
8714                }
8715                if (!mResizingWindows.contains(w)) {
8716                    if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
8717                            "Resizing window " + w + " to " + winAnimator.mSurfaceW
8718                            + "x" + winAnimator.mSurfaceH);
8719                    mResizingWindows.add(w);
8720                }
8721            } else if (w.mOrientationChanging) {
8722                if (w.isDrawnLw()) {
8723                    if (DEBUG_ORIENTATION) Slog.v(TAG,
8724                            "Orientation not waiting for draw in "
8725                            + w + ", surface " + winAnimator.mSurfaceControl);
8726                    w.mOrientationChanging = false;
8727                    w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
8728                            - mDisplayFreezeTime);
8729                }
8730            }
8731        }
8732    }
8733
8734    /**
8735     * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
8736     *
8737     * @param w WindowState this method is applied to.
8738     * @param currentTime The time which animations use for calculating transitions.
8739     * @param innerDw Width of app window.
8740     * @param innerDh Height of app window.
8741     */
8742    private void handleNotObscuredLocked(final WindowState w, final long currentTime,
8743                                         final int innerDw, final int innerDh) {
8744        final WindowManager.LayoutParams attrs = w.mAttrs;
8745        final int attrFlags = attrs.flags;
8746        final boolean canBeSeen = w.isDisplayedLw();
8747        final boolean opaqueDrawn = canBeSeen && w.isOpaqueDrawn();
8748
8749        if (opaqueDrawn && w.isFullscreen(innerDw, innerDh)) {
8750            // This window completely covers everything behind it,
8751            // so we want to leave all of them as undimmed (for
8752            // performance reasons).
8753            mInnerFields.mObscured = true;
8754        }
8755
8756        if (w.mHasSurface) {
8757            if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
8758                mInnerFields.mHoldScreen = w.mSession;
8759            }
8760            if (!mInnerFields.mSyswin && w.mAttrs.screenBrightness >= 0
8761                    && mInnerFields.mScreenBrightness < 0) {
8762                mInnerFields.mScreenBrightness = w.mAttrs.screenBrightness;
8763            }
8764            if (!mInnerFields.mSyswin && w.mAttrs.buttonBrightness >= 0
8765                    && mInnerFields.mButtonBrightness < 0) {
8766                mInnerFields.mButtonBrightness = w.mAttrs.buttonBrightness;
8767            }
8768            if (!mInnerFields.mSyswin && w.mAttrs.userActivityTimeout >= 0
8769                    && mInnerFields.mUserActivityTimeout < 0) {
8770                mInnerFields.mUserActivityTimeout = w.mAttrs.userActivityTimeout;
8771            }
8772
8773            final int type = attrs.type;
8774            if (canBeSeen
8775                    && (type == TYPE_SYSTEM_DIALOG
8776                     || type == TYPE_RECENTS_OVERLAY
8777                     || type == TYPE_KEYGUARD
8778                     || type == TYPE_SYSTEM_ERROR)) {
8779                mInnerFields.mSyswin = true;
8780            }
8781
8782            if (canBeSeen) {
8783                // This function assumes that the contents of the default display are
8784                // processed first before secondary displays.
8785                final DisplayContent displayContent = w.mDisplayContent;
8786                if (displayContent.isDefaultDisplay) {
8787                    // While a dream or keyguard is showing, obscure ordinary application
8788                    // content on secondary displays (by forcibly enabling mirroring unless
8789                    // there is other content we want to show) but still allow opaque
8790                    // keyguard dialogs to be shown.
8791                    if (type == TYPE_DREAM || type == TYPE_KEYGUARD) {
8792                        mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true;
8793                    }
8794                    mInnerFields.mDisplayHasContent = true;
8795                } else if (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays
8796                        || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG)) {
8797                    // Allow full screen keyguard presentation dialogs to be seen.
8798                    mInnerFields.mDisplayHasContent = true;
8799                }
8800            }
8801        }
8802    }
8803
8804    private void handleFlagDimBehind(WindowState w, int innerDw, int innerDh) {
8805        final WindowManager.LayoutParams attrs = w.mAttrs;
8806        if ((attrs.flags & FLAG_DIM_BEHIND) != 0
8807                && w.isDisplayedLw()
8808                && !w.mExiting) {
8809            final WindowStateAnimator winAnimator = w.mWinAnimator;
8810            final TaskStack stack = w.getStack();
8811            stack.setDimmingTag();
8812            if (!stack.isDimming(winAnimator)) {
8813                if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming.");
8814                stack.startDimmingIfNeeded(winAnimator);
8815            }
8816        }
8817    }
8818
8819    private void updateAllDrawnLocked(DisplayContent displayContent) {
8820        // See if any windows have been drawn, so they (and others
8821        // associated with them) can now be shown.
8822        final ArrayList<Task> tasks = displayContent.getTasks();
8823        final int numTasks = tasks.size();
8824        for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) {
8825            final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
8826            final int numTokens = tokens.size();
8827            for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) {
8828                final AppWindowToken wtoken = tokens.get(tokenNdx);
8829                if (!wtoken.allDrawn) {
8830                    int numInteresting = wtoken.numInterestingWindows;
8831                    if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
8832                        if (DEBUG_VISIBILITY) Slog.v(TAG,
8833                                "allDrawn: " + wtoken
8834                                + " interesting=" + numInteresting
8835                                + " drawn=" + wtoken.numDrawnWindows);
8836                        wtoken.allDrawn = true;
8837                        mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
8838                    }
8839                }
8840            }
8841        }
8842    }
8843
8844    // "Something has changed!  Let's make it correct now."
8845    private final void performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory) {
8846        if (DEBUG_WINDOW_TRACE) {
8847            Slog.v(TAG, "performLayoutAndPlaceSurfacesLockedInner: entry. Called by "
8848                    + Debug.getCallers(3));
8849        }
8850
8851        final long currentTime = SystemClock.uptimeMillis();
8852
8853        int i;
8854
8855        if (mFocusMayChange) {
8856            mFocusMayChange = false;
8857            updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
8858                    false /*updateInputWindows*/);
8859        }
8860
8861        // Initialize state of exiting tokens.
8862        final int numDisplays = mDisplayContents.size();
8863        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8864            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
8865            for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
8866                displayContent.mExitingTokens.get(i).hasVisible = false;
8867            }
8868
8869            // Initialize state of exiting applications.
8870            for (i=displayContent.mExitingAppTokens.size()-1; i>=0; i--) {
8871                displayContent.mExitingAppTokens.get(i).hasVisible = false;
8872            }
8873        }
8874
8875        mInnerFields.mHoldScreen = null;
8876        mInnerFields.mScreenBrightness = -1;
8877        mInnerFields.mButtonBrightness = -1;
8878        mInnerFields.mUserActivityTimeout = -1;
8879        mInnerFields.mObscureApplicationContentOnSecondaryDisplays = false;
8880
8881        mTransactionSequence++;
8882
8883        final DisplayContent defaultDisplay = getDefaultDisplayContentLocked();
8884        final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
8885        final int defaultDw = defaultInfo.logicalWidth;
8886        final int defaultDh = defaultInfo.logicalHeight;
8887
8888        if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
8889                ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
8890        SurfaceControl.openTransaction();
8891        try {
8892
8893            if (mWatermark != null) {
8894                mWatermark.positionSurface(defaultDw, defaultDh);
8895            }
8896            if (mStrictModeFlash != null) {
8897                mStrictModeFlash.positionSurface(defaultDw, defaultDh);
8898            }
8899
8900            boolean focusDisplayed = false;
8901
8902            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
8903                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
8904                boolean updateAllDrawn = false;
8905                WindowList windows = displayContent.getWindowList();
8906                DisplayInfo displayInfo = displayContent.getDisplayInfo();
8907                final int displayId = displayContent.getDisplayId();
8908                final int dw = displayInfo.logicalWidth;
8909                final int dh = displayInfo.logicalHeight;
8910                final int innerDw = displayInfo.appWidth;
8911                final int innerDh = displayInfo.appHeight;
8912                final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
8913
8914                // Reset for each display.
8915                mInnerFields.mDisplayHasContent = false;
8916
8917                int repeats = 0;
8918                do {
8919                    repeats++;
8920                    if (repeats > 6) {
8921                        Slog.w(TAG, "Animation repeat aborted after too many iterations");
8922                        displayContent.layoutNeeded = false;
8923                        break;
8924                    }
8925
8926                    if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("On entry to LockedInner",
8927                        displayContent.pendingLayoutChanges);
8928
8929                    if ((displayContent.pendingLayoutChanges &
8930                            WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
8931                            (adjustWallpaperWindowsLocked() &
8932                                    ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
8933                        assignLayersLocked(windows);
8934                        displayContent.layoutNeeded = true;
8935                    }
8936
8937                    if (isDefaultDisplay && (displayContent.pendingLayoutChanges
8938                            & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
8939                        if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
8940                        if (updateOrientationFromAppTokensLocked(true)) {
8941                            displayContent.layoutNeeded = true;
8942                            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
8943                        }
8944                    }
8945
8946                    if ((displayContent.pendingLayoutChanges
8947                            & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
8948                        displayContent.layoutNeeded = true;
8949                    }
8950
8951                    // FIRST LOOP: Perform a layout, if needed.
8952                    if (repeats < 4) {
8953                        performLayoutLockedInner(displayContent, repeats == 1,
8954                                false /*updateInputWindows*/);
8955                    } else {
8956                        Slog.w(TAG, "Layout repeat skipped after too many iterations");
8957                    }
8958
8959                    // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
8960                    // it is animating.
8961                    displayContent.pendingLayoutChanges = 0;
8962
8963                    if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("loop number "
8964                            + mLayoutRepeatCount, displayContent.pendingLayoutChanges);
8965
8966                    if (isDefaultDisplay) {
8967                        mPolicy.beginPostLayoutPolicyLw(dw, dh);
8968                        for (i = windows.size() - 1; i >= 0; i--) {
8969                            WindowState w = windows.get(i);
8970                            if (w.mHasSurface) {
8971                                mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs);
8972                            }
8973                        }
8974                        displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
8975                        if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
8976                            "after finishPostLayoutPolicyLw", displayContent.pendingLayoutChanges);
8977                    }
8978                } while (displayContent.pendingLayoutChanges != 0);
8979
8980                mInnerFields.mObscured = false;
8981                mInnerFields.mSyswin = false;
8982                displayContent.resetDimming();
8983
8984                // Only used if default window
8985                final boolean someoneLosingFocus = !mLosingFocus.isEmpty();
8986
8987                final int N = windows.size();
8988                for (i=N-1; i>=0; i--) {
8989                    WindowState w = windows.get(i);
8990                    final TaskStack stack = w.getStack();
8991                    if (stack == null) {
8992                        continue;
8993                    }
8994
8995                    final boolean obscuredChanged = w.mObscured != mInnerFields.mObscured;
8996
8997                    // Update effect.
8998                    w.mObscured = mInnerFields.mObscured;
8999                    if (!mInnerFields.mObscured) {
9000                        handleNotObscuredLocked(w, currentTime, innerDw, innerDh);
9001                    }
9002
9003                    if (!stack.testDimmingTag()) {
9004                        handleFlagDimBehind(w, innerDw, innerDh);
9005                    }
9006
9007                    if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
9008                            && w.isVisibleLw()) {
9009                        // This is the wallpaper target and its obscured state
9010                        // changed... make sure the current wallaper's visibility
9011                        // has been updated accordingly.
9012                        updateWallpaperVisibilityLocked();
9013                    }
9014
9015                    final WindowStateAnimator winAnimator = w.mWinAnimator;
9016
9017                    // If the window has moved due to its containing
9018                    // content frame changing, then we'd like to animate
9019                    // it.
9020                    if (w.mHasSurface && w.shouldAnimateMove()) {
9021                        // Frame has moved, containing content frame
9022                        // has also moved, and we're not currently animating...
9023                        // let's do something.
9024                        Animation a = AnimationUtils.loadAnimation(mContext,
9025                                com.android.internal.R.anim.window_move_from_decor);
9026                        winAnimator.setAnimation(a);
9027                        winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
9028                        winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
9029                        try {
9030                            w.mClient.moved(w.mFrame.left, w.mFrame.top);
9031                        } catch (RemoteException e) {
9032                        }
9033                    }
9034
9035                    //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
9036                    w.mContentChanged = false;
9037
9038                    // Moved from updateWindowsAndWallpaperLocked().
9039                    if (w.mHasSurface) {
9040                        // Take care of the window being ready to display.
9041                        final boolean committed =
9042                                winAnimator.commitFinishDrawingLocked(currentTime);
9043                        if (isDefaultDisplay && committed) {
9044                            if (w.mAttrs.type == TYPE_DREAM) {
9045                                // HACK: When a dream is shown, it may at that
9046                                // point hide the lock screen.  So we need to
9047                                // redo the layout to let the phone window manager
9048                                // make this happen.
9049                                displayContent.pendingLayoutChanges |=
9050                                        WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9051                                if (DEBUG_LAYOUT_REPEATS) {
9052                                    debugLayoutRepeats(
9053                                        "dream and commitFinishDrawingLocked true",
9054                                        displayContent.pendingLayoutChanges);
9055                                }
9056                            }
9057                            if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
9058                                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
9059                                        "First draw done in potential wallpaper target " + w);
9060                                mInnerFields.mWallpaperMayChange = true;
9061                                displayContent.pendingLayoutChanges |=
9062                                        WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9063                                if (DEBUG_LAYOUT_REPEATS) {
9064                                    debugLayoutRepeats(
9065                                        "wallpaper and commitFinishDrawingLocked true",
9066                                        displayContent.pendingLayoutChanges);
9067                                }
9068                            }
9069                        }
9070
9071                        winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
9072
9073                        final AppWindowToken atoken = w.mAppToken;
9074                        if (DEBUG_STARTING_WINDOW && atoken != null
9075                                && w == atoken.startingWindow) {
9076                            Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen="
9077                                + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
9078                                + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
9079                        }
9080                        if (atoken != null
9081                                && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
9082                            if (atoken.lastTransactionSequence != mTransactionSequence) {
9083                                atoken.lastTransactionSequence = mTransactionSequence;
9084                                atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
9085                                atoken.startingDisplayed = false;
9086                            }
9087                            if ((w.isOnScreen() || winAnimator.mAttrType == TYPE_BASE_APPLICATION)
9088                                    && !w.mExiting && !w.mDestroying) {
9089                                if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
9090                                    Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
9091                                            + ", isAnimating=" + winAnimator.isAnimating());
9092                                    if (!w.isDrawnLw()) {
9093                                        Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceControl
9094                                                + " pv=" + w.mPolicyVisibility
9095                                                + " mDrawState=" + winAnimator.mDrawState
9096                                                + " ah=" + w.mAttachedHidden
9097                                                + " th=" + atoken.hiddenRequested
9098                                                + " a=" + winAnimator.mAnimating);
9099                                    }
9100                                }
9101                                if (w != atoken.startingWindow) {
9102                                    if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
9103                                        atoken.numInterestingWindows++;
9104                                        if (w.isDrawnLw()) {
9105                                            atoken.numDrawnWindows++;
9106                                            if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
9107                                                    "tokenMayBeDrawn: " + atoken
9108                                                    + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
9109                                                    + " mAppFreezing=" + w.mAppFreezing);
9110                                            updateAllDrawn = true;
9111                                        }
9112                                    }
9113                                } else if (w.isDrawnLw()) {
9114                                    atoken.startingDisplayed = true;
9115                                }
9116                            }
9117                        }
9118                    }
9119
9120                    if (isDefaultDisplay && someoneLosingFocus && (w == mCurrentFocus)
9121                            && w.isDisplayedLw()) {
9122                        focusDisplayed = true;
9123                    }
9124
9125                    updateResizingWindows(w);
9126                }
9127
9128                mDisplayManagerService.setDisplayHasContent(displayId,
9129                        mInnerFields.mDisplayHasContent,
9130                        true /* inTraversal, must call performTraversalInTrans... below */);
9131
9132                getDisplayContentLocked(displayId).stopDimmingIfNeeded();
9133
9134                if (updateAllDrawn) {
9135                    updateAllDrawnLocked(displayContent);
9136                }
9137            }
9138
9139            if (focusDisplayed) {
9140                mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
9141            }
9142
9143            // Give the display manager a chance to adjust properties
9144            // like display rotation if it needs to.
9145            mDisplayManagerService.performTraversalInTransactionFromWindowManager();
9146
9147        } catch (RuntimeException e) {
9148            Log.wtf(TAG, "Unhandled exception in Window Manager", e);
9149        } finally {
9150            SurfaceControl.closeTransaction();
9151            if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
9152                    "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
9153        }
9154
9155        final WindowList defaultWindows = defaultDisplay.getWindowList();
9156
9157        // If we are ready to perform an app transition, check through
9158        // all of the app tokens to be shown and see if they are ready
9159        // to go.
9160        if (mAppTransition.isReady()) {
9161            defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
9162            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAppTransitionReadyLocked",
9163                    defaultDisplay.pendingLayoutChanges);
9164        }
9165
9166        if (!mAnimator.mAnimating && mAppTransition.isRunning()) {
9167            // We have finished the animation of an app transition.  To do
9168            // this, we have delayed a lot of operations like showing and
9169            // hiding apps, moving apps in Z-order, etc.  The app token list
9170            // reflects the correct Z-order, but the window list may now
9171            // be out of sync with it.  So here we will just rebuild the
9172            // entire app window list.  Fun!
9173            defaultDisplay.pendingLayoutChanges |= handleAnimatingStoppedAndTransitionLocked();
9174            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after handleAnimStopAndXitionLock",
9175                defaultDisplay.pendingLayoutChanges);
9176        }
9177
9178        if (mInnerFields.mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
9179                && !mAppTransition.isReady()) {
9180            // At this point, there was a window with a wallpaper that
9181            // was force hiding other windows behind it, but now it
9182            // is going away.  This may be simple -- just animate
9183            // away the wallpaper and its window -- or it may be
9184            // hard -- the wallpaper now needs to be shown behind
9185            // something that was hidden.
9186            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9187            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animateAwayWallpaperLocked",
9188                defaultDisplay.pendingLayoutChanges);
9189        }
9190        mInnerFields.mWallpaperForceHidingChanged = false;
9191
9192        if (mInnerFields.mWallpaperMayChange) {
9193            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change!  Adjusting");
9194            defaultDisplay.pendingLayoutChanges |=
9195                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9196            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
9197                    defaultDisplay.pendingLayoutChanges);
9198        }
9199
9200        if (mFocusMayChange) {
9201            mFocusMayChange = false;
9202            if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
9203                    false /*updateInputWindows*/)) {
9204                defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
9205            }
9206        }
9207
9208        if (needsLayout()) {
9209            defaultDisplay.pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9210            if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
9211                    defaultDisplay.pendingLayoutChanges);
9212        }
9213
9214        for (i = mResizingWindows.size() - 1; i >= 0; i--) {
9215            WindowState win = mResizingWindows.get(i);
9216            if (win.mAppFreezing) {
9217                // Don't remove this window until rotation has completed.
9218                continue;
9219            }
9220            final WindowStateAnimator winAnimator = win.mWinAnimator;
9221            try {
9222                if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
9223                        "Reporting new frame to " + win + ": " + win.mCompatFrame);
9224                int diff = 0;
9225                boolean configChanged = win.isConfigChanged();
9226                if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION)
9227                        && configChanged) {
9228                    Slog.i(TAG, "Sending new config to window " + win + ": "
9229                            + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH
9230                            + " / " + mCurConfiguration + " / 0x"
9231                            + Integer.toHexString(diff));
9232                }
9233                win.setConfiguration(mCurConfiguration);
9234                if (DEBUG_ORIENTATION &&
9235                        winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i(
9236                        TAG, "Resizing " + win + " WITH DRAW PENDING");
9237                final IWindow client = win.mClient;
9238                final Rect frame = win.mFrame;
9239                final Rect overscanInsets = win.mLastOverscanInsets;
9240                final Rect contentInsets = win.mLastContentInsets;
9241                final Rect visibleInsets = win.mLastVisibleInsets;
9242                final boolean reportDraw
9243                        = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
9244                final Configuration newConfig = configChanged ? win.mConfiguration : null;
9245                if (win.mClient instanceof IWindow.Stub) {
9246                    // To prevent deadlock simulate one-way call if win.mClient is a local object.
9247                    mH.post(new Runnable() {
9248                        @Override
9249                        public void run() {
9250                            try {
9251                                client.resized(frame, overscanInsets, contentInsets,
9252                                        visibleInsets, reportDraw, newConfig);
9253                            } catch (RemoteException e) {
9254                                // Not a remote call, RemoteException won't be raised.
9255                            }
9256                        }
9257                    });
9258                } else {
9259                   client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw,
9260                           newConfig);
9261                }
9262                win.mOverscanInsetsChanged = false;
9263                win.mContentInsetsChanged = false;
9264                win.mVisibleInsetsChanged = false;
9265                winAnimator.mSurfaceResized = false;
9266            } catch (RemoteException e) {
9267                win.mOrientationChanging = false;
9268                win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
9269                        - mDisplayFreezeTime);
9270            }
9271            mResizingWindows.remove(i);
9272        }
9273
9274        if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG,
9275                "With display frozen, orientationChangeComplete="
9276                + mInnerFields.mOrientationChangeComplete);
9277        if (mInnerFields.mOrientationChangeComplete) {
9278            if (mWindowsFreezingScreen) {
9279                mWindowsFreezingScreen = false;
9280                mLastFinishedFreezeSource = mInnerFields.mLastWindowFreezeSource;
9281                mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
9282            }
9283            stopFreezingDisplayLocked();
9284        }
9285
9286        // Destroy the surface of any windows that are no longer visible.
9287        boolean wallpaperDestroyed = false;
9288        i = mDestroySurface.size();
9289        if (i > 0) {
9290            do {
9291                i--;
9292                WindowState win = mDestroySurface.get(i);
9293                win.mDestroying = false;
9294                if (mInputMethodWindow == win) {
9295                    mInputMethodWindow = null;
9296                }
9297                if (win == mWallpaperTarget) {
9298                    wallpaperDestroyed = true;
9299                }
9300                win.mWinAnimator.destroySurfaceLocked();
9301            } while (i > 0);
9302            mDestroySurface.clear();
9303        }
9304
9305        // Time to remove any exiting tokens?
9306        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9307            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9308            ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
9309            for (i = exitingTokens.size() - 1; i >= 0; i--) {
9310                WindowToken token = exitingTokens.get(i);
9311                if (!token.hasVisible) {
9312                    exitingTokens.remove(i);
9313                    if (token.windowType == TYPE_WALLPAPER) {
9314                        mWallpaperTokens.remove(token);
9315                    }
9316                }
9317            }
9318
9319            // Time to remove any exiting applications?
9320            AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
9321            for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
9322                AppWindowToken token = exitingAppTokens.get(i);
9323                if (!token.hasVisible && !mClosingApps.contains(token)) {
9324                    // Make sure there is no animation running on this token,
9325                    // so any windows associated with it will be removed as
9326                    // soon as their animations are complete
9327                    token.mAppAnimator.clearAnimation();
9328                    token.mAppAnimator.animating = false;
9329                    if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
9330                            "performLayout: App token exiting now removed" + token);
9331                    final Task task = mTaskIdToTask.get(token.groupId);
9332                    if (task != null && task.removeAppToken(token)) {
9333                        mTaskIdToTask.delete(token.groupId);
9334                    }
9335                    exitingAppTokens.remove(i);
9336                }
9337            }
9338        }
9339
9340        if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
9341            for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
9342                try {
9343                    mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
9344                } catch (RemoteException e) {
9345                }
9346            }
9347            mRelayoutWhileAnimating.clear();
9348        }
9349
9350        if (wallpaperDestroyed) {
9351            defaultDisplay.pendingLayoutChanges |=
9352                    WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
9353            defaultDisplay.layoutNeeded = true;
9354        }
9355
9356        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9357            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9358            if (displayContent.pendingLayoutChanges != 0) {
9359                displayContent.layoutNeeded = true;
9360            }
9361        }
9362
9363        // Finally update all input windows now that the window changes have stabilized.
9364        mInputMonitor.updateInputWindowsLw(true /*force*/);
9365
9366        setHoldScreenLocked(mInnerFields.mHoldScreen);
9367        if (!mDisplayFrozen) {
9368            if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
9369                mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
9370            } else {
9371                mPowerManager.setScreenBrightnessOverrideFromWindowManager(
9372                        toBrightnessOverride(mInnerFields.mScreenBrightness));
9373            }
9374            if (mInnerFields.mButtonBrightness < 0 || mInnerFields.mButtonBrightness > 1.0f) {
9375                mPowerManager.setButtonBrightnessOverrideFromWindowManager(-1);
9376            } else {
9377                mPowerManager.setButtonBrightnessOverrideFromWindowManager(
9378                        toBrightnessOverride(mInnerFields.mButtonBrightness));
9379            }
9380            mPowerManager.setUserActivityTimeoutOverrideFromWindowManager(
9381                    mInnerFields.mUserActivityTimeout);
9382        }
9383
9384        if (mTurnOnScreen) {
9385            if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
9386            mPowerManager.wakeUp(SystemClock.uptimeMillis());
9387            mTurnOnScreen = false;
9388        }
9389
9390        if (mInnerFields.mUpdateRotation) {
9391            if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
9392            if (updateRotationUncheckedLocked(false)) {
9393                mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9394            } else {
9395                mInnerFields.mUpdateRotation = false;
9396            }
9397        }
9398
9399        if (mInnerFields.mOrientationChangeComplete && !defaultDisplay.layoutNeeded
9400                && !mInnerFields.mUpdateRotation) {
9401            checkDrawnWindowsLocked();
9402        }
9403
9404        final int N = mPendingRemove.size();
9405        if (N > 0) {
9406            if (mPendingRemoveTmp.length < N) {
9407                mPendingRemoveTmp = new WindowState[N+10];
9408            }
9409            mPendingRemove.toArray(mPendingRemoveTmp);
9410            mPendingRemove.clear();
9411            DisplayContentList displayList = new DisplayContentList();
9412            for (i = 0; i < N; i++) {
9413                WindowState w = mPendingRemoveTmp[i];
9414                removeWindowInnerLocked(w.mSession, w);
9415                if (!displayList.contains(w.mDisplayContent)) {
9416                    displayList.add(w.mDisplayContent);
9417                }
9418            }
9419
9420            for (DisplayContent displayContent : displayList) {
9421                assignLayersLocked(displayContent.getWindowList());
9422                displayContent.layoutNeeded = true;
9423            }
9424        }
9425
9426        setFocusedStackFrame();
9427
9428        // Check to see if we are now in a state where the screen should
9429        // be enabled, because the window obscured flags have changed.
9430        enableScreenIfNeededLocked();
9431
9432        scheduleAnimationLocked();
9433
9434        if (DEBUG_WINDOW_TRACE) {
9435            Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating="
9436                    + mAnimator.mAnimating);
9437        }
9438    }
9439
9440    private int toBrightnessOverride(float value) {
9441        return (int)(value * PowerManager.BRIGHTNESS_ON);
9442    }
9443
9444    void checkDrawnWindowsLocked() {
9445        if (mWaitingForDrawn.size() > 0) {
9446            for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
9447                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
9448                WindowState win = pair.first;
9449                //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
9450                //        + win.mRemoved + " visible=" + win.isVisibleLw()
9451                //        + " shown=" + win.mSurfaceShown);
9452                if (win.mRemoved) {
9453                    // Window has been removed; no draw will now happen, so stop waiting.
9454                    Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
9455                    try {
9456                        pair.second.sendResult(null);
9457                    } catch (RemoteException e) {
9458                    }
9459                    mWaitingForDrawn.remove(pair);
9460                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9461                } else if (win.mWinAnimator.mSurfaceShown) {
9462                    // Window is now drawn (and shown).
9463                    try {
9464                        pair.second.sendResult(null);
9465                    } catch (RemoteException e) {
9466                    }
9467                    mWaitingForDrawn.remove(pair);
9468                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9469                }
9470            }
9471        }
9472    }
9473
9474    @Override
9475    public boolean waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
9476        if (token != null && callback != null) {
9477            synchronized (mWindowMap) {
9478                WindowState win = windowForClientLocked(null, token, true);
9479                if (win != null) {
9480                    Pair<WindowState, IRemoteCallback> pair =
9481                            new Pair<WindowState, IRemoteCallback>(win, callback);
9482                    Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
9483                    mH.sendMessageDelayed(m, 2000);
9484                    mWaitingForDrawn.add(pair);
9485                    checkDrawnWindowsLocked();
9486                    return true;
9487                }
9488                Slog.i(TAG, "waitForWindowDrawn: win null");
9489            }
9490        }
9491        return false;
9492    }
9493
9494    void setHoldScreenLocked(final Session newHoldScreen) {
9495        final boolean hold = newHoldScreen != null;
9496
9497        if (hold && mHoldingScreenOn != newHoldScreen) {
9498            mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
9499        }
9500        mHoldingScreenOn = newHoldScreen;
9501
9502        final boolean state = mHoldingScreenWakeLock.isHeld();
9503        if (hold != state) {
9504            if (hold) {
9505                mHoldingScreenWakeLock.acquire();
9506                mPolicy.keepScreenOnStartedLw();
9507            } else {
9508                mPolicy.keepScreenOnStoppedLw();
9509                mHoldingScreenWakeLock.release();
9510            }
9511        }
9512    }
9513
9514    @Override
9515    public void requestTraversal() {
9516        synchronized (mWindowMap) {
9517            requestTraversalLocked();
9518        }
9519    }
9520
9521    void requestTraversalLocked() {
9522        if (!mTraversalScheduled) {
9523            mTraversalScheduled = true;
9524            mH.sendEmptyMessage(H.DO_TRAVERSAL);
9525        }
9526    }
9527
9528    /** Note that Locked in this case is on mLayoutToAnim */
9529    void scheduleAnimationLocked() {
9530        if (!mAnimationScheduled) {
9531            mAnimationScheduled = true;
9532            mChoreographer.postCallback(
9533                    Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null);
9534        }
9535    }
9536
9537    private boolean needsLayout() {
9538        final int numDisplays = mDisplayContents.size();
9539        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9540            final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
9541            if (displayContent.layoutNeeded) {
9542                return true;
9543            }
9544        }
9545        return false;
9546    }
9547
9548    boolean copyAnimToLayoutParamsLocked() {
9549        boolean doRequest = false;
9550
9551        final int bulkUpdateParams = mAnimator.mBulkUpdateParams;
9552        if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) {
9553            mInnerFields.mUpdateRotation = true;
9554            doRequest = true;
9555        }
9556        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) {
9557            mInnerFields.mWallpaperMayChange = true;
9558            doRequest = true;
9559        }
9560        if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) {
9561            mInnerFields.mWallpaperForceHidingChanged = true;
9562            doRequest = true;
9563        }
9564        if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
9565            mInnerFields.mOrientationChangeComplete = false;
9566        } else {
9567            mInnerFields.mOrientationChangeComplete = true;
9568            mInnerFields.mLastWindowFreezeSource = mAnimator.mLastWindowFreezeSource;
9569            if (mWindowsFreezingScreen) {
9570                doRequest = true;
9571            }
9572        }
9573        if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) {
9574            mTurnOnScreen = true;
9575        }
9576        if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) {
9577            mInnerFields.mWallpaperActionPending = true;
9578        }
9579
9580        return doRequest;
9581    }
9582
9583    /** If a window that has an animation specifying a colored background and the current wallpaper
9584     * is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
9585     * suddenly disappear. */
9586    int adjustAnimationBackground(WindowStateAnimator winAnimator) {
9587        WindowList windows = winAnimator.mWin.getWindowList();
9588        for (int i = windows.size() - 1; i >= 0; --i) {
9589            WindowState testWin = windows.get(i);
9590            if (testWin.mIsWallpaper && testWin.isVisibleNow()) {
9591                return testWin.mWinAnimator.mAnimLayer;
9592            }
9593        }
9594        return winAnimator.mAnimLayer;
9595    }
9596
9597    boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
9598                                           boolean secure) {
9599        final SurfaceControl surface = winAnimator.mSurfaceControl;
9600        boolean leakedSurface = false;
9601        boolean killedApps = false;
9602
9603        EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
9604                winAnimator.mSession.mPid, operation);
9605
9606        if (mForceRemoves == null) {
9607            mForceRemoves = new ArrayList<WindowState>();
9608        }
9609
9610        long callingIdentity = Binder.clearCallingIdentity();
9611        try {
9612            // There was some problem...   first, do a sanity check of the
9613            // window list to make sure we haven't left any dangling surfaces
9614            // around.
9615
9616            Slog.i(TAG, "Out of memory for surface!  Looking for leaks...");
9617            final int numDisplays = mDisplayContents.size();
9618            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9619                final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9620                final int numWindows = windows.size();
9621                for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9622                    final WindowState ws = windows.get(winNdx);
9623                    WindowStateAnimator wsa = ws.mWinAnimator;
9624                    if (wsa.mSurfaceControl != null) {
9625                        if (!mSessions.contains(wsa.mSession)) {
9626                            Slog.w(TAG, "LEAKED SURFACE (session doesn't exist): "
9627                                    + ws + " surface=" + wsa.mSurfaceControl
9628                                    + " token=" + ws.mToken
9629                                    + " pid=" + ws.mSession.mPid
9630                                    + " uid=" + ws.mSession.mUid);
9631                            if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9632                            wsa.mSurfaceControl.destroy();
9633                            wsa.mSurfaceShown = false;
9634                            wsa.mSurfaceControl = null;
9635                            ws.mHasSurface = false;
9636                            mForceRemoves.add(ws);
9637                            leakedSurface = true;
9638                        } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
9639                            Slog.w(TAG, "LEAKED SURFACE (app token hidden): "
9640                                    + ws + " surface=" + wsa.mSurfaceControl
9641                                    + " token=" + ws.mAppToken);
9642                            if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", null);
9643                            wsa.mSurfaceControl.destroy();
9644                            wsa.mSurfaceShown = false;
9645                            wsa.mSurfaceControl = null;
9646                            ws.mHasSurface = false;
9647                            leakedSurface = true;
9648                        }
9649                    }
9650                }
9651            }
9652
9653            if (!leakedSurface) {
9654                Slog.w(TAG, "No leaked surfaces; killing applicatons!");
9655                SparseIntArray pidCandidates = new SparseIntArray();
9656                for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
9657                    final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
9658                    final int numWindows = windows.size();
9659                    for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
9660                        final WindowState ws = windows.get(winNdx);
9661                        if (mForceRemoves.contains(ws)) {
9662                            continue;
9663                        }
9664                        WindowStateAnimator wsa = ws.mWinAnimator;
9665                        if (wsa.mSurfaceControl != null) {
9666                            pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
9667                        }
9668                    }
9669                    if (pidCandidates.size() > 0) {
9670                        int[] pids = new int[pidCandidates.size()];
9671                        for (int i=0; i<pids.length; i++) {
9672                            pids[i] = pidCandidates.keyAt(i);
9673                        }
9674                        try {
9675                            if (mActivityManager.killPids(pids, "Free memory", secure)) {
9676                                killedApps = true;
9677                            }
9678                        } catch (RemoteException e) {
9679                        }
9680                    }
9681                }
9682            }
9683
9684            if (leakedSurface || killedApps) {
9685                // We managed to reclaim some memory, so get rid of the trouble
9686                // surface and ask the app to request another one.
9687                Slog.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
9688                if (surface != null) {
9689                    if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
9690                            "RECOVER DESTROY", null);
9691                    surface.destroy();
9692                    winAnimator.mSurfaceShown = false;
9693                    winAnimator.mSurfaceControl = null;
9694                    winAnimator.mWin.mHasSurface = false;
9695                    scheduleRemoveStartingWindow(winAnimator.mWin.mAppToken);
9696                }
9697
9698                try {
9699                    winAnimator.mWin.mClient.dispatchGetNewSurface();
9700                } catch (RemoteException e) {
9701                }
9702            }
9703        } finally {
9704            Binder.restoreCallingIdentity(callingIdentity);
9705        }
9706
9707        return leakedSurface || killedApps;
9708    }
9709
9710    private boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
9711        WindowState newFocus = computeFocusedWindowLocked();
9712        if (mCurrentFocus != newFocus) {
9713            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
9714            // This check makes sure that we don't already have the focus
9715            // change message pending.
9716            mH.removeMessages(H.REPORT_FOCUS_CHANGE);
9717            mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
9718            // TODO(multidisplay): Focused windows on default display only.
9719            final DisplayContent displayContent = getDefaultDisplayContentLocked();
9720            final boolean imWindowChanged = moveInputMethodWindowsIfNeededLocked(
9721                    mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
9722                            && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
9723            if (imWindowChanged) {
9724                displayContent.layoutNeeded = true;
9725                newFocus = computeFocusedWindowLocked();
9726            }
9727
9728            if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG, "Changing focus from " +
9729                    mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4));
9730            final WindowState oldFocus = mCurrentFocus;
9731            mCurrentFocus = newFocus;
9732            mLosingFocus.remove(newFocus);
9733            int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
9734
9735            if (imWindowChanged && oldFocus != mInputMethodWindow) {
9736                // Focus of the input method window changed. Perform layout if needed.
9737                if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
9738                    performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
9739                    focusChanged &= ~WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
9740                } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
9741                    // Client will do the layout, but we need to assign layers
9742                    // for handleNewWindowLocked() below.
9743                    assignLayersLocked(displayContent.getWindowList());
9744                }
9745            }
9746
9747            if ((focusChanged & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
9748                // The change in focus caused us to need to do a layout.  Okay.
9749                displayContent.layoutNeeded = true;
9750                if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
9751                    performLayoutLockedInner(displayContent, true /*initial*/, updateInputWindows);
9752                }
9753            }
9754
9755            if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
9756                // If we defer assigning layers, then the caller is responsible for
9757                // doing this part.
9758                finishUpdateFocusedWindowAfterAssignLayersLocked(updateInputWindows);
9759            }
9760
9761            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
9762            return true;
9763        }
9764        return false;
9765    }
9766
9767    private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) {
9768        mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows);
9769    }
9770
9771    private WindowState computeFocusedWindowLocked() {
9772        if (mAnimator.mUniverseBackground != null
9773                && mAnimator.mUniverseBackground.mWin.canReceiveKeys()) {
9774            return mAnimator.mUniverseBackground.mWin;
9775        }
9776
9777        final int displayCount = mDisplayContents.size();
9778        for (int i = 0; i < displayCount; i++) {
9779            final DisplayContent displayContent = mDisplayContents.valueAt(i);
9780            WindowState win = findFocusedWindowLocked(displayContent);
9781            if (win != null) {
9782                return win;
9783            }
9784        }
9785        return null;
9786    }
9787
9788    private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
9789        final WindowList windows = displayContent.getWindowList();
9790        for (int i = windows.size() - 1; i >= 0; i--) {
9791            final WindowState win = windows.get(i);
9792
9793            if (localLOGV || DEBUG_FOCUS) Slog.v(
9794                TAG, "Looking for focus: " + i
9795                + " = " + win
9796                + ", flags=" + win.mAttrs.flags
9797                + ", canReceive=" + win.canReceiveKeys());
9798
9799            AppWindowToken wtoken = win.mAppToken;
9800
9801            // If this window's application has been removed, just skip it.
9802            if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) {
9803                if (DEBUG_FOCUS) Slog.v(TAG, "Skipping " + wtoken + " because "
9804                        + (wtoken.removed ? "removed" : "sendingToBottom"));
9805                continue;
9806            }
9807
9808            if (!win.canReceiveKeys()) {
9809                continue;
9810            }
9811
9812            // Descend through all of the app tokens and find the first that either matches
9813            // win.mAppToken (return win) or mFocusedApp (return null).
9814            if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING &&
9815                    mFocusedApp != null) {
9816                ArrayList<Task> tasks = displayContent.getTasks();
9817                for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
9818                    AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
9819                    int tokenNdx = tokens.size() - 1;
9820                    for ( ; tokenNdx >= 0; --tokenNdx) {
9821                        final AppWindowToken token = tokens.get(tokenNdx);
9822                        if (wtoken == token) {
9823                            break;
9824                        }
9825                        if (mFocusedApp == token) {
9826                            // Whoops, we are below the focused app...  no focus for you!
9827                            if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG,
9828                                    "findFocusedWindow: Reached focused app=" + mFocusedApp);
9829                            return null;
9830                        }
9831                    }
9832                    if (tokenNdx >= 0) {
9833                        // Early exit from loop, must have found the matching token.
9834                        break;
9835                    }
9836                }
9837            }
9838
9839            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: Found new focus @ " + i +
9840                        " = " + win);
9841            return win;
9842        }
9843
9844        if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "findFocusedWindow: No focusable windows.");
9845        return null;
9846    }
9847
9848    private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
9849        if (mDisplayFrozen) {
9850            return;
9851        }
9852
9853        if (!mDisplayReady || !mPolicy.isScreenOnFully()) {
9854            // No need to freeze the screen before the system is ready or if
9855            // the screen is off.
9856            return;
9857        }
9858
9859        mScreenFrozenLock.acquire();
9860
9861        mDisplayFrozen = true;
9862        mDisplayFreezeTime = SystemClock.elapsedRealtime();
9863        mLastFinishedFreezeSource = null;
9864
9865        mInputMonitor.freezeInputDispatchingLw();
9866
9867        // Clear the last input window -- that is just used for
9868        // clean transitions between IMEs, and if we are freezing
9869        // the screen then the whole world is changing behind the scenes.
9870        mPolicy.setLastInputMethodWindowLw(null, null);
9871
9872        if (mAppTransition.isTransitionSet()) {
9873            mAppTransition.freeze();
9874        }
9875
9876        if (PROFILE_ORIENTATION) {
9877            File file = new File("/data/system/frozen");
9878            Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
9879        }
9880
9881        if (CUSTOM_SCREEN_ROTATION) {
9882            mExitAnimId = exitAnim;
9883            mEnterAnimId = enterAnim;
9884            final DisplayContent displayContent = getDefaultDisplayContentLocked();
9885            final int displayId = displayContent.getDisplayId();
9886            ScreenRotationAnimation screenRotationAnimation =
9887                    mAnimator.getScreenRotationAnimationLocked(displayId);
9888            if (screenRotationAnimation != null) {
9889                screenRotationAnimation.kill();
9890            }
9891
9892            // TODO(multidisplay): rotation on main screen only.
9893            screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
9894                    mFxSession, inTransaction, mPolicy.isDefaultOrientationForced());
9895            mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
9896        }
9897    }
9898
9899    private void stopFreezingDisplayLocked() {
9900        if (!mDisplayFrozen) {
9901            return;
9902        }
9903
9904        if (mWaitingForConfig || mAppsFreezingScreen > 0 || mWindowsFreezingScreen
9905                || mClientFreezingScreen) {
9906            if (DEBUG_ORIENTATION) Slog.d(TAG,
9907                "stopFreezingDisplayLocked: Returning mWaitingForConfig=" + mWaitingForConfig
9908                + ", mAppsFreezingScreen=" + mAppsFreezingScreen
9909                + ", mWindowsFreezingScreen=" + mWindowsFreezingScreen
9910                + ", mClientFreezingScreen=" + mClientFreezingScreen);
9911            return;
9912        }
9913
9914        mDisplayFrozen = false;
9915        mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime);
9916        StringBuilder sb = new StringBuilder(128);
9917        sb.append("Screen frozen for ");
9918        TimeUtils.formatDuration(mLastDisplayFreezeDuration, sb);
9919        if (mLastFinishedFreezeSource != null) {
9920            sb.append(" due to ");
9921            sb.append(mLastFinishedFreezeSource);
9922        }
9923        Slog.i(TAG, sb.toString());
9924        mH.removeMessages(H.APP_FREEZE_TIMEOUT);
9925        mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT);
9926        if (PROFILE_ORIENTATION) {
9927            Debug.stopMethodTracing();
9928        }
9929
9930        boolean updateRotation = false;
9931
9932        final DisplayContent displayContent = getDefaultDisplayContentLocked();
9933        final int displayId = displayContent.getDisplayId();
9934        ScreenRotationAnimation screenRotationAnimation =
9935                mAnimator.getScreenRotationAnimationLocked(displayId);
9936        if (CUSTOM_SCREEN_ROTATION && screenRotationAnimation != null
9937                && screenRotationAnimation.hasScreenshot()) {
9938            if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
9939            // TODO(multidisplay): rotation on main screen only.
9940            DisplayInfo displayInfo = displayContent.getDisplayInfo();
9941            // Get rotation animation again, with new top window
9942            boolean isDimming = displayContent.isDimming();
9943            if (!mPolicy.validateRotationAnimationLw(mExitAnimId, mEnterAnimId, isDimming)) {
9944                mExitAnimId = mEnterAnimId = 0;
9945            }
9946            if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
9947                    mTransitionAnimationScale, displayInfo.logicalWidth,
9948                        displayInfo.logicalHeight, mExitAnimId, mEnterAnimId)) {
9949                scheduleAnimationLocked();
9950            } else {
9951                screenRotationAnimation.kill();
9952                screenRotationAnimation = null;
9953                mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
9954                updateRotation = true;
9955            }
9956        } else {
9957            if (screenRotationAnimation != null) {
9958                screenRotationAnimation.kill();
9959                screenRotationAnimation = null;
9960                mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation);
9961            }
9962            updateRotation = true;
9963        }
9964
9965        mInputMonitor.thawInputDispatchingLw();
9966
9967        boolean configChanged;
9968
9969        // While the display is frozen we don't re-compute the orientation
9970        // to avoid inconsistent states.  However, something interesting
9971        // could have actually changed during that time so re-evaluate it
9972        // now to catch that.
9973        configChanged = updateOrientationFromAppTokensLocked(false);
9974
9975        // A little kludge: a lot could have happened while the
9976        // display was frozen, so now that we are coming back we
9977        // do a gc so that any remote references the system
9978        // processes holds on others can be released if they are
9979        // no longer needed.
9980        mH.removeMessages(H.FORCE_GC);
9981        mH.sendEmptyMessageDelayed(H.FORCE_GC, 2000);
9982
9983        mScreenFrozenLock.release();
9984
9985        if (updateRotation) {
9986            if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
9987            configChanged |= updateRotationUncheckedLocked(false);
9988        }
9989
9990        if (configChanged) {
9991            mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
9992        }
9993    }
9994
9995    static int getPropertyInt(String[] tokens, int index, int defUnits, int defDps,
9996            DisplayMetrics dm) {
9997        if (index < tokens.length) {
9998            String str = tokens[index];
9999            if (str != null && str.length() > 0) {
10000                try {
10001                    int val = Integer.parseInt(str);
10002                    return val;
10003                } catch (Exception e) {
10004                }
10005            }
10006        }
10007        if (defUnits == TypedValue.COMPLEX_UNIT_PX) {
10008            return defDps;
10009        }
10010        int val = (int)TypedValue.applyDimension(defUnits, defDps, dm);
10011        return val;
10012    }
10013
10014    void createWatermarkInTransaction() {
10015        if (mWatermark != null) {
10016            return;
10017        }
10018
10019        File file = new File("/system/etc/setup.conf");
10020        FileInputStream in = null;
10021        DataInputStream ind = null;
10022        try {
10023            in = new FileInputStream(file);
10024            ind = new DataInputStream(in);
10025            String line = ind.readLine();
10026            if (line != null) {
10027                String[] toks = line.split("%");
10028                if (toks != null && toks.length > 0) {
10029                    mWatermark = new Watermark(getDefaultDisplayContentLocked().getDisplay(),
10030                            mRealDisplayMetrics, mFxSession, toks);
10031                }
10032            }
10033        } catch (FileNotFoundException e) {
10034        } catch (IOException e) {
10035        } finally {
10036            if (ind != null) {
10037                try {
10038                    ind.close();
10039                } catch (IOException e) {
10040                }
10041            } else if (in != null) {
10042                try {
10043                    in.close();
10044                } catch (IOException e) {
10045                }
10046            }
10047        }
10048    }
10049
10050    @Override
10051    public void statusBarVisibilityChanged(int visibility) {
10052        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
10053                != PackageManager.PERMISSION_GRANTED) {
10054            throw new SecurityException("Caller does not hold permission "
10055                    + android.Manifest.permission.STATUS_BAR);
10056        }
10057
10058        synchronized (mWindowMap) {
10059            mLastStatusBarVisibility = visibility;
10060            visibility = mPolicy.adjustSystemUiVisibilityLw(visibility);
10061            updateStatusBarVisibilityLocked(visibility);
10062        }
10063    }
10064
10065    // TOOD(multidisplay): StatusBar on multiple screens?
10066    void updateStatusBarVisibilityLocked(int visibility) {
10067        mInputManager.setSystemUiVisibility(visibility);
10068        final WindowList windows = getDefaultWindowListLocked();
10069        final int N = windows.size();
10070        for (int i = 0; i < N; i++) {
10071            WindowState ws = windows.get(i);
10072            try {
10073                int curValue = ws.mSystemUiVisibility;
10074                int diff = curValue ^ visibility;
10075                // We are only interested in differences of one of the
10076                // clearable flags...
10077                diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
10078                // ...if it has actually been cleared.
10079                diff &= ~visibility;
10080                int newValue = (curValue&~diff) | (visibility&diff);
10081                if (newValue != curValue) {
10082                    ws.mSeq++;
10083                    ws.mSystemUiVisibility = newValue;
10084                }
10085                if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
10086                    ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
10087                            visibility, newValue, diff);
10088                }
10089            } catch (RemoteException e) {
10090                // so sorry
10091            }
10092        }
10093    }
10094
10095    @Override
10096    public void reevaluateStatusBarVisibility() {
10097        synchronized (mWindowMap) {
10098            int visibility = mPolicy.adjustSystemUiVisibilityLw(mLastStatusBarVisibility);
10099            updateStatusBarVisibilityLocked(visibility);
10100            performLayoutAndPlaceSurfacesLocked();
10101        }
10102    }
10103
10104    @Override
10105    public FakeWindow addFakeWindow(Looper looper,
10106            InputEventReceiver.Factory inputEventReceiverFactory,
10107            String name, int windowType, int layoutParamsFlags, int layoutParamsPrivateFlags,
10108            boolean canReceiveKeys, boolean hasFocus, boolean touchFullscreen) {
10109        synchronized (mWindowMap) {
10110            FakeWindowImpl fw = new FakeWindowImpl(this, looper, inputEventReceiverFactory,
10111                    name, windowType,
10112                    layoutParamsFlags, layoutParamsPrivateFlags, canReceiveKeys,
10113                    hasFocus, touchFullscreen);
10114            int i=0;
10115            while (i<mFakeWindows.size()) {
10116                if (mFakeWindows.get(i).mWindowLayer <= fw.mWindowLayer) {
10117                    break;
10118                }
10119            }
10120            mFakeWindows.add(i, fw);
10121            mInputMonitor.updateInputWindowsLw(true);
10122            return fw;
10123        }
10124    }
10125
10126    boolean removeFakeWindowLocked(FakeWindow window) {
10127        synchronized (mWindowMap) {
10128            if (mFakeWindows.remove(window)) {
10129                mInputMonitor.updateInputWindowsLw(true);
10130                return true;
10131            }
10132            return false;
10133        }
10134    }
10135
10136    // It is assumed that this method is called only by InputMethodManagerService.
10137    public void saveLastInputMethodWindowForTransition() {
10138        synchronized (mWindowMap) {
10139            // TODO(multidisplay): Pass in the displayID.
10140            DisplayContent displayContent = getDefaultDisplayContentLocked();
10141            if (mInputMethodWindow != null) {
10142                mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
10143            }
10144        }
10145    }
10146
10147    @Override
10148    public boolean hasNavigationBar() {
10149        return mPolicy.hasNavigationBar();
10150    }
10151
10152    @Override
10153    public void lockNow(Bundle options) {
10154        mPolicy.lockNow(options);
10155    }
10156
10157    @Override
10158    public boolean isSafeModeEnabled() {
10159        return mSafeMode;
10160    }
10161
10162    void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
10163        pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
10164        mPolicy.dump("    ", pw, args);
10165    }
10166
10167    void dumpAnimatorLocked(PrintWriter pw, String[] args, boolean dumpAll) {
10168        pw.println("WINDOW MANAGER ANIMATOR STATE (dumpsys window animator)");
10169        mAnimator.dumpLocked(pw, "    ", dumpAll);
10170    }
10171
10172    void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
10173        pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
10174        if (mTokenMap.size() > 0) {
10175            pw.println("  All tokens:");
10176            Iterator<WindowToken> it = mTokenMap.values().iterator();
10177            while (it.hasNext()) {
10178                WindowToken token = it.next();
10179                pw.print("  "); pw.print(token);
10180                if (dumpAll) {
10181                    pw.println(':');
10182                    token.dump(pw, "    ");
10183                } else {
10184                    pw.println();
10185                }
10186            }
10187        }
10188        if (mWallpaperTokens.size() > 0) {
10189            pw.println();
10190            pw.println("  Wallpaper tokens:");
10191            for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
10192                WindowToken token = mWallpaperTokens.get(i);
10193                pw.print("  Wallpaper #"); pw.print(i);
10194                        pw.print(' '); pw.print(token);
10195                if (dumpAll) {
10196                    pw.println(':');
10197                    token.dump(pw, "    ");
10198                } else {
10199                    pw.println();
10200                }
10201            }
10202        }
10203        if (mFinishedStarting.size() > 0) {
10204            pw.println();
10205            pw.println("  Finishing start of application tokens:");
10206            for (int i=mFinishedStarting.size()-1; i>=0; i--) {
10207                WindowToken token = mFinishedStarting.get(i);
10208                pw.print("  Finished Starting #"); pw.print(i);
10209                        pw.print(' '); pw.print(token);
10210                if (dumpAll) {
10211                    pw.println(':');
10212                    token.dump(pw, "    ");
10213                } else {
10214                    pw.println();
10215                }
10216            }
10217        }
10218        if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
10219            pw.println();
10220            if (mOpeningApps.size() > 0) {
10221                pw.print("  mOpeningApps="); pw.println(mOpeningApps);
10222            }
10223            if (mClosingApps.size() > 0) {
10224                pw.print("  mClosingApps="); pw.println(mClosingApps);
10225            }
10226        }
10227    }
10228
10229    void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
10230        pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
10231        if (mSessions.size() > 0) {
10232            Iterator<Session> it = mSessions.iterator();
10233            while (it.hasNext()) {
10234                Session s = it.next();
10235                pw.print("  Session "); pw.print(s); pw.println(':');
10236                s.dump(pw, "    ");
10237            }
10238        }
10239    }
10240
10241    void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
10242        pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
10243        if (mDisplayReady) {
10244            final int numDisplays = mDisplayContents.size();
10245            for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10246                final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
10247                displayContent.dump("  ", pw);
10248            }
10249        } else {
10250            pw.println("  NO DISPLAY");
10251        }
10252    }
10253
10254    void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
10255            ArrayList<WindowState> windows) {
10256        pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
10257        dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
10258    }
10259
10260    void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
10261            ArrayList<WindowState> windows) {
10262        final int numDisplays = mDisplayContents.size();
10263        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10264            final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
10265            for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10266                final WindowState w = windowList.get(winNdx);
10267                if (windows == null || windows.contains(w)) {
10268                    pw.print("  Window #"); pw.print(winNdx); pw.print(' ');
10269                            pw.print(w); pw.println(":");
10270                    w.dump(pw, "    ", dumpAll || windows != null);
10271                }
10272            }
10273        }
10274        if (mInputMethodDialogs.size() > 0) {
10275            pw.println();
10276            pw.println("  Input method dialogs:");
10277            for (int i=mInputMethodDialogs.size()-1; i>=0; i--) {
10278                WindowState w = mInputMethodDialogs.get(i);
10279                if (windows == null || windows.contains(w)) {
10280                    pw.print("  IM Dialog #"); pw.print(i); pw.print(": "); pw.println(w);
10281                }
10282            }
10283        }
10284        if (mPendingRemove.size() > 0) {
10285            pw.println();
10286            pw.println("  Remove pending for:");
10287            for (int i=mPendingRemove.size()-1; i>=0; i--) {
10288                WindowState w = mPendingRemove.get(i);
10289                if (windows == null || windows.contains(w)) {
10290                    pw.print("  Remove #"); pw.print(i); pw.print(' ');
10291                            pw.print(w);
10292                    if (dumpAll) {
10293                        pw.println(":");
10294                        w.dump(pw, "    ", true);
10295                    } else {
10296                        pw.println();
10297                    }
10298                }
10299            }
10300        }
10301        if (mForceRemoves != null && mForceRemoves.size() > 0) {
10302            pw.println();
10303            pw.println("  Windows force removing:");
10304            for (int i=mForceRemoves.size()-1; i>=0; i--) {
10305                WindowState w = mForceRemoves.get(i);
10306                pw.print("  Removing #"); pw.print(i); pw.print(' ');
10307                        pw.print(w);
10308                if (dumpAll) {
10309                    pw.println(":");
10310                    w.dump(pw, "    ", true);
10311                } else {
10312                    pw.println();
10313                }
10314            }
10315        }
10316        if (mDestroySurface.size() > 0) {
10317            pw.println();
10318            pw.println("  Windows waiting to destroy their surface:");
10319            for (int i=mDestroySurface.size()-1; i>=0; i--) {
10320                WindowState w = mDestroySurface.get(i);
10321                if (windows == null || windows.contains(w)) {
10322                    pw.print("  Destroy #"); pw.print(i); pw.print(' ');
10323                            pw.print(w);
10324                    if (dumpAll) {
10325                        pw.println(":");
10326                        w.dump(pw, "    ", true);
10327                    } else {
10328                        pw.println();
10329                    }
10330                }
10331            }
10332        }
10333        if (mLosingFocus.size() > 0) {
10334            pw.println();
10335            pw.println("  Windows losing focus:");
10336            for (int i=mLosingFocus.size()-1; i>=0; i--) {
10337                WindowState w = mLosingFocus.get(i);
10338                if (windows == null || windows.contains(w)) {
10339                    pw.print("  Losing #"); pw.print(i); pw.print(' ');
10340                            pw.print(w);
10341                    if (dumpAll) {
10342                        pw.println(":");
10343                        w.dump(pw, "    ", true);
10344                    } else {
10345                        pw.println();
10346                    }
10347                }
10348            }
10349        }
10350        if (mResizingWindows.size() > 0) {
10351            pw.println();
10352            pw.println("  Windows waiting to resize:");
10353            for (int i=mResizingWindows.size()-1; i>=0; i--) {
10354                WindowState w = mResizingWindows.get(i);
10355                if (windows == null || windows.contains(w)) {
10356                    pw.print("  Resizing #"); pw.print(i); pw.print(' ');
10357                            pw.print(w);
10358                    if (dumpAll) {
10359                        pw.println(":");
10360                        w.dump(pw, "    ", true);
10361                    } else {
10362                        pw.println();
10363                    }
10364                }
10365            }
10366        }
10367        if (mWaitingForDrawn.size() > 0) {
10368            pw.println();
10369            pw.println("  Clients waiting for these windows to be drawn:");
10370            for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
10371                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
10372                pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
10373                        pw.print(": "); pw.println(pair.second);
10374            }
10375        }
10376        pw.println();
10377        pw.print("  mCurConfiguration="); pw.println(this.mCurConfiguration);
10378        pw.print("  mCurrentFocus="); pw.println(mCurrentFocus);
10379        if (mLastFocus != mCurrentFocus) {
10380            pw.print("  mLastFocus="); pw.println(mLastFocus);
10381        }
10382        pw.print("  mFocusedApp="); pw.println(mFocusedApp);
10383        if (mInputMethodTarget != null) {
10384            pw.print("  mInputMethodTarget="); pw.println(mInputMethodTarget);
10385        }
10386        pw.print("  mInTouchMode="); pw.print(mInTouchMode);
10387                pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
10388        pw.print("  mLastDisplayFreezeDuration=");
10389                TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
10390                if ( mLastFinishedFreezeSource != null) {
10391                    pw.print(" due to ");
10392                    pw.print(mLastFinishedFreezeSource);
10393                }
10394                pw.println();
10395        if (dumpAll) {
10396            pw.print("  mSystemDecorLayer="); pw.print(mSystemDecorLayer);
10397                    pw.print(" mScreenRect="); pw.println(mScreenRect.toShortString());
10398            if (mLastStatusBarVisibility != 0) {
10399                pw.print("  mLastStatusBarVisibility=0x");
10400                        pw.println(Integer.toHexString(mLastStatusBarVisibility));
10401            }
10402            if (mInputMethodWindow != null) {
10403                pw.print("  mInputMethodWindow="); pw.println(mInputMethodWindow);
10404            }
10405            pw.print("  mWallpaperTarget="); pw.println(mWallpaperTarget);
10406            if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
10407                pw.print("  mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
10408                pw.print("  mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
10409            }
10410            pw.print("  mLastWallpaperX="); pw.print(mLastWallpaperX);
10411                    pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
10412            if (mInputMethodAnimLayerAdjustment != 0 ||
10413                    mWallpaperAnimLayerAdjustment != 0) {
10414                pw.print("  mInputMethodAnimLayerAdjustment=");
10415                        pw.print(mInputMethodAnimLayerAdjustment);
10416                        pw.print("  mWallpaperAnimLayerAdjustment=");
10417                        pw.println(mWallpaperAnimLayerAdjustment);
10418            }
10419            pw.print("  mSystemBooted="); pw.print(mSystemBooted);
10420                    pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
10421            if (needsLayout()) {
10422                pw.print("  layoutNeeded on displays=");
10423                for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10424                    final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
10425                    if (displayContent.layoutNeeded) {
10426                        pw.print(displayContent.getDisplayId());
10427                    }
10428                }
10429                pw.println();
10430            }
10431            pw.print("  mTransactionSequence="); pw.println(mTransactionSequence);
10432            pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
10433                    pw.print(" windows="); pw.print(mWindowsFreezingScreen);
10434                    pw.print(" client="); pw.print(mClientFreezingScreen);
10435                    pw.print(" apps="); pw.print(mAppsFreezingScreen);
10436                    pw.print(" waitingForConfig="); pw.println(mWaitingForConfig);
10437            pw.print("  mRotation="); pw.print(mRotation);
10438                    pw.print(" mAltOrientation="); pw.println(mAltOrientation);
10439            pw.print("  mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
10440                    pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
10441            pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
10442            pw.print("  mWindowAnimationScale="); pw.print(mWindowAnimationScale);
10443                    pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
10444                    pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
10445            pw.print("  mTraversalScheduled="); pw.println(mTraversalScheduled);
10446            pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
10447                    pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
10448            pw.println("  mLayoutToAnim:");
10449            mAppTransition.dump(pw);
10450        }
10451    }
10452
10453    boolean dumpWindows(PrintWriter pw, String name, String[] args,
10454            int opti, boolean dumpAll) {
10455        WindowList windows = new WindowList();
10456        if ("visible".equals(name)) {
10457            synchronized(mWindowMap) {
10458                final int numDisplays = mDisplayContents.size();
10459                for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10460                    final WindowList windowList =
10461                            mDisplayContents.valueAt(displayNdx).getWindowList();
10462                    for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10463                        final WindowState w = windowList.get(winNdx);
10464                        if (w.mWinAnimator.mSurfaceShown) {
10465                            windows.add(w);
10466                        }
10467                    }
10468                }
10469            }
10470        } else {
10471            int objectId = 0;
10472            // See if this is an object ID.
10473            try {
10474                objectId = Integer.parseInt(name, 16);
10475                name = null;
10476            } catch (RuntimeException e) {
10477            }
10478            synchronized(mWindowMap) {
10479                final int numDisplays = mDisplayContents.size();
10480                for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
10481                    final WindowList windowList =
10482                            mDisplayContents.valueAt(displayNdx).getWindowList();
10483                    for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
10484                        final WindowState w = windowList.get(winNdx);
10485                        if (name != null) {
10486                            if (w.mAttrs.getTitle().toString().contains(name)) {
10487                                windows.add(w);
10488                            }
10489                        } else if (System.identityHashCode(w) == objectId) {
10490                            windows.add(w);
10491                        }
10492                    }
10493                }
10494            }
10495        }
10496
10497        if (windows.size() <= 0) {
10498            return false;
10499        }
10500
10501        synchronized(mWindowMap) {
10502            dumpWindowsLocked(pw, dumpAll, windows);
10503        }
10504        return true;
10505    }
10506
10507    void dumpLastANRLocked(PrintWriter pw) {
10508        pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
10509        if (mLastANRState == null) {
10510            pw.println("  <no ANR has occurred since boot>");
10511        } else {
10512            pw.println(mLastANRState);
10513        }
10514    }
10515
10516    /**
10517     * Saves information about the state of the window manager at
10518     * the time an ANR occurred before anything else in the system changes
10519     * in response.
10520     *
10521     * @param appWindowToken The application that ANR'd, may be null.
10522     * @param windowState The window that ANR'd, may be null.
10523     * @param reason The reason for the ANR, may be null.
10524     */
10525    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState,
10526            String reason) {
10527        StringWriter sw = new StringWriter();
10528        PrintWriter pw = new FastPrintWriter(sw, false, 1024);
10529        pw.println("  ANR time: " + DateFormat.getInstance().format(new Date()));
10530        if (appWindowToken != null) {
10531            pw.println("  Application at fault: " + appWindowToken.stringName);
10532        }
10533        if (windowState != null) {
10534            pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
10535        }
10536        if (reason != null) {
10537            pw.println("  Reason: " + reason);
10538        }
10539        pw.println();
10540        dumpWindowsNoHeaderLocked(pw, true, null);
10541        pw.close();
10542        mLastANRState = sw.toString();
10543    }
10544
10545    @Override
10546    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10547        if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
10548                != PackageManager.PERMISSION_GRANTED) {
10549            pw.println("Permission Denial: can't dump WindowManager from from pid="
10550                    + Binder.getCallingPid()
10551                    + ", uid=" + Binder.getCallingUid());
10552            return;
10553        }
10554
10555        boolean dumpAll = false;
10556
10557        int opti = 0;
10558        while (opti < args.length) {
10559            String opt = args[opti];
10560            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10561                break;
10562            }
10563            opti++;
10564            if ("-a".equals(opt)) {
10565                dumpAll = true;
10566            } else if ("-h".equals(opt)) {
10567                pw.println("Window manager dump options:");
10568                pw.println("  [-a] [-h] [cmd] ...");
10569                pw.println("  cmd may be one of:");
10570                pw.println("    l[astanr]: last ANR information");
10571                pw.println("    p[policy]: policy state");
10572                pw.println("    a[animator]: animator state");
10573                pw.println("    s[essions]: active sessions");
10574                pw.println("    d[isplays]: active display contents");
10575                pw.println("    t[okens]: token list");
10576                pw.println("    w[indows]: window list");
10577                pw.println("  cmd may also be a NAME to dump windows.  NAME may");
10578                pw.println("    be a partial substring in a window name, a");
10579                pw.println("    Window hex object identifier, or");
10580                pw.println("    \"all\" for all windows, or");
10581                pw.println("    \"visible\" for the visible windows.");
10582                pw.println("  -a: include all available server state.");
10583                return;
10584            } else {
10585                pw.println("Unknown argument: " + opt + "; use -h for help");
10586            }
10587        }
10588
10589        // Is the caller requesting to dump a particular piece of data?
10590        if (opti < args.length) {
10591            String cmd = args[opti];
10592            opti++;
10593            if ("lastanr".equals(cmd) || "l".equals(cmd)) {
10594                synchronized(mWindowMap) {
10595                    dumpLastANRLocked(pw);
10596                }
10597                return;
10598            } else if ("policy".equals(cmd) || "p".equals(cmd)) {
10599                synchronized(mWindowMap) {
10600                    dumpPolicyLocked(pw, args, true);
10601                }
10602                return;
10603            } else if ("animator".equals(cmd) || "a".equals(cmd)) {
10604                synchronized(mWindowMap) {
10605                    dumpAnimatorLocked(pw, args, true);
10606                }
10607                return;
10608            } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
10609                synchronized(mWindowMap) {
10610                    dumpSessionsLocked(pw, true);
10611                }
10612                return;
10613            } else if ("displays".equals(cmd) || "d".equals(cmd)) {
10614                synchronized(mWindowMap) {
10615                    dumpDisplayContentsLocked(pw, true);
10616                }
10617                return;
10618            } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
10619                synchronized(mWindowMap) {
10620                    dumpTokensLocked(pw, true);
10621                }
10622                return;
10623            } else if ("windows".equals(cmd) || "w".equals(cmd)) {
10624                synchronized(mWindowMap) {
10625                    dumpWindowsLocked(pw, true, null);
10626                }
10627                return;
10628            } else if ("all".equals(cmd) || "a".equals(cmd)) {
10629                synchronized(mWindowMap) {
10630                    dumpWindowsLocked(pw, true, null);
10631                }
10632                return;
10633            } else {
10634                // Dumping a single name?
10635                if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
10636                    pw.println("Bad window command, or no windows match: " + cmd);
10637                    pw.println("Use -h for help.");
10638                }
10639                return;
10640            }
10641        }
10642
10643        synchronized(mWindowMap) {
10644            pw.println();
10645            if (dumpAll) {
10646                pw.println("-------------------------------------------------------------------------------");
10647            }
10648            dumpLastANRLocked(pw);
10649            pw.println();
10650            if (dumpAll) {
10651                pw.println("-------------------------------------------------------------------------------");
10652            }
10653            dumpPolicyLocked(pw, args, dumpAll);
10654            pw.println();
10655            if (dumpAll) {
10656                pw.println("-------------------------------------------------------------------------------");
10657            }
10658            dumpAnimatorLocked(pw, args, dumpAll);
10659            pw.println();
10660            if (dumpAll) {
10661                pw.println("-------------------------------------------------------------------------------");
10662            }
10663            dumpSessionsLocked(pw, dumpAll);
10664            pw.println();
10665            if (dumpAll) {
10666                pw.println("-------------------------------------------------------------------------------");
10667            }
10668            dumpDisplayContentsLocked(pw, dumpAll);
10669            pw.println();
10670            if (dumpAll) {
10671                pw.println("-------------------------------------------------------------------------------");
10672            }
10673            dumpTokensLocked(pw, dumpAll);
10674            pw.println();
10675            if (dumpAll) {
10676                pw.println("-------------------------------------------------------------------------------");
10677            }
10678            dumpWindowsLocked(pw, dumpAll, null);
10679        }
10680    }
10681
10682    // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection).
10683    @Override
10684    public void monitor() {
10685        synchronized (mWindowMap) { }
10686    }
10687
10688    public interface OnHardKeyboardStatusChangeListener {
10689        public void onHardKeyboardStatusChange(boolean available, boolean enabled);
10690    }
10691
10692    void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
10693        if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
10694            Slog.v(TAG, "Layouts looping: " + msg + ", mPendingLayoutChanges = 0x" +
10695                    Integer.toHexString(pendingLayoutChanges));
10696        }
10697    }
10698
10699    private DisplayContent newDisplayContentLocked(final Display display) {
10700        DisplayContent displayContent = new DisplayContent(display, this);
10701        final int displayId = display.getDisplayId();
10702        mDisplayContents.put(displayId, displayContent);
10703
10704        DisplayInfo displayInfo = displayContent.getDisplayInfo();
10705        final Rect rect = new Rect();
10706        mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
10707        synchronized (displayContent.mDisplaySizeLock) {
10708            displayInfo.overscanLeft = rect.left;
10709            displayInfo.overscanTop = rect.top;
10710            displayInfo.overscanRight = rect.right;
10711            displayInfo.overscanBottom = rect.bottom;
10712            mDisplayManagerService.setDisplayInfoOverrideFromWindowManager(
10713                    displayId, displayInfo);
10714        }
10715        configureDisplayPolicyLocked(displayContent);
10716
10717        // TODO: Create an input channel for each display with touch capability.
10718        if (displayId == Display.DEFAULT_DISPLAY) {
10719            displayContent.mTapDetector = new StackTapPointerEventListener(this, displayContent);
10720            registerPointerEventListener(displayContent.mTapDetector);
10721        }
10722
10723        return displayContent;
10724    }
10725
10726    public void createDisplayContentLocked(final Display display) {
10727        if (display == null) {
10728            throw new IllegalArgumentException("getDisplayContent: display must not be null");
10729        }
10730        getDisplayContentLocked(display.getDisplayId());
10731    }
10732
10733    /**
10734     * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
10735     * there is a Display for the displayId.
10736     * @param displayId The display the caller is interested in.
10737     * @return The DisplayContent associated with displayId or null if there is no Display for it.
10738     */
10739    public DisplayContent getDisplayContentLocked(final int displayId) {
10740        DisplayContent displayContent = mDisplayContents.get(displayId);
10741        if (displayContent == null) {
10742            final Display display = mDisplayManager.getDisplay(displayId);
10743            if (display != null) {
10744                displayContent = newDisplayContentLocked(display);
10745            }
10746        }
10747        return displayContent;
10748    }
10749
10750    // There is an inherent assumption that this will never return null.
10751    public DisplayContent getDefaultDisplayContentLocked() {
10752        return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
10753    }
10754
10755    public WindowList getDefaultWindowListLocked() {
10756        return getDefaultDisplayContentLocked().getWindowList();
10757    }
10758
10759    public DisplayInfo getDefaultDisplayInfoLocked() {
10760        return getDefaultDisplayContentLocked().getDisplayInfo();
10761    }
10762
10763    /**
10764     * Return the list of WindowStates associated on the passed display.
10765     * @param display The screen to return windows from.
10766     * @return The list of WindowStates on the screen, or null if the there is no screen.
10767     */
10768    public WindowList getWindowListLocked(final Display display) {
10769        return getWindowListLocked(display.getDisplayId());
10770    }
10771
10772    /**
10773     * Return the list of WindowStates associated on the passed display.
10774     * @param displayId The screen to return windows from.
10775     * @return The list of WindowStates on the screen, or null if the there is no screen.
10776     */
10777    public WindowList getWindowListLocked(final int displayId) {
10778        final DisplayContent displayContent = getDisplayContentLocked(displayId);
10779        return displayContent != null ? displayContent.getWindowList() : null;
10780    }
10781
10782    @Override
10783    public void onDisplayAdded(int displayId) {
10784        mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0));
10785    }
10786
10787    private void handleDisplayAddedLocked(int displayId) {
10788        final Display display = mDisplayManager.getDisplay(displayId);
10789        if (display != null) {
10790            createDisplayContentLocked(display);
10791            displayReady(displayId);
10792        }
10793    }
10794
10795    @Override
10796    public void onDisplayRemoved(int displayId) {
10797        mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0));
10798    }
10799
10800    private void handleDisplayRemovedLocked(int displayId) {
10801        final DisplayContent displayContent = getDisplayContentLocked(displayId);
10802        if (displayContent != null) {
10803            mDisplayContents.delete(displayId);
10804            displayContent.close();
10805            if (displayId == Display.DEFAULT_DISPLAY) {
10806                unregisterPointerEventListener(displayContent.mTapDetector);
10807            }
10808            WindowList windows = displayContent.getWindowList();
10809            while (!windows.isEmpty()) {
10810                final WindowState win = windows.get(windows.size() - 1);
10811                removeWindowLocked(win.mSession, win);
10812            }
10813        }
10814        mAnimator.removeDisplayLocked(displayId);
10815    }
10816
10817    @Override
10818    public void onDisplayChanged(int displayId) {
10819        mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0));
10820    }
10821
10822    private void handleDisplayChangedLocked(int displayId) {
10823        final DisplayContent displayContent = getDisplayContentLocked(displayId);
10824        if (displayContent != null) {
10825            displayContent.updateDisplayInfo();
10826        }
10827    }
10828
10829    @Override
10830    public Object getWindowManagerLock() {
10831        return mWindowMap;
10832    }
10833}
10834