Work on issue #2079167: Flickering issue across multiple UI

This addresses a few parts of the bug:

- There was a small issue in the window manager where we could show a window
  too early before the transition animation starts, which was introduced
  by the recent wallpaper work.  This was the cause of the flicker when
  starting the dialer for the first time.

- There was a much larger problem that has existing forever where moving
  an application token to the front or back was not synchronized with the
  application animation transaction.  This was the cause of the flicker
  when hanging up (now that the in-call screen moves to the back instead
  of closing and we always have a wallpaper visible).  The approach to
  solving this is to have the window manager go ahead and move the app
  tokens (it must in order to keep in sync with the activity manager), but
  to delay the actual window movement: perform the movement to front when
  the animation starts, and to back when it ends.  Actually, when the
  animation ends, we just go and completely rebuild the window list to
  ensure it is correct, because there can be ways people can add windows
  while in this intermediate state where they could end up at the wrong
  place once we do the delayed movement to the front or back.  And it is
  simply reasuring to know that every time we finish a full app transition,
  we re-evaluate the world and put everything in its proper place.

Also included in this change are a few little tweaks to the input system,
to perform better logging, and completely ignore input devices that do not
have any of our input classes.  There is also a little cleanup of evaluating
configuration changes to not do more work than needed when an input
devices appears or disappears, and to only log a config change message when
the config is truly changing.

Change-Id: Ifb2db77f8867435121722a6abeb946ec7c3ea9d3
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index 7ca12f21..244e136 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -54,6 +54,7 @@
     private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
 
     final SparseArray<InputDevice> mDevices = new SparseArray<InputDevice>();
+    final SparseArray<InputDevice> mIgnoredDevices = new SparseArray<InputDevice>();
     final ArrayList<VirtualKey> mVirtualKeys = new ArrayList<VirtualKey>();
     final HapticFeedbackCallback mHapticFeedbackCallback;
     
@@ -391,26 +392,50 @@
                     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 @@
                         }
                     }
 
-                    if (di == null) {
-                        continue;
-                    }
-                    
                     if (configChanged) {
                         synchronized (mFirst) {
                             addLocked(di, System.nanoTime(), 0,
@@ -1056,28 +1077,33 @@
     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);