OSDN Git Service

Allow wallpapers to get touch events.
authorDianne Hackborn <hackbod@google.com>
Mon, 17 Aug 2009 22:15:18 +0000 (15:15 -0700)
committerDianne Hackborn <hackbod@google.com>
Tue, 18 Aug 2009 04:23:05 +0000 (21:23 -0700)
api/current.xml
core/java/android/service/wallpaper/WallpaperService.java
core/java/android/view/IWindow.aidl
core/java/android/view/MotionEvent.java
core/java/android/view/SurfaceView.java
core/java/android/view/ViewRoot.java
core/java/com/android/internal/os/HandlerCaller.java
core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
core/java/com/android/internal/view/BaseIWindow.java
services/java/com/android/server/WindowManagerService.java
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java

index 461fc38..ca8d81f 100644 (file)
 <parameter name="o" type="android.view.MotionEvent">
 </parameter>
 </method>
+<method name="obtainNoHistory"
+ return="android.view.MotionEvent"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="o" type="android.view.MotionEvent">
+</parameter>
+</method>
 <method name="offsetLocation"
  return="void"
  abstract="false"
index 0a3ffff..80a154b 100644 (file)
@@ -30,6 +30,7 @@ import android.os.RemoteException;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.IWindowSession;
+import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.view.View;
 import android.view.ViewGroup;
@@ -59,6 +60,7 @@ public abstract class WallpaperService extends Service {
     private static final int MSG_VISIBILITY_CHANGED = 10010;
     private static final int MSG_WALLPAPER_OFFSETS = 10020;
     private static final int MSG_WINDOW_RESIZED = 10030;
+    private static final int MSG_TOUCH_EVENT = 10040;
     
     /**
      * The actual implementation of a wallpaper.  A wallpaper service may
@@ -87,6 +89,8 @@ public abstract class WallpaperService extends Service {
         int mType;
         int mCurWidth;
         int mCurHeight;
+        int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+        int mCurWindowFlags = mWindowFlags;
         boolean mDestroyReportNeeded;
         final Rect mVisibleInsets = new Rect();
         final Rect mWinFrame = new Rect();
@@ -100,6 +104,7 @@ public abstract class WallpaperService extends Service {
         boolean mOffsetMessageEnqueued;
         float mPendingXOffset;
         float mPendingYOffset;
+        MotionEvent mPendingMove;
         
         final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() {
 
@@ -131,6 +136,27 @@ public abstract class WallpaperService extends Service {
         };
         
         final BaseIWindow mWindow = new BaseIWindow() {
+            @Override
+            public boolean onDispatchPointer(MotionEvent event, long eventTime,
+                    boolean callWhenDone) {
+                synchronized (mLock) {
+                    if (event.getAction() == MotionEvent.ACTION_MOVE) {
+                        if (mPendingMove != null) {
+                            mCaller.removeMessages(MSG_TOUCH_EVENT, mPendingMove);
+                            mPendingMove.recycle();
+                        }
+                        mPendingMove = event;
+                    } else {
+                        mPendingMove = null;
+                    }
+                    Message msg = mCaller.obtainMessageO(MSG_TOUCH_EVENT,
+                            event);
+                    mCaller.sendMessage(msg);
+                }
+                return false;
+            }
+            
+            @Override
             public void resized(int w, int h, Rect coveredInsets,
                     Rect visibleInsets, boolean reportDraw) {
                 Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
@@ -138,6 +164,7 @@ public abstract class WallpaperService extends Service {
                 mCaller.sendMessage(msg);
             }
             
+            @Override
             public void dispatchAppVisibility(boolean visible) {
                 Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED,
                         visible ? 1 : 0);
@@ -185,6 +212,22 @@ public abstract class WallpaperService extends Service {
         }
         
         /**
+         * Control whether this wallpaper will receive raw touch events
+         * from the window manager as the user interacts with the window
+         * that is currently displaying the wallpaper.  By default they
+         * are turned off.  If enabled, the events will be received in
+         * {@link #onTouchEvent(MotionEvent)}.
+         */
+        public void setTouchEventsEnabled(boolean enabled) {
+            mWindowFlags = enabled
+                    ? (mWindowFlags&~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
+                    : (mWindowFlags|WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+            if (mCreated) {
+                updateSurface(false);
+            }
+        }
+        
+        /**
          * Called once to initialize the engine.  After returning, the
          * engine's surface will be created by the framework.
          */
@@ -208,6 +251,16 @@ public abstract class WallpaperService extends Service {
         }
         
         /**
+         * Called as the user performs touch-screen interaction with the
+         * window that is currently showing this wallpaper.  Note that the
+         * events you receive here are driven by the actual application the
+         * user is interacting with, so if it is slow you will get viewer
+         * move events.
+         */
+        public void onTouchEvent(MotionEvent event) {
+        }
+        
+        /**
          * Called to inform you of the wallpaper's offsets changing
          * within its contain, corresponding to the container's
          * call to {@link WallpaperManager#setWallpaperOffsets(IBinder, float, float)
@@ -248,7 +301,9 @@ public abstract class WallpaperService extends Service {
             final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
             boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
             final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
-            if (force || creating || formatChanged || sizeChanged || typeChanged) {
+            final boolean flagsChanged = mCurWindowFlags != mWindowFlags;
+            if (force || creating || formatChanged || sizeChanged || typeChanged
+                    || flagsChanged) {
 
                 if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
                         + " format=" + formatChanged + " size=" + sizeChanged);
@@ -259,20 +314,19 @@ public abstract class WallpaperService extends Service {
                     mFormat = mSurfaceHolder.getRequestedFormat();
                     mType = mSurfaceHolder.getRequestedType();
 
-                    // Scaling/Translate window's layout here because mLayout is not used elsewhere.
-                    
-                    // Places the window relative
                     mLayout.x = 0;
                     mLayout.y = 0;
                     mLayout.width = myWidth;
                     mLayout.height = myHeight;
                     
                     mLayout.format = mFormat;
-                    mLayout.flags |=WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                                  | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                                  | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                                  | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                                  ;
+                    
+                    mCurWindowFlags = mWindowFlags;
+                    mLayout.flags = mWindowFlags
+                            | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+                            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                            | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            ;
 
                     mLayout.memoryType = mType;
                     mLayout.token = mWindowToken;
@@ -478,6 +532,16 @@ public abstract class WallpaperService extends Service {
                         }
                     }
                 } break;
+                case MSG_TOUCH_EVENT: {
+                    MotionEvent ev = (MotionEvent)message.obj;
+                    synchronized (mEngine.mLock) {
+                        if (mEngine.mPendingMove == ev) {
+                            mEngine.mPendingMove = null;
+                        }
+                    }
+                    mEngine.onTouchEvent(ev);
+                    ev.recycle();
+                } break;
                 default :
                     Log.w(TAG, "Unknown message type " + message.what);
             }
index ec2036e..ebc5f7b 100644 (file)
@@ -46,8 +46,8 @@ oneway interface IWindow {
     void resized(int w, int h, in Rect coveredInsets, in Rect visibleInsets,
             boolean reportDraw);
     void dispatchKey(in KeyEvent event);
-    void dispatchPointer(in MotionEvent event, long eventTime);
-    void dispatchTrackball(in MotionEvent event, long eventTime);
+    void dispatchPointer(in MotionEvent event, long eventTime, boolean callWhenDone);
+    void dispatchTrackball(in MotionEvent event, long eventTime, boolean callWhenDone);
     void dispatchAppVisibility(boolean visible);
     void dispatchGetNewSurface();
 
index e8bfa6a..b2f0c60 100644 (file)
@@ -552,6 +552,44 @@ public final class MotionEvent implements Parcelable {
     }
 
     /**
+     * Create a new MotionEvent, copying from an existing one, but not including
+     * any historical point information.
+     */
+    static public MotionEvent obtainNoHistory(MotionEvent o) {
+        MotionEvent ev = obtain();
+        ev.mDeviceId = o.mDeviceId;
+        ev.mEdgeFlags = o.mEdgeFlags;
+        ev.mDownTime = o.mDownTime;
+        ev.mEventTimeNano = o.mEventTimeNano;
+        ev.mAction = o.mAction;
+        ev.mNumPointers = o.mNumPointers;
+        ev.mRawX = o.mRawX;
+        ev.mRawY = o.mRawY;
+        ev.mMetaState = o.mMetaState;
+        ev.mXPrecision = o.mXPrecision;
+        ev.mYPrecision = o.mYPrecision;
+        
+        ev.mNumSamples = 1;
+        ev.mTimeSamples[0] = o.mTimeSamples[0];
+        
+        final int NP = (ev.mNumPointers=o.mNumPointers);
+        if (ev.mPointerIdentifiers.length >= NP) {
+            System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP);
+        } else {
+            ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone();
+        }
+        
+        final int ND = NP * NUM_SAMPLE_DATA;
+        if (ev.mDataSamples.length >= ND) {
+            System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND);
+        } else {
+            ev.mDataSamples = (float[])o.mDataSamples.clone();
+        }
+        
+        return ev;
+    }
+
+    /**
      * Recycle the MotionEvent, to be re-used by a later caller.  After calling
      * this function you must not ever touch the event again.
      */
index 3b64945..ea879ed 100644 (file)
@@ -481,7 +481,8 @@ public class SurfaceView extends View {
             }
         }
 
-        public void dispatchPointer(MotionEvent event, long eventTime) {
+        public void dispatchPointer(MotionEvent event, long eventTime,
+                boolean callWhenDone) {
             Log.w("SurfaceView", "Unexpected pointer event in surface: " + event);
             //if (mSession != null && mSurface != null) {
             //    try {
@@ -491,7 +492,8 @@ public class SurfaceView extends View {
             //}
         }
 
-        public void dispatchTrackball(MotionEvent event, long eventTime) {
+        public void dispatchTrackball(MotionEvent event, long eventTime,
+                boolean callWhenDone) {
             Log.w("SurfaceView", "Unexpected trackball event in surface: " + event);
             //if (mSession != null && mSurface != null) {
             //    try {
index 4623bb5..3b78060 100644 (file)
@@ -1637,8 +1637,8 @@ public final class ViewRoot extends Handler implements ViewParent,
             break;
         case DISPATCH_POINTER: {
             MotionEvent event = (MotionEvent)msg.obj;
-
-            boolean didFinish;
+            boolean callWhenDone = msg.arg1 != 0;
+            
             if (event == null) {
                 try {
                     long timeBeforeGettingEvents;
@@ -1654,9 +1654,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                     }
                 } catch (RemoteException e) {
                 }
-                didFinish = true;
-            } else {
-                didFinish = event.getAction() == MotionEvent.ACTION_OUTSIDE;
+                callWhenDone = false;
             }
             if (event != null && mTranslator != null) {
                 mTranslator.translateEventInScreenToAppWindow(event);
@@ -1728,7 +1726,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                     }
                 }
             } finally {
-                if (!didFinish) {
+                if (callWhenDone) {
                     try {
                         sWindowSession.finishKey(mWindow);
                     } catch (RemoteException e) {
@@ -1743,7 +1741,7 @@ public final class ViewRoot extends Handler implements ViewParent,
             }
         } break;
         case DISPATCH_TRACKBALL:
-            deliverTrackballEvent((MotionEvent)msg.obj);
+            deliverTrackballEvent((MotionEvent)msg.obj, msg.arg1 != 0);
             break;
         case DISPATCH_APP_VISIBILITY:
             handleAppVisibility(msg.arg1 != 0);
@@ -1985,16 +1983,13 @@ public final class ViewRoot extends Handler implements ViewParent,
     }
 
 
-    private void deliverTrackballEvent(MotionEvent event) {
-        boolean didFinish;
+    private void deliverTrackballEvent(MotionEvent event, boolean callWhenDone) {
         if (event == null) {
             try {
                 event = sWindowSession.getPendingTrackballMove(mWindow);
             } catch (RemoteException e) {
             }
-            didFinish = true;
-        } else {
-            didFinish = false;
+            callWhenDone = false;
         }
 
         if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
@@ -2012,7 +2007,7 @@ public final class ViewRoot extends Handler implements ViewParent,
             }
         } finally {
             if (handled) {
-                if (!didFinish) {
+                if (callWhenDone) {
                     try {
                         sWindowSession.finishKey(mWindow);
                     } catch (RemoteException e) {
@@ -2128,7 +2123,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                 mLastTrackballTime = curTime;
             }
         } finally {
-            if (!didFinish) {
+            if (callWhenDone) {
                 try {
                     sWindowSession.finishKey(mWindow);
                 } catch (RemoteException e) {
@@ -2591,15 +2586,19 @@ public final class ViewRoot extends Handler implements ViewParent,
         sendMessageAtTime(msg, event.getEventTime());
     }
 
-    public void dispatchPointer(MotionEvent event, long eventTime) {
+    public void dispatchPointer(MotionEvent event, long eventTime,
+            boolean callWhenDone) {
         Message msg = obtainMessage(DISPATCH_POINTER);
         msg.obj = event;
+        msg.arg1 = callWhenDone ? 1 : 0;
         sendMessageAtTime(msg, eventTime);
     }
 
-    public void dispatchTrackball(MotionEvent event, long eventTime) {
+    public void dispatchTrackball(MotionEvent event, long eventTime,
+            boolean callWhenDone) {
         Message msg = obtainMessage(DISPATCH_TRACKBALL);
         msg.obj = event;
+        msg.arg1 = callWhenDone ? 1 : 0;
         sendMessageAtTime(msg, eventTime);
     }
 
@@ -2772,23 +2771,25 @@ public final class ViewRoot extends Handler implements ViewParent,
             }
         }
 
-        public void dispatchPointer(MotionEvent event, long eventTime) {
+        public void dispatchPointer(MotionEvent event, long eventTime,
+                boolean callWhenDone) {
             final ViewRoot viewRoot = mViewRoot.get();
             if (viewRoot != null) {                
                 if (MEASURE_LATENCY) {
                     // Note: eventTime is in milliseconds
                     ViewRoot.lt.sample("* ViewRoot b4 dispatchPtr", System.nanoTime() - eventTime * 1000000);
                 }
-                viewRoot.dispatchPointer(event, eventTime);
+                viewRoot.dispatchPointer(event, eventTime, callWhenDone);
             } else {
                 new EventCompletion(mMainLooper, this, null, true, event);
             }
         }
 
-        public void dispatchTrackball(MotionEvent event, long eventTime) {
+        public void dispatchTrackball(MotionEvent event, long eventTime,
+                boolean callWhenDone) {
             final ViewRoot viewRoot = mViewRoot.get();
             if (viewRoot != null) {
-                viewRoot.dispatchTrackball(event, eventTime);
+                viewRoot.dispatchTrackball(event, eventTime, callWhenDone);
             } else {
                 new EventCompletion(mMainLooper, this, null, false, event);
             }
index e4c473d..5825024 100644 (file)
@@ -97,6 +97,14 @@ public class HandlerCaller {
         return mH.hasMessages(what);
     }
     
+    public void removeMessages(int what) {
+        mH.removeMessages(what);
+    }
+    
+    public void removeMessages(int what, Object obj) {
+        mH.removeMessages(what, obj);
+    }
+    
     public void sendMessage(Message msg) {
         mH.sendMessage(msg);
     }
index 7147ac0..3f2979f 100644 (file)
@@ -22,6 +22,7 @@ import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.service.wallpaper.WallpaperService;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.SurfaceHolder;
 import android.content.Context;
 import android.content.IntentFilter;
@@ -75,6 +76,7 @@ public class ImageWallpaper extends WallpaperService {
             super.onCreate(surfaceHolder);
             updateWallpaper();
             surfaceHolder.setSizeFromLayout();
+            //setTouchEventsEnabled(true);
         }
 
         @Override
@@ -83,6 +85,12 @@ public class ImageWallpaper extends WallpaperService {
         }
         
         @Override
+        public void onTouchEvent(MotionEvent event) {
+            super.onTouchEvent(event);
+            Log.i("foo", "Touch event: " + event);
+        }
+
+        @Override
         public void onOffsetsChanged(float xOffset, float yOffset,
                 int xPixels, int yPixels) {
             mXOffset = xOffset;
index a030db7..f4f6297 100644 (file)
@@ -32,23 +32,47 @@ public class BaseIWindow extends IWindow.Stub {
         }
     }
 
-    public void dispatchPointer(MotionEvent event, long eventTime) {
+    public boolean onDispatchPointer(MotionEvent event, long eventTime,
+            boolean callWhenDone) {
+        event.recycle();
+        return false;
+    }
+    
+    public void dispatchPointer(MotionEvent event, long eventTime,
+            boolean callWhenDone) {
         try {
             if (event == null) {
                 event = mSession.getPendingPointerMove(this);
-            } else if (event.getAction() != MotionEvent.ACTION_OUTSIDE) {
-                mSession.finishKey(this);
+                onDispatchPointer(event, eventTime, false);
+            } else if (callWhenDone) {
+                if (!onDispatchPointer(event, eventTime, true)) {
+                    mSession.finishKey(this);
+                }
+            } else {
+                onDispatchPointer(event, eventTime, false);
             }
         } catch (RemoteException ex) {
         }
     }
 
-    public void dispatchTrackball(MotionEvent event, long eventTime) {
+    public boolean onDispatchTrackball(MotionEvent event, long eventTime,
+            boolean callWhenDone) {
+        event.recycle();
+        return false;
+    }
+    
+    public void dispatchTrackball(MotionEvent event, long eventTime,
+            boolean callWhenDone) {
         try {
             if (event == null) {
                 event = mSession.getPendingTrackballMove(this);
-            } else if (event.getAction() != MotionEvent.ACTION_OUTSIDE) {
-                mSession.finishKey(this);
+                onDispatchTrackball(event, eventTime, false);
+            } else if (callWhenDone) {
+                if (!onDispatchTrackball(event, eventTime, true)) {
+                    mSession.finishKey(this);
+                }
+            } else {
+                onDispatchTrackball(event, eventTime, false);
             }
         } catch (RemoteException ex) {
         }
index 6af85db..988c3d5 100644 (file)
@@ -1247,7 +1247,8 @@ public class WindowManagerService extends IWindowManager.Stub
                 WindowState wallpaper = token.windows.get(curWallpaperIndex);
                 
                 if (visible) {
-                    updateWallpaperOffsetLocked(w, wallpaper, dw, dh);                        
+                    updateWallpaperOffsetLocked(mWallpaperTarget,
+                            wallpaper, dw, dh);                        
                 }
                 
                 // First, make sure the client has the current visibility
@@ -1389,6 +1390,32 @@ public class WindowManagerService extends IWindowManager.Stub
         return changed;
     }
     
+    void sendPointerToWallpaperLocked(WindowState srcWin,
+            MotionEvent pointer, long eventTime) {
+        int curTokenIndex = mWallpaperTokens.size();
+        while (curTokenIndex > 0) {
+            curTokenIndex--;
+            WindowToken token = mWallpaperTokens.get(curTokenIndex);
+            int curWallpaperIndex = token.windows.size();
+            while (curWallpaperIndex > 0) {
+                curWallpaperIndex--;
+                WindowState wallpaper = token.windows.get(curWallpaperIndex);
+                if ((wallpaper.mAttrs.flags &
+                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
+                    continue;
+                }
+                try {
+                    MotionEvent ev = MotionEvent.obtainNoHistory(pointer);
+                    ev.offsetLocation(srcWin.mFrame.left-wallpaper.mFrame.left,
+                            srcWin.mFrame.top-wallpaper.mFrame.top);
+                    wallpaper.mClient.dispatchPointer(ev, eventTime, false);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failure sending pointer to wallpaper", e);
+                }
+            }
+        }
+    }
+    
     public int addWindow(Session session, IWindow client,
             WindowManager.LayoutParams attrs, int viewVisibility,
             Rect outContentInsets) {
@@ -1677,6 +1704,8 @@ public class WindowManagerService extends IWindowManager.Stub
     }
 
     private void removeWindowInnerLocked(Session session, WindowState win) {
+        mKeyWaiter.finishedKey(session, win.mClient, true,
+                KeyWaiter.RETURN_NOTHING);
         mKeyWaiter.releasePendingPointerLocked(win.mSession);
         mKeyWaiter.releasePendingTrackballLocked(win.mSession);
 
@@ -4343,7 +4372,7 @@ public class WindowManagerService extends IWindowManager.Stub
                             final Rect frame = out.mFrame;
                             oev.offsetLocation(-(float)frame.left, -(float)frame.top);
                             try {
-                                out.mClient.dispatchPointer(oev, eventTime);
+                                out.mClient.dispatchPointer(oev, eventTime, false);
                             } catch (android.os.RemoteException e) {
                                 Log.i(TAG, "WINDOW DIED during outside motion dispatch: " + out);
                             }
@@ -4356,6 +4385,12 @@ public class WindowManagerService extends IWindowManager.Stub
                 final Rect frame = target.mFrame;
                 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
                 mKeyWaiter.bindTargetWindowLocked(target);
+                
+                // If we are on top of the wallpaper, then the wallpaper also
+                // gets to see this movement.
+                if (mWallpaperTarget == target) {
+                    sendPointerToWallpaperLocked(target, ev, eventTime);
+                }
             }
         }
 
@@ -4370,7 +4405,7 @@ public class WindowManagerService extends IWindowManager.Stub
                 lt.sample("6 before svr->client ipc ", System.nanoTime() - eventTimeNano);
             }
 
-            target.mClient.dispatchPointer(ev, eventTime);
+            target.mClient.dispatchPointer(ev, eventTime, true);
 
             if (MEASURE_LATENCY) {
                 lt.sample("7 after  svr->client ipc ", System.nanoTime() - eventTimeNano);
@@ -4446,7 +4481,7 @@ public class WindowManagerService extends IWindowManager.Stub
         }
 
         try {
-            focus.mClient.dispatchTrackball(ev, eventTime);
+            focus.mClient.dispatchTrackball(ev, eventTime, true);
             return INJECT_SUCCEEDED;
         } catch (android.os.RemoteException e) {
             Log.i(TAG, "WINDOW DIED during key dispatch: " + focus);
@@ -5221,14 +5256,16 @@ public class WindowManagerService extends IWindowManager.Stub
                 return null;
             }
 
+            MotionEvent res = null;
+            QueuedEvent qev = null;
+            WindowState win = null;
+            
             synchronized (this) {
                 if (DEBUG_INPUT) Log.v(
                     TAG, "finishedKey: client=" + client.asBinder()
                     + ", force=" + force + ", last=" + mLastBinder
                     + " (token=" + (mLastWin != null ? mLastWin.mToken : null) + ")");
 
-                QueuedEvent qev = null;
-                WindowState win = null;
                 if (returnWhat == RETURN_PENDING_POINTER) {
                     qev = session.mPendingPointerMove;
                     win = session.mPendingPointerWindow;
@@ -5258,17 +5295,25 @@ public class WindowManagerService extends IWindowManager.Stub
                 }
 
                 if (qev != null) {
-                    MotionEvent res = (MotionEvent)qev.event;
+                    res = (MotionEvent)qev.event;
                     if (DEBUG_INPUT) Log.v(TAG,
                             "Returning pending motion: " + res);
                     mQueue.recycleEvent(qev);
                     if (win != null && returnWhat == RETURN_PENDING_POINTER) {
                         res.offsetLocation(-win.mFrame.left, -win.mFrame.top);
                     }
-                    return res;
                 }
-                return null;
             }
+            
+            if (res != null && returnWhat == RETURN_PENDING_POINTER) {
+                synchronized (mWindowMap) {
+                    if (mWallpaperTarget == win) {
+                        sendPointerToWallpaperLocked(win, res, res.getEventTime());
+                    }
+                }
+            }
+            
+            return res;
         }
 
         void tickle() {
index 8d44ac0..e941b7f 100644 (file)
@@ -1021,12 +1021,12 @@ public final class Bridge implements ILayoutBridge {
         }
 
         @SuppressWarnings("unused")
-        public void dispatchPointer(MotionEvent arg0, long arg1) throws RemoteException {
+        public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
             // pass for now.
         }
 
         @SuppressWarnings("unused")
-        public void dispatchTrackball(MotionEvent arg0, long arg1) throws RemoteException {
+        public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
             // pass for now.
         }