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

Commit 6d0ac955 authored by Vaibhav Devmurari's avatar Vaibhav Devmurari
Browse files

Log system keys and shortcuts

Test: atest ShortcutLoggingTests
Bug: 280423320
Change-Id: I22ca8cca9f3ea42625b1c406eec51ebeebc17cec
parent 83ec16e2
Loading
Loading
Loading
Loading
+301 −9
Original line number Diff line number Diff line
@@ -21,12 +21,16 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Intent;
import android.hardware.input.KeyboardLayout;
import android.icu.util.ULocale;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.inputmethod.InputMethodSubtype;

import com.android.internal.annotations.VisibleForTesting;
@@ -36,8 +40,12 @@ import com.android.internal.util.FrameworkStatsLog;

import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Collect Keyboard metrics
@@ -56,7 +64,8 @@ public final class KeyboardMetricsCollector {
            LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
            LAYOUT_SELECTION_CRITERIA_DEFAULT
    })
    public @interface LayoutSelectionCriteria {}
    public @interface LayoutSelectionCriteria {
    }

    /** Manual selection by user */
    public static final int LAYOUT_SELECTION_CRITERIA_USER = 0;
@@ -76,17 +85,301 @@ public final class KeyboardMetricsCollector {
    @VisibleForTesting
    static final String DEFAULT_LANGUAGE_TAG = "None";

    public enum KeyboardLogEvent {
        UNSPECIFIED(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__UNSPECIFIED,
                "INVALID_KEYBOARD_EVENT"),
        HOME(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME,
                "HOME"),
        RECENT_APPS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS,
                "RECENT_APPS"),
        BACK(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BACK,
                "BACK"),
        APP_SWITCH(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__APP_SWITCH,
                "APP_SWITCH"),
        LAUNCH_ASSISTANT(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_ASSISTANT,
                "LAUNCH_ASSISTANT"),
        LAUNCH_VOICE_ASSISTANT(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_VOICE_ASSISTANT,
                "LAUNCH_VOICE_ASSISTANT"),
        LAUNCH_SYSTEM_SETTINGS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SYSTEM_SETTINGS,
                "LAUNCH_SYSTEM_SETTINGS"),
        TOGGLE_NOTIFICATION_PANEL(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_NOTIFICATION_PANEL,
                "TOGGLE_NOTIFICATION_PANEL"),
        TOGGLE_TASKBAR(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_TASKBAR,
                "TOGGLE_TASKBAR"),
        TAKE_SCREENSHOT(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TAKE_SCREENSHOT,
                "TAKE_SCREENSHOT"),
        OPEN_SHORTCUT_HELPER(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_SHORTCUT_HELPER,
                "OPEN_SHORTCUT_HELPER"),
        BRIGHTNESS_UP(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_UP,
                "BRIGHTNESS_UP"),
        BRIGHTNESS_DOWN(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__BRIGHTNESS_DOWN,
                "BRIGHTNESS_DOWN"),
        KEYBOARD_BACKLIGHT_UP(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_UP,
                "KEYBOARD_BACKLIGHT_UP"),
        KEYBOARD_BACKLIGHT_DOWN(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_DOWN,
                "KEYBOARD_BACKLIGHT_DOWN"),
        KEYBOARD_BACKLIGHT_TOGGLE(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__KEYBOARD_BACKLIGHT_TOGGLE,
                "KEYBOARD_BACKLIGHT_TOGGLE"),
        VOLUME_UP(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_UP,
                "VOLUME_UP"),
        VOLUME_DOWN(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_DOWN,
                "VOLUME_DOWN"),
        VOLUME_MUTE(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__VOLUME_MUTE,
                "VOLUME_MUTE"),
        ALL_APPS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ALL_APPS,
                "ALL_APPS"),
        LAUNCH_SEARCH(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_SEARCH,
                "LAUNCH_SEARCH"),
        LANGUAGE_SWITCH(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LANGUAGE_SWITCH,
                "LANGUAGE_SWITCH"),
        ACCESSIBILITY_ALL_APPS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__ACCESSIBILITY_ALL_APPS,
                "ACCESSIBILITY_ALL_APPS"),
        TOGGLE_CAPS_LOCK(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_CAPS_LOCK,
                "TOGGLE_CAPS_LOCK"),
        SYSTEM_MUTE(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_MUTE,
                "SYSTEM_MUTE"),
        SPLIT_SCREEN_NAVIGATION(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SPLIT_SCREEN_NAVIGATION,
                "SPLIT_SCREEN_NAVIGATION"),
        TRIGGER_BUG_REPORT(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TRIGGER_BUG_REPORT,
                "TRIGGER_BUG_REPORT"),
        LOCK_SCREEN(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LOCK_SCREEN,
                "LOCK_SCREEN"),
        OPEN_NOTES(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__OPEN_NOTES,
                "OPEN_NOTES"),
        TOGGLE_POWER(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__TOGGLE_POWER,
                "TOGGLE_POWER"),
        SYSTEM_NAVIGATION(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SYSTEM_NAVIGATION,
                "SYSTEM_NAVIGATION"),
        SLEEP(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__SLEEP,
                "SLEEP"),
        WAKEUP(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__WAKEUP,
                "WAKEUP"),
        MEDIA_KEY(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__MEDIA_KEY,
                "MEDIA_KEY"),
        LAUNCH_DEFAULT_BROWSER(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_BROWSER,
                "LAUNCH_DEFAULT_BROWSER"),
        LAUNCH_DEFAULT_EMAIL(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_EMAIL,
                "LAUNCH_DEFAULT_EMAIL"),
        LAUNCH_DEFAULT_CONTACTS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CONTACTS,
                "LAUNCH_DEFAULT_CONTACTS"),
        LAUNCH_DEFAULT_CALENDAR(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALENDAR,
                "LAUNCH_DEFAULT_CALENDAR"),
        LAUNCH_DEFAULT_CALCULATOR(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_CALCULATOR,
                "LAUNCH_DEFAULT_CALCULATOR"),
        LAUNCH_DEFAULT_MUSIC(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MUSIC,
                "LAUNCH_DEFAULT_MUSIC"),
        LAUNCH_DEFAULT_MAPS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MAPS,
                "LAUNCH_DEFAULT_MAPS"),
        LAUNCH_DEFAULT_MESSAGING(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_MESSAGING,
                "LAUNCH_DEFAULT_MESSAGING"),
        LAUNCH_DEFAULT_GALLERY(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_GALLERY,
                "LAUNCH_DEFAULT_GALLERY"),
        LAUNCH_DEFAULT_FILES(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FILES,
                "LAUNCH_DEFAULT_FILES"),
        LAUNCH_DEFAULT_WEATHER(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_WEATHER,
                "LAUNCH_DEFAULT_WEATHER"),
        LAUNCH_DEFAULT_FITNESS(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_DEFAULT_FITNESS,
                "LAUNCH_DEFAULT_FITNESS"),
        LAUNCH_APPLICATION_BY_PACKAGE_NAME(
                FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__LAUNCH_APPLICATION_BY_PACKAGE_NAME,
                "LAUNCH_APPLICATION_BY_PACKAGE_NAME");

        private final int mValue;
        private final String mName;

        private static final SparseArray<KeyboardLogEvent> VALUE_TO_ENUM_MAP = new SparseArray<>();

        static {
            for (KeyboardLogEvent type : KeyboardLogEvent.values()) {
                VALUE_TO_ENUM_MAP.put(type.mValue, type);
            }
        }

        KeyboardLogEvent(int enumValue, String enumName) {
            mValue = enumValue;
            mName = enumName;
        }

        public int getIntValue() {
            return mValue;
        }

        /**
         * Convert int value to corresponding KeyboardLogEvent enum. If can't find any matching
         * value will return {@code null}
         */
        @Nullable
        public static KeyboardLogEvent from(int value) {
            return VALUE_TO_ENUM_MAP.get(value);
        }

        /**
         * Find KeyboardLogEvent corresponding to volume up/down/mute key events.
         */
        @Nullable
        public static KeyboardLogEvent getVolumeEvent(int keycode) {
            switch (keycode) {
                case KeyEvent.KEYCODE_VOLUME_DOWN:
                    return VOLUME_DOWN;
                case KeyEvent.KEYCODE_VOLUME_UP:
                    return VOLUME_UP;
                case KeyEvent.KEYCODE_VOLUME_MUTE:
                    return VOLUME_MUTE;
                default:
                    return null;
            }
        }

        /**
         * Find KeyboardLogEvent corresponding to brightness up/down key events.
         */
        @Nullable
        public static KeyboardLogEvent getBrightnessEvent(int keycode) {
            switch (keycode) {
                case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
                    return BRIGHTNESS_DOWN;
                case KeyEvent.KEYCODE_BRIGHTNESS_UP:
                    return BRIGHTNESS_UP;
                default:
                    return null;
            }
        }

        /**
         * Find KeyboardLogEvent corresponding to intent filter category. Returns
         * {@code null if no matching event found}
         */
        @Nullable
        public static KeyboardLogEvent getLogEventFromIntent(Intent intent) {
            Intent selectorIntent = intent.getSelector();
            if (selectorIntent != null) {
                Set<String> selectorCategories = selectorIntent.getCategories();
                if (selectorCategories != null && !selectorCategories.isEmpty()) {
                    for (String intentCategory : selectorCategories) {
                        KeyboardLogEvent logEvent = getEventFromSelectorCategory(intentCategory);
                        if (logEvent == null) {
                            continue;
                        }
                        return logEvent;
                    }
                }
            }

            Set<String> intentCategories = intent.getCategories();
            if (intentCategories == null || intentCategories.isEmpty()
                    || !intentCategories.contains(Intent.CATEGORY_LAUNCHER)) {
                return null;
            }
            if (intent.getComponent() == null) {
                return null;
            }

            // TODO(b/280423320): Add new field package name associated in the
            //  KeyboardShortcutEvent atom and log it accordingly.
            return LAUNCH_APPLICATION_BY_PACKAGE_NAME;
        }

        @Nullable
        private static KeyboardLogEvent getEventFromSelectorCategory(String category) {
            switch (category) {
                case Intent.CATEGORY_APP_BROWSER:
                    return LAUNCH_DEFAULT_BROWSER;
                case Intent.CATEGORY_APP_EMAIL:
                    return LAUNCH_DEFAULT_EMAIL;
                case Intent.CATEGORY_APP_CONTACTS:
                    return LAUNCH_DEFAULT_CONTACTS;
                case Intent.CATEGORY_APP_CALENDAR:
                    return LAUNCH_DEFAULT_CALENDAR;
                case Intent.CATEGORY_APP_CALCULATOR:
                    return LAUNCH_DEFAULT_CALCULATOR;
                case Intent.CATEGORY_APP_MUSIC:
                    return LAUNCH_DEFAULT_MUSIC;
                case Intent.CATEGORY_APP_MAPS:
                    return LAUNCH_DEFAULT_MAPS;
                case Intent.CATEGORY_APP_MESSAGING:
                    return LAUNCH_DEFAULT_MESSAGING;
                case Intent.CATEGORY_APP_GALLERY:
                    return LAUNCH_DEFAULT_GALLERY;
                case Intent.CATEGORY_APP_FILES:
                    return LAUNCH_DEFAULT_FILES;
                case Intent.CATEGORY_APP_WEATHER:
                    return LAUNCH_DEFAULT_WEATHER;
                case Intent.CATEGORY_APP_FITNESS:
                    return LAUNCH_DEFAULT_FITNESS;
                default:
                    return null;
            }
        }
    }

    /**
     * Log keyboard system shortcuts for the proto
     * {@link com.android.os.input.KeyboardSystemsEventReported}
     * defined in "stats/atoms/input/input_extension_atoms.proto"
     */
    public static void logKeyboardSystemsEventReportedAtom(InputDevice inputDevice,
            int keyboardSystemEvent, int[] keyCode, int modifierState) {
    public static void logKeyboardSystemsEventReportedAtom(@Nullable InputDevice inputDevice,
            @Nullable KeyboardLogEvent keyboardSystemEvent, int modifierState, int... keyCodes) {
        // Logging Keyboard system event only for an external HW keyboard. We should not log events
        // for virtual keyboards or internal Key events.
        if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
            return;
        }
        int vendorId = inputDevice.getVendorId();
        int productId = inputDevice.getProductId();
        if (keyboardSystemEvent == null) {
            Slog.w(TAG, "Invalid keyboard event logging, keycode = " + Arrays.toString(keyCodes)
                    + ", modifier state = " + modifierState);
            return;
        }
        FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED,
                vendorId, productId, keyboardSystemEvent, keyCode, modifierState);
                vendorId, productId, keyboardSystemEvent.getIntValue(), keyCodes, modifierState);

        if (DEBUG) {
            Slog.d(TAG, "Logging Keyboard system event: " + keyboardSystemEvent.mName);
        }
    }

    /**
@@ -328,4 +621,3 @@ public final class KeyboardMetricsCollector {
                || layoutSelectionCriteria == LAYOUT_SELECTION_CRITERIA_DEFAULT;
    }
}
+28 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.policy;

import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@@ -23,6 +24,8 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -30,11 +33,14 @@ import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;

import com.android.internal.policy.IShortcutService;
import com.android.internal.util.XmlUtils;
import com.android.server.input.KeyboardMetricsCollector;
import com.android.server.input.KeyboardMetricsCollector.KeyboardLogEvent;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -88,11 +94,13 @@ class ModifierShortcutManager {
    }

    private final Context mContext;
    private final Handler mHandler;
    private boolean mSearchKeyShortcutPending = false;
    private boolean mConsumeSearchKeyUp = true;

    ModifierShortcutManager(Context context) {
    ModifierShortcutManager(Context context, Handler handler) {
        mContext = context;
        mHandler = handler;
        loadShortcuts();
    }

@@ -273,11 +281,13 @@ class ModifierShortcutManager {
     * Handle the shortcut to {@link Intent}
     *
     * @param kcm the {@link KeyCharacterMap} associated with the keyboard device.
     * @param keyCode The key code of the event.
     * @param keyEvent The key event.
     * @param metaState The meta key modifier state.
     * @return True if invoked the shortcut, otherwise false.
     */
    private boolean handleIntentShortcut(KeyCharacterMap kcm, int keyCode, int metaState) {
    @SuppressLint("MissingPermission")
    private boolean handleIntentShortcut(KeyCharacterMap kcm, KeyEvent keyEvent, int metaState) {
        final int keyCode = keyEvent.getKeyCode();
        // Shortcuts are invoked through Search+key, so intercept those here
        // Any printing key that is chorded with Search should be consumed
        // even if no shortcut was invoked.  This prevents text from being
@@ -307,6 +317,7 @@ class ModifierShortcutManager {
                            + "keyCode=" + KeyEvent.keyCodeToString(keyCode) + ","
                            + " category=" + category);
                }
                logKeyboardShortcut(keyEvent, KeyboardLogEvent.getLogEventFromIntent(intent));
                return true;
            } else {
                return false;
@@ -323,11 +334,24 @@ class ModifierShortcutManager {
                        + "the activity to which it is registered was not found: "
                        + "META+ or SEARCH" + KeyEvent.keyCodeToString(keyCode));
            }
            logKeyboardShortcut(keyEvent, KeyboardLogEvent.getLogEventFromIntent(shortcutIntent));
            return true;
        }
        return false;
    }

    private void logKeyboardShortcut(KeyEvent event, KeyboardLogEvent logEvent) {
        mHandler.post(() -> handleKeyboardLogging(event, logEvent));
    }

    private void handleKeyboardLogging(KeyEvent event, KeyboardLogEvent logEvent) {
        final InputManager inputManager = mContext.getSystemService(InputManager.class);
        final InputDevice inputDevice = inputManager != null
                ? inputManager.getInputDevice(event.getDeviceId()) : null;
        KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom(inputDevice,
                logEvent, event.getMetaState(), event.getKeyCode());
    }

    /**
     * Handle the shortcut from {@link KeyEvent}
     *
@@ -360,7 +384,7 @@ class ModifierShortcutManager {
        }

        final KeyCharacterMap kcm = event.getKeyCharacterMap();
        if (handleIntentShortcut(kcm, keyCode, metaState)) {
        if (handleIntentShortcut(kcm, event, metaState)) {
            return true;
        }

+83 −19

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ android_test {
        "services.core",
        "androidx.test.runner",
        "androidx.test.rules",
        "junit-params",
        "mockito-target-extended-minus-junit4",
        "platform-test-annotations",
        "servicestests-utils",
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ class ShortcutKeyTestBase {
    final Context mContext = spy(getInstrumentation().getTargetContext());

    /** Modifier key to meta state */
    private static final Map<Integer, Integer> MODIFIER;
    protected static final Map<Integer, Integer> MODIFIER;
    static {
        final Map<Integer, Integer> map = new ArrayMap<>();
        map.put(KEYCODE_CTRL_LEFT, META_CTRL_LEFT_ON | META_CTRL_ON);
Loading