diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index 60c177b7aac20..e39a357598a95 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -781,12 +781,21 @@ int EventHub::close_device(const char *deviceName) if(strcmp(mDevices[i]->path.string(), deviceName) == 0) { //LOGD("remove device %d: %s\n", i, deviceName); device_t* device = mDevices[i]; - int count = mFDCount - i - 1; + + LOGI("Removed device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n", + device->path.string(), device->name.string(), device->id, + mNumDevicesById, mFDCount, mFDs[i].fd, device->classes); + + // Clear this device's entry. int index = (device->id&ID_MASK); mDevicesById[index].device = NULL; + + // Close the file descriptor and compact the fd array. close(mFDs[i].fd); + int count = mFDCount - i - 1; memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count); memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count); + mFDCount--; #ifdef EV_SW for (int j=0; jnext = mClosingDevices; mClosingDevices = device; - mFDCount--; - uint32_t publicID; if (device->id == mFirstKeyboardId) { LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this", @@ -817,7 +824,7 @@ int EventHub::close_device(const char *deviceName) return 0; } } - LOGE("remote device: %s not found\n", deviceName); + LOGE("remove device: %s not found\n", deviceName); return -1; } @@ -832,7 +839,7 @@ int EventHub::read_notify(int nfd) int event_pos = 0; struct inotify_event *event; -LOGD("EventHub::read_notify nfd: %d\n", nfd); + LOGV("EventHub::read_notify nfd: %d\n", nfd); res = read(nfd, event_buf, sizeof(event_buf)); if(res < (int)sizeof(*event)) { if(errno == EINTR) diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java index 7ca12f211da23..244e13679bd0c 100644 --- a/services/java/com/android/server/KeyInputQueue.java +++ b/services/java/com/android/server/KeyInputQueue.java @@ -54,6 +54,7 @@ public abstract class KeyInputQueue { private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; final SparseArray mDevices = new SparseArray(); + final SparseArray mIgnoredDevices = new SparseArray(); final ArrayList mVirtualKeys = new ArrayList(); final HapticFeedbackCallback mHapticFeedbackCallback; @@ -391,26 +392,50 @@ public abstract class KeyInputQueue { if (ev.type == RawInputEvent.EV_DEVICE_ADDED) { synchronized (mFirst) { di = newInputDevice(ev.deviceId); - mDevices.put(ev.deviceId, di); - if ((di.classes & RawInputEvent.CLASS_TOUCHSCREEN) != 0) { - readVirtualKeys(di.name); + if (di.classes != 0) { + // If this device is some kind of input class, + // we care about it. + mDevices.put(ev.deviceId, di); + if ((di.classes & RawInputEvent.CLASS_TOUCHSCREEN) != 0) { + readVirtualKeys(di.name); + } + // The configuration may have changed because + // of this device. + configChanged = true; + } else { + // We won't do anything with this device. + mIgnoredDevices.put(ev.deviceId, di); + Log.i(TAG, "Ignoring non-input device: id=0x" + + Integer.toHexString(di.id) + + ", name=" + di.name); } - configChanged = true; } } else if (ev.type == RawInputEvent.EV_DEVICE_REMOVED) { synchronized (mFirst) { - Log.i(TAG, "Device removed: id=0x" - + Integer.toHexString(ev.deviceId)); + if (false) { + Log.i(TAG, "Device removed: id=0x" + + Integer.toHexString(ev.deviceId)); + } di = mDevices.get(ev.deviceId); if (di != null) { mDevices.delete(ev.deviceId); + // The configuration may have changed because + // of this device. configChanged = true; + } else if ((di=mIgnoredDevices.get(ev.deviceId)) != null) { + mIgnoredDevices.remove(ev.deviceId); } else { - Log.w(TAG, "Bad device id: " + ev.deviceId); + Log.w(TAG, "Removing bad device id: " + + Integer.toHexString(ev.deviceId)); + continue; } } } else { di = getInputDevice(ev.deviceId); + if (di == null) { + // This may be some junk from an ignored device. + continue; + } // first crack at it send = preprocessEvent(di, ev); @@ -422,10 +447,6 @@ public abstract class KeyInputQueue { } } - if (di == null) { - continue; - } - if (configChanged) { synchronized (mFirst) { addLocked(di, System.nanoTime(), 0, @@ -1056,28 +1077,33 @@ public abstract class KeyInputQueue { private InputDevice newInputDevice(int deviceId) { int classes = getDeviceClasses(deviceId); String name = getDeviceName(deviceId); - Log.i(TAG, "Device added: id=0x" + Integer.toHexString(deviceId) - + ", name=" + name - + ", classes=" + Integer.toHexString(classes)); - InputDevice.AbsoluteInfo absX; - InputDevice.AbsoluteInfo absY; - InputDevice.AbsoluteInfo absPressure; - InputDevice.AbsoluteInfo absSize; - if ((classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) { - absX = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_POSITION_X, "X"); - absY = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_POSITION_Y, "Y"); - absPressure = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_TOUCH_MAJOR, "Pressure"); - absSize = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_WIDTH_MAJOR, "Size"); - } else if ((classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) { - absX = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_X, "X"); - absY = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_Y, "Y"); - absPressure = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_PRESSURE, "Pressure"); - absSize = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_TOOL_WIDTH, "Size"); - } else { - absX = null; - absY = null; - absPressure = null; - absSize = null; + InputDevice.AbsoluteInfo absX = null; + InputDevice.AbsoluteInfo absY = null; + InputDevice.AbsoluteInfo absPressure = null; + InputDevice.AbsoluteInfo absSize = null; + if (classes != 0) { + Log.i(TAG, "Device added: id=0x" + Integer.toHexString(deviceId) + + ", name=" + name + + ", classes=" + Integer.toHexString(classes)); + if ((classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) { + absX = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_MT_POSITION_X, "X"); + absY = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_MT_POSITION_Y, "Y"); + absPressure = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_MT_TOUCH_MAJOR, "Pressure"); + absSize = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_MT_WIDTH_MAJOR, "Size"); + } else if ((classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) { + absX = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_X, "X"); + absY = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_Y, "Y"); + absPressure = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_PRESSURE, "Pressure"); + absSize = loadAbsoluteInfo(deviceId, + RawInputEvent.ABS_TOOL_WIDTH, "Size"); + } } return new InputDevice(deviceId, classes, name, absX, absY, absPressure, absSize); diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 81e0136169cb6..c7c748f5ac409 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -375,11 +375,14 @@ public class WindowManagerService extends IWindowManager.Stub // made visible or hidden at the next transition. int mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE; boolean mAppTransitionReady = false; + boolean mAppTransitionRunning = false; boolean mAppTransitionTimeout = false; boolean mStartingIconInTransition = false; boolean mSkipAppTransitionAnimation = false; final ArrayList mOpeningApps = new ArrayList(); final ArrayList mClosingApps = new ArrayList(); + final ArrayList mToTopApps = new ArrayList(); + final ArrayList mToBottomApps = new ArrayList(); //flag to detect fat touch events boolean mFatTouch = false; @@ -690,7 +693,11 @@ public class WindowManagerService extends IWindowManager.Stub i--; break; } - if (t.windows.size() > 0) { + + // We haven't reached the token yet; if this token + // is not going to the bottom and has windows, we can + // use it as an anchor for when we do reach the token. + if (!t.sendingToBottom && t.windows.size() > 0) { pos = t.windows.get(0); } } @@ -712,6 +719,8 @@ public class WindowManagerService extends IWindowManager.Stub } placeWindowBefore(pos, win); } else { + // Continue looking down until we find the first + // token that has windows. while (i >= 0) { AppWindowToken t = mAppTokens.get(i); final int NW = t.windows.size(); @@ -2760,7 +2769,6 @@ public class WindowManagerService extends IWindowManager.Stub mTempConfiguration.setToDefaults(); if (computeNewConfigurationLocked(mTempConfiguration)) { if (appConfig.diff(mTempConfiguration) != 0) { - Log.i(TAG, "Config changed: " + mTempConfiguration); return new Configuration(mTempConfiguration); } } @@ -3198,12 +3206,14 @@ public class WindowManagerService extends IWindowManager.Stub wtoken.setDummyAnimation(); mOpeningApps.remove(wtoken); mClosingApps.remove(wtoken); + wtoken.waitingToShow = wtoken.waitingToHide = false; wtoken.inPendingTransaction = true; if (visible) { mOpeningApps.add(wtoken); wtoken.allDrawn = false; wtoken.startingDisplayed = false; wtoken.startingMoved = false; + wtoken.waitingToShow = true; if (wtoken.clientHidden) { // In the case where we are making an app visible @@ -3217,6 +3227,7 @@ public class WindowManagerService extends IWindowManager.Stub } } else { mClosingApps.add(wtoken); + wtoken.waitingToHide = true; } return; } @@ -3351,10 +3362,12 @@ public class WindowManagerService extends IWindowManager.Stub delayed = setTokenVisibilityLocked(wtoken, null, false, WindowManagerPolicy.TRANSIT_NONE, true); wtoken.inPendingTransaction = false; mOpeningApps.remove(wtoken); + wtoken.waitingToShow = false; if (mClosingApps.contains(wtoken)) { delayed = true; } else if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) { mClosingApps.add(wtoken); + wtoken.waitingToHide = true; delayed = true; } if (DEBUG_APP_TRANSITIONS) Log.v( @@ -3441,6 +3454,12 @@ public class WindowManagerService extends IWindowManager.Stub final AppWindowToken wtoken = mAppTokens.get(tokenPos-1); if (DEBUG_REORDER) Log.v(TAG, "Looking for lower windows @ " + tokenPos + " -- " + wtoken.token); + if (wtoken.sendingToBottom) { + if (DEBUG_REORDER) Log.v(TAG, + "Skipping token -- currently sending to bottom"); + tokenPos--; + continue; + } int i = wtoken.windows.size(); while (i > 0) { i--; @@ -3449,7 +3468,7 @@ public class WindowManagerService extends IWindowManager.Stub while (j > 0) { j--; WindowState cwin = (WindowState)win.mChildWindows.get(j); - if (cwin.mSubLayer >= 0 ) { + if (cwin.mSubLayer >= 0) { for (int pos=NW-1; pos>=0; pos--) { if (mWindows.get(pos) == cwin) { if (DEBUG_REORDER) Log.v(TAG, @@ -3553,6 +3572,26 @@ public class WindowManagerService extends IWindowManager.Stub } } + private void moveAppWindowsLocked(AppWindowToken wtoken, int tokenPos, + boolean updateFocusAndLayout) { + // First remove all of the windows from the list. + tmpRemoveAppWindowsLocked(wtoken); + + // Where to start adding? + int pos = findWindowOffsetLocked(tokenPos); + + // And now add them back at the correct place. + pos = reAddAppWindowsLocked(pos, wtoken); + + if (updateFocusAndLayout) { + if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) { + assignLayersLocked(); + } + mLayoutNeeded = true; + performLayoutAndPlaceSurfacesLocked(); + } + } + private void moveAppWindowsLocked(List tokens, int tokenPos) { // First remove all of the windows from the list. final int N = tokens.size(); @@ -3575,7 +3614,9 @@ public class WindowManagerService extends IWindowManager.Stub } } - updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES); + if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES)) { + assignLayersLocked(); + } mLayoutNeeded = true; performLayoutAndPlaceSurfacesLocked(); @@ -3596,9 +3637,19 @@ public class WindowManagerService extends IWindowManager.Stub AppWindowToken wt = findAppWindowToken(tokens.get(i)); if (wt != null) { mAppTokens.add(wt); + if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) { + mToTopApps.remove(wt); + mToBottomApps.remove(wt); + mToTopApps.add(wt); + wt.sendingToBottom = false; + wt.sendingToTop = true; + } } } - moveAppWindowsLocked(tokens, mAppTokens.size()); + + if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) { + moveAppWindowsLocked(tokens, mAppTokens.size()); + } } Binder.restoreCallingIdentity(origId); } @@ -3618,10 +3669,20 @@ public class WindowManagerService extends IWindowManager.Stub AppWindowToken wt = findAppWindowToken(tokens.get(i)); if (wt != null) { mAppTokens.add(pos, wt); + if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) { + mToTopApps.remove(wt); + mToBottomApps.remove(wt); + mToBottomApps.add(i, wt); + wt.sendingToTop = false; + wt.sendingToBottom = true; + } pos++; } } - moveAppWindowsLocked(tokens, 0); + + if (mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) { + moveAppWindowsLocked(tokens, 0); + } } Binder.restoreCallingIdentity(origId); } @@ -4253,19 +4314,6 @@ public class WindowManagerService extends IWindowManager.Stub if (!computeNewConfigurationLocked(config)) { return null; } - Log.i(TAG, "Config changed: " + config); - long now = SystemClock.uptimeMillis(); - //Log.i(TAG, "Config changing, gc pending: " + mFreezeGcPending + ", now " + now); - if (mFreezeGcPending != 0) { - if (now > (mFreezeGcPending+1000)) { - //Log.i(TAG, "Gc! " + now + " > " + (mFreezeGcPending+1000)); - mH.removeMessages(H.FORCE_GC); - Runtime.getRuntime().gc(); - mFreezeGcPending = now; - } - } else { - mFreezeGcPending = now; - } return config; } @@ -7213,6 +7261,10 @@ public class WindowManagerService extends IWindowManager.Stub * of a transition that has not yet been started. */ boolean isReadyForDisplay() { + if (mRootToken.waitingToShow && + mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) { + return false; + } final AppWindowToken atoken = mAppToken; final boolean animating = atoken != null ? (atoken.animation != null) : false; @@ -7547,6 +7599,22 @@ public class WindowManagerService extends IWindowManager.Stub // Temporary for finding which tokens no longer have visible windows. boolean hasVisible; + // Set to true when this token is in a pending transaction where it + // will be shown. + boolean waitingToShow; + + // Set to true when this token is in a pending transaction where it + // will be hidden. + boolean waitingToHide; + + // Set to true when this token is in a pending transaction where its + // windows will be put to the bottom of the list. + boolean sendingToBottom; + + // Set to true when this token is in a pending transaction where its + // windows will be put to the top of the list. + boolean sendingToTop; + WindowToken(IBinder _token, int type, boolean _explicit) { token = _token; windowType = type; @@ -7559,6 +7627,12 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(prefix); pw.print("windowType="); pw.print(windowType); pw.print(" hidden="); pw.print(hidden); pw.print(" hasVisible="); pw.println(hasVisible); + if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) { + pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow); + pw.print(" waitingToHide="); pw.print(waitingToHide); + pw.print(" sendingToBottom="); pw.print(sendingToBottom); + pw.print(" sendingToTop="); pw.println(sendingToTop); + } } @Override @@ -7868,7 +7942,7 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows); } pw.print(prefix); pw.print("groupId="); pw.print(groupId); - pw.print(" appFullscreen="); pw.println(appFullscreen); + pw.print(" appFullscreen="); pw.print(appFullscreen); pw.print(" requestedOrientation="); pw.println(requestedOrientation); pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested); pw.print(" clientHidden="); pw.print(clientHidden); @@ -8434,6 +8508,50 @@ public class WindowManagerService extends IWindowManager.Stub return win; } + final void rebuildAppWindowListLocked() { + int NW = mWindows.size(); + int i; + + // First remove all existing app windows. + i=0; + while (i < NW) { + if (((WindowState)mWindows.get(i)).mAppToken != null) { + mWindows.remove(i); + NW--; + continue; + } + i++; + } + + // Now go through the app tokens and add the windows back in. + int NT = mAppTokens.size(); + i = 0; + for (int j=0; j= 0) { + break; + } + mWindows.add(i, cwin); + i++; + } + mWindows.add(i, win); + i++; + for (; c 0) { + NN = mAppTokens.size(); + for (i=0; i