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