While many readers of Android-centric websites such as our own are less likely to come across situations where a rogue application compromises their system, the same may not be true for the general population. Nearly every week we hear from various security researchers about new malware targeting Android users. Most of these malicious attacks can be avoided by inspecting permissions or avoiding installing sketchy-looking applications, and while we do recommend our readers take their phone’s security into their own hands, Google is responsible for securing every Android phone. To that end, the company quietly introduced a new security feature in Android 7.1 Nougat called “panic detection” which listens for multiple back button presses in succession then returns the user to their home screen.
Quite simply, if a rogue applications attempts to hijack the user’s screen and prevent the user from leaving (perhaps by implementing an Accessibility Service to intercept all key events), Android will itself override the application to bring back the home screen. The user can then presumably uninstall the malicious application from the launcher.
This feature flew under the radar, understandably so as Google would likely not want to advertise to the world one way they are gutting malicious applications. But a quick look at Android’s open source code reveals how this simple feature works on the devices that support it.
First of all, just because your device is running Android 7.1+ doesn’t mean this panic detection behavior is actually enabled. The value that determines whether the feature is on can be found in the
config.xml file within the SystemUI APK.
<!-- Control the behavior when the user panic presses the back button. 0 - Nothing 1 - Go to home --> <integer name="config_backPanicBehavior">0</integer>
By default, Android’s reaction to panic presses of the back button is to do nothing. If the integer value of
config_backPanicBehavior is set to 1, however, that’s where Android’s new protection measure kicks in.
PhoneWindowManager.java we can see the bulk of how this feature is implemented. First of all, the file defines two things: how many back button presses are needed for the system to determine that the user is “panicking” and then what action to take based on that state.
// 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;
By default, the system requires 4 consecutive back button presses to enter the panic mode. Whether or not the function uses the integer value of
PANIC_PRESS_BACK_HOME is determined by the value in the configuration file within the SystemUI APK.
Regardless of this value, each back button multi-press is checked to see if it will count as a panic press. First, the system intercepts the down press for the KEYCODE_BACK key event and checks whether or not the system is set to check for multi-presses or long-presses of the key. Then, the system checks whether or not it should pass the up press for the same KEYCODE_BACK key event to the user app.
interceptBackKeyDown() method, if the back key press counter is between 1 and 3, then the system skips the multi-press detection timeout as the panic detection requires at least 4 presses for any action to be taken.
Next, once the user removes their finger from the back key which triggers an up event, the
interceptBackKeyUp adds 1 to the back key counter. It then enqueues a message for 300 milliseconds in the future. The reason for this is because the system is reserving a 300 millisecond delay period when deciding if the back button presses are part of a multi-press event. If it is, then the user may be panic pressing the button so the system should not be sending the key event to the user application.
The 300ms multi press timeout value is stored in the secure setting “
multi_press_timeout” as shown below.
/** * 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";
By default, this value is set to 300ms.
/** * 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
Then, if a multi-press is indeed detected (>1 back button complete up/down presses within 300ms), the system calls the
backMultiPressAction method to determine what action to take. Finally, the back button counter is reset to 0.