19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.PixelFormat; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AndroidRuntimeException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfinal class WindowLeaked extends AndroidRuntimeException { 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public WindowLeaked(String msg) { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(msg); 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Low-level communication with the global system window manager. It implements 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the ViewManager interface, allowing you to add any View subclass as a 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * top-level window on the screen. Additional window manager specific layout 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * parameters are defined for control over how windows are displayed. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It also implemens the WindowManager interface, allowing you to control the 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * displays attached to the device. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Applications will not normally use WindowManager directly, instead relying 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on the higher-level facilities in {@link android.app.Activity} and 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.app.Dialog}. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Even for low-level window manager access, it is almost never correct to use 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this class. For example, {@link android.app.Activity#getWindowManager} 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * provides a ViewManager for adding windows that are associated with that 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * activity -- the window manager will not normally allow you to add arbitrary 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * windows that are not associated with an activity. 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class WindowManagerImpl implements WindowManager { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The user is navigating with keys (not the touch screen), so 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * navigational focus should be shown. 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RELAYOUT_IN_TOUCH_MODE = 0x1; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the first time the window is being drawn, 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * so the client must call drawingFinished() when done 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RELAYOUT_FIRST_TIME = 0x2; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_FLAG_APP_VISIBLE = 0x2; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_IN_TOUCH_MODE; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_OKAY = 0; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_BAD_APP_TOKEN = -1; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_BAD_SUBWINDOW_TOKEN = -2; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_NOT_APP_TOKEN = -3; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_APP_EXITING = -4; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_DUPLICATE_ADD = -5; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_STARTING_NOT_NEEDED = -6; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_MULTIPLE_SINGLETON = -7; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ADD_PERMISSION_DENIED = -8; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static WindowManagerImpl getDefault() 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mWindowManager; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View view) 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addView(view, new WindowManager.LayoutParams( 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.OPAQUE)); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View view, ViewGroup.LayoutParams params) 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addView(view, params, false); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addViewNesting(View view, ViewGroup.LayoutParams params) 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addView(view, params, false); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void addView(View view, ViewGroup.LayoutParams params, boolean nest) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v("WindowManager", "addView view=" + view); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(params instanceof WindowManager.LayoutParams)) { 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException( 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Params must be WindowManager.LayoutParams"); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowManager.LayoutParams wparams 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = (WindowManager.LayoutParams)params; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot root; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View panelParentView = null; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Here's an odd/questionable case: if someone tries to add a 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // view multiple times, then we simply bump up a nesting count 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and they need to remove the view the corresponding number of 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // times to have it actually removed from the window manager. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is useful specifically for the notification manager, 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which can continually add/remove the same view as a 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notification gets updated. 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = findViewLocked(view, false); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0) { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!nest) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("View " + view 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " has already been added to the window manager."); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root = mRoots[index]; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.mAddNesting++; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Update layout parameters. 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setLayoutParams(wparams); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.setLayoutParams(wparams, true); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If this is a panel window, then find the window it is being 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // attached to for future reference. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW && 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = mViews != null ? mViews.length : 0; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<count; i++) { 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRoots[i].mWindow.asBinder() == wparams.token) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project panelParentView = mViews[i]; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root = new ViewRoot(view.getContext()); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.mAddNesting = 1; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setLayoutParams(wparams); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mViews == null) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = 1; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViews = new View[1]; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoots = new ViewRoot[1]; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams = new WindowManager.LayoutParams[1]; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = mViews.length + 1; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object[] old = mViews; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViews = new View[index]; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(old, 0, mViews, 0, index-1); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project old = mRoots; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoots = new ViewRoot[index]; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(old, 0, mRoots, 0, index-1); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project old = mParams; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams = new WindowManager.LayoutParams[index]; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(old, 0, mParams, 0, index-1); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index--; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViews[index] = view; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoots[index] = root; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams[index] = wparams; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do this last because it fires off messages to start doing things 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.setView(view, wparams, panelParentView); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateViewLayout(View view, ViewGroup.LayoutParams params) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(params instanceof WindowManager.LayoutParams)) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final WindowManager.LayoutParams wparams 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = (WindowManager.LayoutParams)params; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setLayoutParams(wparams); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = findViewLocked(view, true); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot root = mRoots[index]; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams[index] = wparams; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.setLayoutParams(wparams, false); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeView(View view) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = findViewLocked(view, true); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View curView = removeViewLocked(index); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curView == view) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Calling with view " + view 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " but the ViewRoot is attached to " + curView); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeViewImmediate(View view) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = findViewLocked(view, true); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot root = mRoots[index]; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View curView = root.getView(); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.mAddNesting = 0; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.die(true); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finishRemoveViewLocked(curView, index); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curView == view) { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Calling with view " + view 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " but the ViewRoot is attached to " + curView); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View removeViewLocked(int index) { 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot root = mRoots[index]; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View view = root.getView(); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't really remove until we have matched all calls to add(). 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.mAddNesting--; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (root.mAddNesting > 0) { 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return view; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager imm = InputMethodManager.getInstance(view.getContext()); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (imm != null) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imm.windowDismissed(mViews[index].getWindowToken()); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.die(false); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finishRemoveViewLocked(view, index); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return view; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void finishRemoveViewLocked(View view, int index) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = mViews.length; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove it from the list 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View[] tmpViews = new View[count-1]; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeItem(tmpViews, mViews, index); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mViews = tmpViews; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot[] tmpRoots = new ViewRoot[count-1]; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeItem(tmpRoots, mRoots, index); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRoots = tmpRoots; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams[] tmpParams 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new WindowManager.LayoutParams[count-1]; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeItem(tmpParams, mParams, index); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParams = tmpParams; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.assignParent(null); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // func doesn't allow null... does it matter if we clear them? 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //view.setLayoutParams(null); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void closeAll(IBinder token, String who, String what) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mViews == null) 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = mViews.length; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i("foo", "Closing all windows of " + token); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<count; i++) { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i("foo", "@ " + i + " token " + mParams[i].token 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // + " view " + mRoots[i].getView()); 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (token == null || mParams[i].token == token) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot root = mRoots[i]; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.mAddNesting = 1; 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i("foo", "Force closing " + root); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (who != null) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowLeaked leak = new WindowLeaked( 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project what + " " + who + " has leaked window " 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + root.getView() + " that was originally added here"); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leak.setStackTrace(root.getLocation().getStackTrace()); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e("WindowManager", leak.getMessage(), leak); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeViewLocked(i); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i--; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count--; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public WindowManager.LayoutParams getRootViewLayoutParameter(View view) { 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewParent vp = view.getParent(); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (vp != null && !(vp instanceof ViewRoot)) { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vp = vp.getParent(); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vp == null) return null; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewRoot vr = (ViewRoot)vp; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mRoots.length; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < N; ++i) { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRoots[i] == vr) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mParams[i]; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void closeAll() { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closeAll(null, null, null); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Display getDefaultDisplay() { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new Display(Display.DEFAULT_DISPLAY); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View[] mViews; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ViewRoot[] mRoots; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private WindowManager.LayoutParams[] mParams; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void removeItem(Object[] dst, Object[] src, int index) 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dst.length > 0) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index > 0) { 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(src, 0, dst, 0, index); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index < dst.length) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(src, index+1, dst, index, src.length-index-1); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int findViewLocked(View view, boolean required) 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = mViews != null ? mViews.length : 0; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<count; i++) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mViews[i] == view) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return i; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (required) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException( 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "View not attached to window manager"); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static WindowManagerImpl mWindowManager = new WindowManagerImpl(); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 364