OSDN Git Service

Cancel or drop key events if activity is stopped.
authorWale Ogunwale <ogunwale@google.com>
Wed, 5 Nov 2014 23:17:35 +0000 (15:17 -0800)
committerWale Ogunwale <ogunwale@google.com>
Wed, 12 Nov 2014 17:23:22 +0000 (09:23 -0800)
After an activity instance state is saved due to onStop()/onPause(),
there is a small window where it can still get key events like the
back button since we still allow the ActivityThread to handle
pending messages (like memory trim request) before informing the
activity manager that we are done. If the activity is stopped,
we will now drop non-terminal input events and set the cancel
flag on terminal events.

Bug: 18151331
Change-Id: I370d7c871530eea4b16fa42428d0248f1a87abb6

core/java/android/view/InputEvent.java
core/java/android/view/KeyEvent.java
core/java/android/view/MotionEvent.java
core/java/android/view/ViewRootImpl.java

index 1ecdf30..e2ad3ad 100644 (file)
@@ -196,6 +196,13 @@ public abstract class InputEvent implements Parcelable {
     public abstract long getEventTimeNano();
 
     /**
+     * Marks the input event as being canceled.
+     *
+     * @hide
+     */
+    public abstract void cancel();
+
+    /**
      * Gets the unique sequence number of this event.
      * Every input event that is created or received by a process has a
      * unique sequence number.  Moreover, a new sequence number is obtained
index 0701b53..243a0fc 100644 (file)
@@ -2304,6 +2304,16 @@ public class KeyEvent extends InputEvent implements Parcelable {
     }
 
     /**
+     * Set {@link #FLAG_CANCELED} flag for the key event.
+     *
+     * @hide
+     */
+    @Override
+    public final void cancel() {
+        mFlags |= FLAG_CANCELED;
+    }
+
+    /**
      * Call this during {@link Callback#onKeyDown} to have the system track
      * the key through its final up (possibly including a long press).  Note
      * that only one key can be tracked at a time -- if another key down
index ae39b7a..1c5c41c 100644 (file)
@@ -3168,6 +3168,12 @@ public final class MotionEvent extends InputEvent implements Parcelable {
         return ev;
     }
 
+    /** @hide */
+    @Override
+    public final void cancel() {
+        setAction(ACTION_CANCEL);
+    }
+
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(PARCEL_TOKEN_MOTION_EVENT);
         nativeWriteToParcel(mNativePtr, out);
index 5d2a24b..fe17417 100644 (file)
@@ -3596,12 +3596,19 @@ public final class ViewRootImpl implements ViewParent,
             if (mView == null || !mAdded) {
                 Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
                 return true;
-            } else if (!mAttachInfo.mHasWindowFocus &&
-                  !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) &&
-                  !isTerminalInputEvent(q.mEvent)) {
-                // If this is a focused event and the window doesn't currently have input focus,
-                // then drop this event.  This could be an event that came back from the previous
-                // stage but the window has lost focus in the meantime.
+            } else if ((!mAttachInfo.mHasWindowFocus || mStopped)
+                    && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+                // This is a focus event and the window doesn't currently have input focus or
+                // has stopped. This could be an event that came back from the previous stage
+                // but the window has lost focus or stopped in the meantime.
+                if (isTerminalInputEvent(q.mEvent)) {
+                    // Don't drop terminal input events, however mark them as canceled.
+                    q.mEvent.cancel();
+                    Slog.w(TAG, "Cancelling event due to no window focus: " + q.mEvent);
+                    return false;
+                }
+
+                // Drop non-terminal input events.
                 Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent);
                 return true;
             }