Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 91aa5cbd authored by Bruno Martins's avatar Bruno Martins Committed by Michael Bestas
Browse files

Support for device specific key handlers



Co-authored-by: default avatarAlexander Hofbauer <alex@derhofbauer.at>
Co-authored-by: default avatarDanesh Mondegarian <daneshm90@gmail.com>
Co-authored-by: default avatarJorge Ruesga <jorge@ruesga.com>
Co-authored-by: default avatarPaul Keith <javelinanddart@gmail.com>
Co-authored-by: default avatarSteve Kondik <steve@cyngn.com>
Co-authored-by: default avatarZhao Wei Liew <zhaoweiliew@gmail.com>
Change-Id: Ie65a89cd7efd645622d99d47699df847bc3ad96b
parent c96ac1cc
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2012 The CyanogenMod Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.os;

import android.view.KeyEvent;

public interface DeviceKeyHandler {

    /**
     * Invoked when an unknown key was detected by the system, letting the device handle
     * this special keys prior to pass the key to the active app.
     *
     * @param event The key event to be handled
     * @return null if event is consumed, KeyEvent to be handled otherwise
     */
    public KeyEvent handleKeyEvent(KeyEvent event);
}
+56 −0
Original line number Diff line number Diff line
@@ -230,6 +230,7 @@ import com.android.internal.display.BrightnessUtils;
import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.os.DeviceKeyHandler;
import com.android.internal.os.RoSystemProperties;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardService;
@@ -264,11 +265,14 @@ import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;

import dalvik.system.PathClassLoader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -752,6 +756,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    // Timeout for showing the keyguard after the screen is on, in case no "ready" is received.
    private int mKeyguardDrawnTimeout = 1000;

    private final List<DeviceKeyHandler> mDeviceKeyHandlers = new ArrayList<>();

    private final boolean mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();

    private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
@@ -2598,6 +2604,29 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        initKeyGestures();
        mButtonOverridePermissionChecker = injector.getButtonOverridePermissionChecker();
        mSideFpsEventHandler = new SideFpsEventHandler(mContext, mHandler, mPowerManager);

        final String[] deviceKeyHandlerLibs = res.getStringArray(
                org.lineageos.platform.internal.R.array.config_deviceKeyHandlerLibs);
        final String[] deviceKeyHandlerClasses = res.getStringArray(
                org.lineageos.platform.internal.R.array.config_deviceKeyHandlerClasses);

        for (int i = 0;
                i < deviceKeyHandlerLibs.length && i < deviceKeyHandlerClasses.length; i++) {
            try {
                PathClassLoader loader = new PathClassLoader(
                        deviceKeyHandlerLibs[i], getClass().getClassLoader());
                Class<?> klass = loader.loadClass(deviceKeyHandlerClasses[i]);
                Constructor<?> constructor = klass.getConstructor(Context.class);
                mDeviceKeyHandlers.add((DeviceKeyHandler) constructor.newInstance(mContext));
            } catch (Exception e) {
                Slog.w(TAG, "Could not instantiate device key handler "
                        + deviceKeyHandlerLibs[i] + " from class "
                        + deviceKeyHandlerClasses[i], e);
            }
        }
        if (DEBUG_INPUT) {
            Slog.d(TAG, "" + mDeviceKeyHandlers.size() + " device key handlers loaded");
        }
    }

    private void initKeyCombinationRules() {
@@ -4095,6 +4124,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return true;
        }

        // Specific device key handling
        if (dispatchKeyToKeyHandlers(event)) {
            return true;
        }

        // Reserve all the META modifier combos for system behavior
        return (metaState & KeyEvent.META_META_ON) != 0;
    }
@@ -4606,6 +4640,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
    }

    private boolean dispatchKeyToKeyHandlers(KeyEvent event) {
        for (DeviceKeyHandler handler : mDeviceKeyHandlers) {
            try {
                if (DEBUG_INPUT) {
                    Log.d(TAG, "Dispatching key event " + event + " to handler " + handler);
                }
                event = handler.handleKeyEvent(event);
                if (event == null) {
                    return true;
                }
            } catch (Exception e) {
                Slog.w(TAG, "Could not dispatch event to device key handler", e);
            }
        }
        return false;
    }

    // TODO(b/117479243): handle it in InputPolicy
    /** {@inheritDoc} */
    @Override
@@ -5315,6 +5366,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                && (!isNavBarVirtKey || mNavBarVirtualKeyHapticFeedbackEnabled)
                && event.getRepeatCount() == 0;

        // Specific device key handling
        if (dispatchKeyToKeyHandlers(event)) {
            return 0;
        }

        // Handle special keys.
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK: {