/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import android.graphics.PixelFormat; import android.os.IBinder; import android.util.AndroidRuntimeException; import android.util.Config; import android.util.Log; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; final class WindowLeaked extends AndroidRuntimeException { public WindowLeaked(String msg) { super(msg); } } /** * Low-level communication with the global system window manager. It implements * the ViewManager interface, allowing you to add any View subclass as a * top-level window on the screen. Additional window manager specific layout * parameters are defined for control over how windows are displayed. * It also implemens the WindowManager interface, allowing you to control the * displays attached to the device. * *
Applications will not normally use WindowManager directly, instead relying * on the higher-level facilities in {@link android.app.Activity} and * {@link android.app.Dialog}. * *
Even for low-level window manager access, it is almost never correct to use
* this class. For example, {@link android.app.Activity#getWindowManager}
* provides a ViewManager for adding windows that are associated with that
* activity -- the window manager will not normally allow you to add arbitrary
* windows that are not associated with an activity.
*
* @hide
*/
public class WindowManagerImpl implements WindowManager {
/**
* The user is navigating with keys (not the touch screen), so
* navigational focus should be shown.
*/
public static final int RELAYOUT_IN_TOUCH_MODE = 0x1;
/**
* This is the first time the window is being drawn,
* so the client must call drawingFinished() when done
*/
public static final int RELAYOUT_FIRST_TIME = 0x2;
public static final int ADD_FLAG_APP_VISIBLE = 0x2;
public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_IN_TOUCH_MODE;
public static final int ADD_OKAY = 0;
public static final int ADD_BAD_APP_TOKEN = -1;
public static final int ADD_BAD_SUBWINDOW_TOKEN = -2;
public static final int ADD_NOT_APP_TOKEN = -3;
public static final int ADD_APP_EXITING = -4;
public static final int ADD_DUPLICATE_ADD = -5;
public static final int ADD_STARTING_NOT_NEEDED = -6;
public static final int ADD_MULTIPLE_SINGLETON = -7;
public static final int ADD_PERMISSION_DENIED = -8;
public static WindowManagerImpl getDefault()
{
return mWindowManager;
}
public void addView(View view)
{
addView(view, new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.OPAQUE));
}
public void addView(View view, ViewGroup.LayoutParams params)
{
addView(view, params, false);
}
public void addViewNesting(View view, ViewGroup.LayoutParams params)
{
addView(view, params, false);
}
private void addView(View view, ViewGroup.LayoutParams params, boolean nest)
{
if (Config.LOGV) Log.v("WindowManager", "addView view=" + view);
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException(
"Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams
= (WindowManager.LayoutParams)params;
ViewRoot root;
View panelParentView = null;
synchronized (this) {
// Here's an odd/questionable case: if someone tries to add a
// view multiple times, then we simply bump up a nesting count
// and they need to remove the view the corresponding number of
// times to have it actually removed from the window manager.
// This is useful specifically for the notification manager,
// which can continually add/remove the same view as a
// notification gets updated.
int index = findViewLocked(view, false);
if (index >= 0) {
if (!nest) {
throw new IllegalStateException("View " + view
+ " has already been added to the window manager.");
}
root = mRoots[index];
root.mAddNesting++;
// Update layout parameters.
view.setLayoutParams(wparams);
root.setLayoutParams(wparams, true);
return;
}
// If this is a panel window, then find the window it is being
// attached to for future reference.
if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
final int count = mViews != null ? mViews.length : 0;
for (int i=0; i