package android.view;
import android.graphics.PixelFormat;
public class WindowManagerImpl extends WindowManager {
private static final String TAG = "WindowManagerImpl";
/**
* 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;
private static WindowManagerImpl mWindowManager = null;
private boolean mInTouchMode = false;
public static WindowManagerImpl getDefault() {
if (mWindowManager == null)
mWindowManager = new WindowManagerImpl();
return mWindowManager;
}
private View[] mViews;
private ViewRoot[] mRoots;
private WindowManager.LayoutParams[] mParams;
private Display mDisplay = new Display(0);
public Display getDefaultDisplay() {
return mDisplay;
}
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) {
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
ViewRoot root;
View panelParentView = null;
// 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) {
System.out.println(TAG + "should not go here");
final int count = mViews != null ? mViews.length : 0;
for (int i = 0; i < count; i++) {
// if (mRoots[i].mWindow.asBinder() == wparams.token) {
// panelParentView = mViews[i];
// }
}
}
root = new ViewRoot(view.getContext());
root.mAddNesting = 1;
view.setLayoutParams(wparams);
if (mViews == null) {
index = 1;
mViews = new View[1];
mRoots = new ViewRoot[1];
mParams = new WindowManager.LayoutParams[1];
} else {
index = mViews.length + 1;
Object[] old = mViews;
mViews = new View[index];
System.arraycopy(old, 0, mViews, 0, index - 1);
old = mRoots;
mRoots = new ViewRoot[index];
System.arraycopy(old, 0, mRoots, 0, index - 1);
old = mParams;
mParams = new WindowManager.LayoutParams[index];
System.arraycopy(old, 0, mParams, 0, index - 1);
}
index--;
mViews[index] = view;
mRoots[index] = root;
mParams[index] = wparams;
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (Exception e) {
}
}
private int findViewLocked(View view, boolean required) {
final int count = mViews != null ? mViews.length : 0;
for (int i = 0; i < count; i++) {
if (mViews[i] == view) {
return i;
}
}
if (required) {
throw new IllegalArgumentException(
"View not attached to window manager");
}
return -1;
}
public void updateViewLayout(View view,
android.view.ViewGroup.LayoutParams params) {
if (!(params instanceof WindowManager.LayoutParams)) {
throw new IllegalArgumentException(
"Params must be WindowManager.LayoutParams");
}
final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
view.setLayoutParams(wparams);
int index = findViewLocked(view, true);
ViewRoot root = mRoots[index];
mParams[index] = wparams;
root.setLayoutParams(wparams, false);
}
public void removeView(View view) {
int index = findViewLocked(view, true);
View curView = removeViewLocked(index);
if (curView == view) {
return;
}
throw new IllegalStateException("Calling with view " + view
+ " but the ViewRoot is attached to " + curView);
}
View removeViewLocked(int index) {
ViewRoot root = mRoots[index];
View view = root.getView();
// Don't really remove until we have matched all calls to add().
root.mAddNesting--;
if (root.mAddNesting > 0) {
return view;
}
root.die(false);
finishRemoveViewLocked(view, index);
return view;
}
void finishRemoveViewLocked(View view, int index) {
final int count = mViews.length;
// remove it from the list
View[] tmpViews = new View[count - 1];
removeItem(tmpViews, mViews, index);
mViews = tmpViews;
ViewRoot[] tmpRoots = new ViewRoot[count - 1];
removeItem(tmpRoots, mRoots, index);
mRoots = tmpRoots;
WindowManager.LayoutParams[] tmpParams = new WindowManager.LayoutParams[count - 1];
removeItem(tmpParams, mParams, index);
mParams = tmpParams;
view.assignParent(null, true);
// func doesn't allow null... does it matter if we clear them?
// view.setLayoutParams(null);
}
private static void removeItem(Object[] dst, Object[] src, int index) {
if (dst.length > 0) {
if (index > 0) {
System.arraycopy(src, 0, dst, 0, index);
}
if (index < dst.length) {
System.arraycopy(src, index + 1, dst, index, src.length - index
- 1);
}
}
}
public WindowManager.LayoutParams getRootViewLayoutParameter(View view) {
ViewParent vp = view.getParent();
while (vp != null && !(vp instanceof ViewRoot)) {
vp = vp.getParent();
}
if (vp == null)
return null;
ViewRoot vr = (ViewRoot) vp;
int N = mRoots.length;
for (int i = 0; i < N; ++i) {
if (mRoots[i] == vr) {
return mParams[i];
}
}
return null;
}
// public void onKeyDown(int keyCode) {
// switch (keyCode) {
// // case 70:
// // // f: tooggle Menu
// // if (null != mStaticWD) {
// // mStaticWD.togglePanel(Window.FEATURE_OPTIONS_PANEL, null);
// // }
// // break;
// default:
// // System.out.println("keyCode is " + keyCode);
// break;
// }
// }
public void removeViewImmediate(View view) {
int index = findViewLocked(view, true);
ViewRoot root = mRoots[index];
View curView = root.getView();
root.mAddNesting = 0;
root.die(true);
finishRemoveViewLocked(curView, index);
if (curView == view) {
return;
}
throw new IllegalStateException("Calling with view " + view
+ " but the ViewRoot is attached to " + curView);
}
public class ToastView extends View{
}
public void setInTouchMode(boolean inTouch) {
mInTouchMode = inTouch;
}
public boolean getInTouchMode() {
return mInTouchMode;
}
}