Merge "Add panic detection to back button" into cw-f-dev

This commit is contained in:
Anthony Hugh
2016-08-05 00:47:06 +00:00
committed by Android (Google) Code Review
8 changed files with 135 additions and 13 deletions

View File

@@ -5344,6 +5344,13 @@ public final class Settings {
*/ */
public static final String LONG_PRESS_TIMEOUT = "long_press_timeout"; public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
/**
* The duration in milliseconds between the first tap's up event and the second tap's
* down event for an interaction to be considered part of the same multi-press.
* @hide
*/
public static final String MULTI_PRESS_TIMEOUT = "multi_press_timeout";
/** /**
* List of the enabled print services. * List of the enabled print services.
* *

View File

@@ -63,6 +63,12 @@ public class ViewConfiguration {
*/ */
private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500; private static final int DEFAULT_LONG_PRESS_TIMEOUT = 500;
/**
* Defines the default duration in milliseconds between the first tap's up event and the second
* tap's down event for an interaction to be considered part of the same multi-press.
*/
private static final int DEFAULT_MULTI_PRESS_TIMEOUT = 300;
/** /**
* Defines the time between successive key repeats in milliseconds. * Defines the time between successive key repeats in milliseconds.
*/ */
@@ -440,6 +446,16 @@ public class ViewConfiguration {
DEFAULT_LONG_PRESS_TIMEOUT); DEFAULT_LONG_PRESS_TIMEOUT);
} }
/**
* @return the duration in milliseconds between the first tap's up event and the second tap's
* down event for an interaction to be considered part of the same multi-press.
* @hide
*/
public static int getMultiPressTimeout() {
return AppGlobals.getIntCoreSetting(Settings.Secure.MULTI_PRESS_TIMEOUT,
DEFAULT_MULTI_PRESS_TIMEOUT);
}
/** /**
* @return the time before the first key repeat in milliseconds. * @return the time before the first key repeat in milliseconds.
*/ */

View File

@@ -796,6 +796,12 @@
--> -->
<integer name="config_longPressOnBackBehavior">0</integer> <integer name="config_longPressOnBackBehavior">0</integer>
<!-- Control the behavior when the user panic presses the back button.
0 - Nothing
1 - Go to home
-->
<integer name="config_backPanicBehavior">0</integer>
<!-- Control the behavior when the user short presses the power button. <!-- Control the behavior when the user short presses the power button.
0 - Nothing 0 - Nothing
1 - Go to sleep (doze) 1 - Go to sleep (doze)

View File

@@ -375,6 +375,7 @@
<java-symbol type="integer" name="config_immersive_mode_confirmation_panic" /> <java-symbol type="integer" name="config_immersive_mode_confirmation_panic" />
<java-symbol type="integer" name="config_longPressOnPowerBehavior" /> <java-symbol type="integer" name="config_longPressOnPowerBehavior" />
<java-symbol type="integer" name="config_longPressOnBackBehavior" /> <java-symbol type="integer" name="config_longPressOnBackBehavior" />
<java-symbol type="integer" name="config_backPanicBehavior" />
<java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" />
<java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" />
<java-symbol type="integer" name="config_max_pan_devices" /> <java-symbol type="integer" name="config_max_pan_devices" />

View File

@@ -155,6 +155,9 @@
<!-- Default for Settings.Secure.LONG_PRESS_TIMEOUT_MILLIS --> <!-- Default for Settings.Secure.LONG_PRESS_TIMEOUT_MILLIS -->
<integer name="def_long_press_timeout_millis">400</integer> <integer name="def_long_press_timeout_millis">400</integer>
<!-- Default for Settings.Secure.MULTI_PRESS_TIMEOUT -->
<integer name="def_multi_press_timeout_millis">300</integer>
<!-- Default for Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD --> <!-- Default for Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD -->
<bool name="def_show_ime_with_hard_keyboard">false</bool> <bool name="def_show_ime_with_hard_keyboard">false</bool>

View File

@@ -2102,7 +2102,7 @@ public class SettingsProvider extends ContentProvider {
} }
private final class UpgradeController { private final class UpgradeController {
private static final int SETTINGS_VERSION = 130; private static final int SETTINGS_VERSION = 131;
private final int mUserId; private final int mUserId;
@@ -2410,6 +2410,22 @@ public class SettingsProvider extends ContentProvider {
currentVersion = 130; currentVersion = 130;
} }
if (currentVersion == 130) {
// Initialize new multi-press timeout to default value
final SettingsState systemSecureSettings = getSecureSettingsLocked(userId);
final String oldValue = systemSecureSettings.getSettingLocked(
Settings.Secure.MULTI_PRESS_TIMEOUT).getValue();
if (TextUtils.equals(null, oldValue)) {
systemSecureSettings.insertSettingLocked(
Settings.Secure.MULTI_PRESS_TIMEOUT,
String.valueOf(getContext().getResources().getInteger(
R.integer.def_multi_press_timeout_millis)),
SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 131;
}
if (currentVersion != newVersion) { if (currentVersion != newVersion) {
Slog.w("SettingsProvider", "warning: upgrading settings database to version " Slog.w("SettingsProvider", "warning: upgrading settings database to version "
+ newVersion + " left it at " + newVersion + " left it at "

View File

@@ -42,6 +42,7 @@ final class CoreSettingsObserver extends ContentObserver {
String, Class<?>>(); String, Class<?>>();
static { static {
sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class); sSecureSettingToTypeMap.put(Settings.Secure.LONG_PRESS_TIMEOUT, int.class);
sSecureSettingToTypeMap.put(Settings.Secure.MULTI_PRESS_TIMEOUT, int.class);
// add other secure settings here... // add other secure settings here...
sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class); sSystemSettingToTypeMap.put(Settings.System.TIME_12_24, String.class);

View File

@@ -200,6 +200,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int MULTI_PRESS_POWER_THEATER_MODE = 1; static final int MULTI_PRESS_POWER_THEATER_MODE = 1;
static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2; static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2;
// Number of presses needed before we induce panic press behavior on the back button
static final int PANIC_PRESS_BACK_COUNT = 4;
static final int PANIC_PRESS_BACK_NOTHING = 0;
static final int PANIC_PRESS_BACK_HOME = 1;
// These need to match the documentation/constant in // These need to match the documentation/constant in
// core/res/res/values/config.xml // core/res/res/values/config.xml
static final int LONG_PRESS_HOME_NOTHING = 0; static final int LONG_PRESS_HOME_NOTHING = 0;
@@ -406,6 +411,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
volatile boolean mBackKeyHandled; volatile boolean mBackKeyHandled;
volatile boolean mBeganFromNonInteractive; volatile boolean mBeganFromNonInteractive;
volatile int mPowerKeyPressCounter; volatile int mPowerKeyPressCounter;
volatile int mBackKeyPressCounter;
volatile boolean mEndCallKeyHandled; volatile boolean mEndCallKeyHandled;
volatile boolean mCameraGestureTriggeredDuringGoingToSleep; volatile boolean mCameraGestureTriggeredDuringGoingToSleep;
volatile boolean mGoingToSleep; volatile boolean mGoingToSleep;
@@ -464,6 +470,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mDoublePressOnPowerBehavior; int mDoublePressOnPowerBehavior;
int mTriplePressOnPowerBehavior; int mTriplePressOnPowerBehavior;
int mLongPressOnBackBehavior; int mLongPressOnBackBehavior;
int mPanicPressOnBackBehavior;
int mShortPressOnSleepBehavior; int mShortPressOnSleepBehavior;
int mShortPressWindowBehavior; int mShortPressWindowBehavior;
boolean mAwake; boolean mAwake;
@@ -726,6 +733,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU = 17; private static final int MSG_SHOW_TV_PICTURE_IN_PICTURE_MENU = 17;
private static final int MSG_BACK_LONG_PRESS = 18; private static final int MSG_BACK_LONG_PRESS = 18;
private static final int MSG_DISPOSE_INPUT_CONSUMER = 19; private static final int MSG_DISPOSE_INPUT_CONSUMER = 19;
private static final int MSG_BACK_DELAYED_PRESS = 20;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -792,10 +800,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break; break;
case MSG_BACK_LONG_PRESS: case MSG_BACK_LONG_PRESS:
backLongPress(); backLongPress();
finishBackKeyPress();
break; break;
case MSG_DISPOSE_INPUT_CONSUMER: case MSG_DISPOSE_INPUT_CONSUMER:
disposeInputConsumer((InputConsumer) msg.obj); disposeInputConsumer((InputConsumer) msg.obj);
break; break;
case MSG_BACK_DELAYED_PRESS:
backMultiPressAction((Long) msg.obj, msg.arg1);
finishBackKeyPress();
break;
} }
} }
} }
@@ -1010,6 +1023,52 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} }
} }
private void interceptBackKeyDown() {
// Reset back key state for long press
mBackKeyHandled = false;
// Cancel multi-press detection timeout.
if (hasPanicPressOnBackBehavior()) {
if (mBackKeyPressCounter != 0
&& mBackKeyPressCounter < PANIC_PRESS_BACK_COUNT) {
mHandler.removeMessages(MSG_BACK_DELAYED_PRESS);
}
}
if (hasLongPressOnBackBehavior()) {
Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
}
// returns true if the key was handled and should not be passed to the user
private boolean interceptBackKeyUp(KeyEvent event) {
// Cache handled state
boolean handled = mBackKeyHandled;
if (hasPanicPressOnBackBehavior()) {
// Check for back key panic press
++mBackKeyPressCounter;
final long eventTime = event.getDownTime();
if (mBackKeyPressCounter <= PANIC_PRESS_BACK_COUNT) {
// This could be a multi-press. Wait a little bit longer to confirm.
Message msg = mHandler.obtainMessage(MSG_BACK_DELAYED_PRESS,
mBackKeyPressCounter, 0, eventTime);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg, ViewConfiguration.getMultiPressTimeout());
}
}
// Reset back long press state
cancelPendingBackKeyAction();
return handled;
}
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
// Hold a wake lock until the power key is released. // Hold a wake lock until the power key is released.
if (!mPowerKeyWakeLock.isHeld()) { if (!mPowerKeyWakeLock.isHeld()) {
@@ -1140,6 +1199,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} }
} }
private void finishBackKeyPress() {
mBackKeyPressCounter = 0;
}
private void cancelPendingPowerKeyAction() { private void cancelPendingPowerKeyAction() {
if (!mPowerKeyHandled) { if (!mPowerKeyHandled) {
mPowerKeyHandled = true; mPowerKeyHandled = true;
@@ -1154,6 +1217,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} }
} }
private void backMultiPressAction(long eventTime, int count) {
if (count >= PANIC_PRESS_BACK_COUNT) {
switch (mPanicPressOnBackBehavior) {
case PANIC_PRESS_BACK_NOTHING:
break;
case PANIC_PRESS_BACK_HOME:
launchHomeFromHotKey();
break;
}
}
}
private void powerPress(long eventTime, boolean interactive, int count) { private void powerPress(long eventTime, boolean interactive, int count) {
if (mScreenOnEarly && !mScreenOnFully) { if (mScreenOnEarly && !mScreenOnFully) {
Slog.i(TAG, "Suppressed redundant power key press while " Slog.i(TAG, "Suppressed redundant power key press while "
@@ -1312,6 +1387,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING; return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING;
} }
private boolean hasPanicPressOnBackBehavior() {
return mPanicPressOnBackBehavior != PANIC_PRESS_BACK_NOTHING;
}
private void interceptScreenshotChord() { private void interceptScreenshotChord() {
if (mScreenshotChordEnabled if (mScreenshotChordEnabled
&& mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered
@@ -1639,6 +1718,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mLongPressOnBackBehavior = mContext.getResources().getInteger( mLongPressOnBackBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_longPressOnBackBehavior); com.android.internal.R.integer.config_longPressOnBackBehavior);
mPanicPressOnBackBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_backPanicBehavior);
mShortPressOnPowerBehavior = mContext.getResources().getInteger( mShortPressOnPowerBehavior = mContext.getResources().getInteger(
com.android.internal.R.integer.config_shortPressOnPowerBehavior); com.android.internal.R.integer.config_shortPressOnPowerBehavior);
@@ -5607,20 +5688,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
switch (keyCode) { switch (keyCode) {
case KeyEvent.KEYCODE_BACK: { case KeyEvent.KEYCODE_BACK: {
if (down) { if (down) {
mBackKeyHandled = false; interceptBackKeyDown();
if (hasLongPressOnBackBehavior()) {
Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
} else { } else {
boolean handled = mBackKeyHandled; boolean handled = interceptBackKeyUp(event);
// Reset back key state // Don't pass back press to app if we've already handled it via long press
cancelPendingBackKeyAction();
// Don't pass back press to app if we've already handled it
if (handled) { if (handled) {
result &= ~ACTION_PASS_TO_USER; result &= ~ACTION_PASS_TO_USER;
} }