androidkeydownxboxgamepadgamecontroller

Detect/override controller "Home" button press android


I have an android application that is meant to be used with a game controller connected to the android device.

Most game controllers have a center 'home' button that I would like to use to pause the game (for example, an Xbox controller center nexus button should pause).

However, when you press the center nexus button on the controller it causes the entire app to close as though the actual home button on the phone was pressed. Why is the center button on some controllers causing the app to return to the home screen? Note, this doesn't happen with all controllers or all devices. For example, using a pixel 6 and an xbox controller it doesn't send the app home. But using a galaxy a32 the center nexus button does triggers the home action.

I understand its not possible to intercept the actual home action from within an app. But is it possible to do so from a physical controller? Or is it possible to remap the controller buttons?

I tried this in an attempt to intercept the home action:

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.e("KeyPress", "Code: " + keyCode);
        switch (event.getKeyCode()){
            case KeyEvent.KEYCODE_HOME:
                return false;
            default:
                return super.onKeyDown(keyCode, event);
        }
    }

but this isn't working. Pressing the center button on the controller doesn't trigger the log but it still goes to the home screen.

Any ideas how to make certain button on physical controllers not trigger the home action?

Thanks


Solution

  • This happens with gamepads that send the same input code used for the "Homepage" key on some keyboards. By default, HID input devices are handled by the hid-input driver which always translates the "Consumer Application Control Home" usage (000C:0223) to the KEY_HOMEPAGE Linux input event code.

    https://github.com/torvalds/linux/blob/4e23eeebb2e57f5a28b36221aa776b5a1122dde5/drivers/hid/hid-input.c#L1151

    The Android OS converts KEY_HOMEPAGE to KeyEvent.KEYCODE_HOME which is handled by the framework and never delivered to applications. Probably it should convert it to BTN_MODE as suggested by the Linux gamepad specification.

    If you have root access you can fix this by adding a Key Layout file to correct the button mapping for a specific device. See Vendor_045e_Product_02fd.kl for an example of a key layout file that maps KEY_HOMEPAGE (Linux input event code 172) to Android's KeyEvent.KEYCODE_BUTTON_MODE.