Loading core/java/android/app/Activity.java +30 −10 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; Loading Loading @@ -1752,8 +1753,16 @@ public class Activity extends ContextThemeWrapper * * <p>If the focused view didn't want this event, this method is called. * * <p>The default implementation sets up state to call * {@link #onKeyLongPress}, and does other default key handling * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK} * by calling {@link #onBackPressed()}, though the behavior varies based * on the application compatibility mode: for * {@link android.os.Build.VERSION_CODES#ECLAIR} or later applications, * it will set up the dispatch to call {@link #onKeyUp} where the action * will be performed; for earlier applications, it will perform the * action immediately in on-down, as those versions of the platform * behaved. * * <p>Other additional default key handling may be performed * if configured with {@link #setDefaultKeyMode}. * * @return Return <code>true</code> to prevent this event from being propagated Loading @@ -1764,7 +1773,12 @@ public class Activity extends ContextThemeWrapper */ public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.ECLAIR) { event.startTracking(); } else { onBackPressed(); } return true; } Loading Loading @@ -1841,11 +1855,14 @@ public class Activity extends ContextThemeWrapper * @see KeyEvent */ public boolean onKeyUp(int keyCode, KeyEvent event) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.ECLAIR) { if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { onBackPressed(); return true; } } return false; } Loading Loading @@ -2016,11 +2033,14 @@ public class Activity extends ContextThemeWrapper */ public boolean dispatchKeyEvent(KeyEvent event) { onUserInteraction(); if (getWindow().superDispatchKeyEvent(event)) { Window win = getWindow(); if (win.superDispatchKeyEvent(event)) { return true; } return event.dispatch(this, mDecor != null ? mDecor.getKeyDispatcherState() : null, this); View decor = mDecor; if (decor == null) decor = win.getDecorView(); return event.dispatch(this, decor != null ? decor.getKeyDispatcherState() : null, this); } /** Loading core/java/android/app/SearchDialog.java +7 −7 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import android.util.Log; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; Loading Loading @@ -1684,7 +1683,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS public static class SearchAutoComplete extends AutoCompleteTextView { private int mThreshold; private int mLastKeyDown; private SearchDialog mSearchDialog; public SearchAutoComplete(Context context) { Loading Loading @@ -1765,26 +1763,26 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS */ @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { mLastKeyDown = keyCode; if (mSearchDialog.mSearchable == null) { return false; } if (keyCode == KeyEvent.KEYCODE_BACK) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { // We releae the back key, might we want to do // We release the back key, might we want to do // something before the IME? if (mSearchDialog.backToPreviousComponent(false)) { getKeyDispatcherState().startTracking(event, this); return true; } if (isInputMethodNotNeeded() || (isEmpty() && getDropDownChildCount() >= getAdapterCount())) { getKeyDispatcherState().startTracking(event, this); return true; } mLastKeyDown = 0; return false; // will dismiss soft keyboard if necessary } else if (event.getAction() == KeyEvent.ACTION_UP && mLastKeyDown == keyCode && !event.isCanceled()) { && event.isTracking() && !event.isCanceled()) { if (mSearchDialog.backToPreviousComponent(true)) { return true; } Loading Loading @@ -1815,8 +1813,10 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS protected boolean handleBackKey(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { // Consume the event, to get an up at which point we execute. event.startTracking(); return true; } if (event.getAction() == KeyEvent.ACTION_UP && event.isTracking() Loading core/java/android/os/Build.java +3 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ public class Build { * Service.onStartCommand} function will return the new * {@link android.app.Service#START_STICKY} behavior instead of the * old compatibility {@link android.app.Service#START_STICKY_COMPATIBILITY}. * <li> The {@link android.app.Activity} class will now execute back * key presses on the key up instead of key down, to be able to detect * canceled presses from virtual keys. * </ul> */ public static final int ECLAIR = CUR_DEVELOPMENT; Loading core/java/android/view/KeyEvent.java +16 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import android.util.SparseIntArray; import android.view.KeyCharacterMap; import android.view.KeyCharacterMap.KeyData; Loading Loading @@ -319,6 +320,9 @@ public class KeyEvent implements Parcelable { return KeyCharacterMap.getDeadChar(accent, c); } static final boolean DEBUG = false; static final String TAG = "KeyEvent"; private int mMetaState; private int mAction; private int mKeyCode; Loading Loading @@ -1028,13 +1032,17 @@ public class KeyEvent implements Parcelable { switch (mAction) { case ACTION_DOWN: { mFlags &= ~FLAG_START_TRACKING; if (DEBUG) Log.v(TAG, "Key down to " + target + " in " + state + ": " + this); boolean res = receiver.onKeyDown(mKeyCode, this); if (state != null) { if (res && mRepeatCount == 0 && (mFlags&FLAG_START_TRACKING) != 0) { if (DEBUG) Log.v(TAG, " Start tracking!"); state.startTracking(this, target); } else if (isLongPress() && state.isTracking(this)) { try { if (receiver.onKeyLongPress(mKeyCode, this)) { if (DEBUG) Log.v(TAG, " Clear from long press!"); state.performedLongPress(this); res = true; } Loading @@ -1045,6 +1053,8 @@ public class KeyEvent implements Parcelable { return res; } case ACTION_UP: if (DEBUG) Log.v(TAG, "Key up to " + target + " in " + state + ": " + this); if (state != null) { state.handleUpEvent(this); } Loading Loading @@ -1085,6 +1095,7 @@ public class KeyEvent implements Parcelable { * Reset back to initial state. */ public void reset() { if (DEBUG) Log.v(TAG, "Reset: " + this); mDownKeyCode = 0; mDownTarget = null; mActiveLongPresses.clear(); Loading @@ -1095,6 +1106,7 @@ public class KeyEvent implements Parcelable { */ public void reset(Object target) { if (mDownTarget == target) { if (DEBUG) Log.v(TAG, "Reset in " + target + ": " + this); mDownKeyCode = 0; mDownTarget = null; } Loading @@ -1115,6 +1127,7 @@ public class KeyEvent implements Parcelable { throw new IllegalArgumentException( "Can only start tracking on a down event"); } if (DEBUG) Log.v(TAG, "Start trackingt in " + target + ": " + this); mDownKeyCode = event.getKeyCode(); mDownTarget = target; } Loading Loading @@ -1145,12 +1158,15 @@ public class KeyEvent implements Parcelable { */ public void handleUpEvent(KeyEvent event) { final int keyCode = event.getKeyCode(); if (DEBUG) Log.v(TAG, "Handle key up " + event + ": " + this); int index = mActiveLongPresses.indexOfKey(keyCode); if (index >= 0) { if (DEBUG) Log.v(TAG, " Index: " + index); event.mFlags |= FLAG_CANCELED | FLAG_CANCELED_LONG_PRESS; mActiveLongPresses.removeAt(index); } if (mDownKeyCode == keyCode) { if (DEBUG) Log.v(TAG, " Tracking!"); event.mFlags |= FLAG_TRACKING; mDownKeyCode = 0; mDownTarget = null; Loading core/java/android/widget/AbsListView.java +3 −1 Original line number Diff line number Diff line Loading @@ -2946,7 +2946,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te break; case KeyEvent.KEYCODE_BACK: if (mFiltered && mPopup != null && mPopup.isShowing()) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { getKeyDispatcherState().startTracking(event, this); handled = true; } else if (event.getAction() == KeyEvent.ACTION_UP && event.isTracking() && !event.isCanceled()) { Loading Loading
core/java/android/app/Activity.java +30 −10 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; Loading Loading @@ -1752,8 +1753,16 @@ public class Activity extends ContextThemeWrapper * * <p>If the focused view didn't want this event, this method is called. * * <p>The default implementation sets up state to call * {@link #onKeyLongPress}, and does other default key handling * <p>The default implementation takes care of {@link KeyEvent#KEYCODE_BACK} * by calling {@link #onBackPressed()}, though the behavior varies based * on the application compatibility mode: for * {@link android.os.Build.VERSION_CODES#ECLAIR} or later applications, * it will set up the dispatch to call {@link #onKeyUp} where the action * will be performed; for earlier applications, it will perform the * action immediately in on-down, as those versions of the platform * behaved. * * <p>Other additional default key handling may be performed * if configured with {@link #setDefaultKeyMode}. * * @return Return <code>true</code> to prevent this event from being propagated Loading @@ -1764,7 +1773,12 @@ public class Activity extends ContextThemeWrapper */ public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.ECLAIR) { event.startTracking(); } else { onBackPressed(); } return true; } Loading Loading @@ -1841,11 +1855,14 @@ public class Activity extends ContextThemeWrapper * @see KeyEvent */ public boolean onKeyUp(int keyCode, KeyEvent event) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.ECLAIR) { if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { onBackPressed(); return true; } } return false; } Loading Loading @@ -2016,11 +2033,14 @@ public class Activity extends ContextThemeWrapper */ public boolean dispatchKeyEvent(KeyEvent event) { onUserInteraction(); if (getWindow().superDispatchKeyEvent(event)) { Window win = getWindow(); if (win.superDispatchKeyEvent(event)) { return true; } return event.dispatch(this, mDecor != null ? mDecor.getKeyDispatcherState() : null, this); View decor = mDecor; if (decor == null) decor = win.getDecorView(); return event.dispatch(this, decor != null ? decor.getKeyDispatcherState() : null, this); } /** Loading
core/java/android/app/SearchDialog.java +7 −7 Original line number Diff line number Diff line Loading @@ -51,7 +51,6 @@ import android.util.Log; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; Loading Loading @@ -1684,7 +1683,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS public static class SearchAutoComplete extends AutoCompleteTextView { private int mThreshold; private int mLastKeyDown; private SearchDialog mSearchDialog; public SearchAutoComplete(Context context) { Loading Loading @@ -1765,26 +1763,26 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS */ @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { mLastKeyDown = keyCode; if (mSearchDialog.mSearchable == null) { return false; } if (keyCode == KeyEvent.KEYCODE_BACK) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { // We releae the back key, might we want to do // We release the back key, might we want to do // something before the IME? if (mSearchDialog.backToPreviousComponent(false)) { getKeyDispatcherState().startTracking(event, this); return true; } if (isInputMethodNotNeeded() || (isEmpty() && getDropDownChildCount() >= getAdapterCount())) { getKeyDispatcherState().startTracking(event, this); return true; } mLastKeyDown = 0; return false; // will dismiss soft keyboard if necessary } else if (event.getAction() == KeyEvent.ACTION_UP && mLastKeyDown == keyCode && !event.isCanceled()) { && event.isTracking() && !event.isCanceled()) { if (mSearchDialog.backToPreviousComponent(true)) { return true; } Loading Loading @@ -1815,8 +1813,10 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS protected boolean handleBackKey(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { // Consume the event, to get an up at which point we execute. event.startTracking(); return true; } if (event.getAction() == KeyEvent.ACTION_UP && event.isTracking() Loading
core/java/android/os/Build.java +3 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ public class Build { * Service.onStartCommand} function will return the new * {@link android.app.Service#START_STICKY} behavior instead of the * old compatibility {@link android.app.Service#START_STICKY_COMPATIBILITY}. * <li> The {@link android.app.Activity} class will now execute back * key presses on the key up instead of key down, to be able to detect * canceled presses from virtual keys. * </ul> */ public static final int ECLAIR = CUR_DEVELOPMENT; Loading
core/java/android/view/KeyEvent.java +16 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view; import android.os.Parcel; import android.os.Parcelable; import android.util.Log; import android.util.SparseIntArray; import android.view.KeyCharacterMap; import android.view.KeyCharacterMap.KeyData; Loading Loading @@ -319,6 +320,9 @@ public class KeyEvent implements Parcelable { return KeyCharacterMap.getDeadChar(accent, c); } static final boolean DEBUG = false; static final String TAG = "KeyEvent"; private int mMetaState; private int mAction; private int mKeyCode; Loading Loading @@ -1028,13 +1032,17 @@ public class KeyEvent implements Parcelable { switch (mAction) { case ACTION_DOWN: { mFlags &= ~FLAG_START_TRACKING; if (DEBUG) Log.v(TAG, "Key down to " + target + " in " + state + ": " + this); boolean res = receiver.onKeyDown(mKeyCode, this); if (state != null) { if (res && mRepeatCount == 0 && (mFlags&FLAG_START_TRACKING) != 0) { if (DEBUG) Log.v(TAG, " Start tracking!"); state.startTracking(this, target); } else if (isLongPress() && state.isTracking(this)) { try { if (receiver.onKeyLongPress(mKeyCode, this)) { if (DEBUG) Log.v(TAG, " Clear from long press!"); state.performedLongPress(this); res = true; } Loading @@ -1045,6 +1053,8 @@ public class KeyEvent implements Parcelable { return res; } case ACTION_UP: if (DEBUG) Log.v(TAG, "Key up to " + target + " in " + state + ": " + this); if (state != null) { state.handleUpEvent(this); } Loading Loading @@ -1085,6 +1095,7 @@ public class KeyEvent implements Parcelable { * Reset back to initial state. */ public void reset() { if (DEBUG) Log.v(TAG, "Reset: " + this); mDownKeyCode = 0; mDownTarget = null; mActiveLongPresses.clear(); Loading @@ -1095,6 +1106,7 @@ public class KeyEvent implements Parcelable { */ public void reset(Object target) { if (mDownTarget == target) { if (DEBUG) Log.v(TAG, "Reset in " + target + ": " + this); mDownKeyCode = 0; mDownTarget = null; } Loading @@ -1115,6 +1127,7 @@ public class KeyEvent implements Parcelable { throw new IllegalArgumentException( "Can only start tracking on a down event"); } if (DEBUG) Log.v(TAG, "Start trackingt in " + target + ": " + this); mDownKeyCode = event.getKeyCode(); mDownTarget = target; } Loading Loading @@ -1145,12 +1158,15 @@ public class KeyEvent implements Parcelable { */ public void handleUpEvent(KeyEvent event) { final int keyCode = event.getKeyCode(); if (DEBUG) Log.v(TAG, "Handle key up " + event + ": " + this); int index = mActiveLongPresses.indexOfKey(keyCode); if (index >= 0) { if (DEBUG) Log.v(TAG, " Index: " + index); event.mFlags |= FLAG_CANCELED | FLAG_CANCELED_LONG_PRESS; mActiveLongPresses.removeAt(index); } if (mDownKeyCode == keyCode) { if (DEBUG) Log.v(TAG, " Tracking!"); event.mFlags |= FLAG_TRACKING; mDownKeyCode = 0; mDownTarget = null; Loading
core/java/android/widget/AbsListView.java +3 −1 Original line number Diff line number Diff line Loading @@ -2946,7 +2946,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te break; case KeyEvent.KEYCODE_BACK: if (mFiltered && mPopup != null && mPopup.isShowing()) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { getKeyDispatcherState().startTracking(event, this); handled = true; } else if (event.getAction() == KeyEvent.ACTION_UP && event.isTracking() && !event.isCanceled()) { Loading