Loading services/core/java/com/android/server/input/KeyboardMetricsCollector.java 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source 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.server.input; import android.view.InputDevice; import com.android.internal.util.FrameworkStatsLog; /** * Collect Keyboard metrics */ public final class KeyboardMetricsCollector { private static final String TAG = "KeyboardMetricCollector"; /** * 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) { int vendor_id = inputDevice.getVendorId(); int product_id = inputDevice.getProductId(); FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED, vendor_id, product_id, keyboardSystemEvent, keyCode, modifierState); } } services/core/java/com/android/server/policy/PhoneWindowManager.java +35 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ import android.hardware.hdmi.HdmiAudioSystemClient; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; import android.hardware.input.InputManager; import android.media.AudioManager; import android.media.AudioManagerInternal; import android.media.AudioSystem; Loading Loading @@ -205,6 +206,7 @@ import com.android.internal.policy.PhoneWindow; import com.android.internal.policy.TransitionAnimation; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.widget.LockPatternUtils; import com.android.server.AccessibilityManagerInternal; import com.android.server.ExtconStateObserver; Loading @@ -215,6 +217,7 @@ import com.android.server.SystemServiceManager; import com.android.server.UiThread; import com.android.server.display.BrightnessUtils; import com.android.server.input.InputManagerInternal; import com.android.server.input.KeyboardMetricsCollector; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.pm.UserManagerInternal; import com.android.server.policy.KeyCombinationManager.TwoKeysCombinationRule; Loading Loading @@ -678,6 +681,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final int MSG_LAUNCH_ASSIST = 23; private static final int MSG_RINGER_TOGGLE_CHORD = 24; private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 25; private static final int MSG_LOG_KEYBOARD_SYSTEM_EVENT = 26; private class PolicyHandler extends Handler { @Override Loading Loading @@ -751,6 +755,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { case MSG_SWITCH_KEYBOARD_LAYOUT: handleSwitchKeyboardLayout(msg.arg1, msg.arg2); break; case MSG_LOG_KEYBOARD_SYSTEM_EVENT: handleKeyboardSystemEvent(msg.arg2, (KeyEvent) msg.obj); break; } } } Loading Loading @@ -2288,6 +2295,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { cancelPendingScreenshotChordAction(); } }); if (mHasFeatureWatch) { mKeyCombinationManager.addRule( new TwoKeysCombinationRule(KEYCODE_POWER, KEYCODE_STEM_PRIMARY) { Loading Loading @@ -2907,7 +2915,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, }; /** * Log the keyboard shortcuts without blocking the current thread. * * We won't log keyboard events when the input device is null * or when it is virtual. */ private void handleKeyboardSystemEvent(int keyboardSystemEvent, KeyEvent event) { final InputManager inputManager = mContext.getSystemService(InputManager.class); final InputDevice inputDevice = inputManager != null ? inputManager.getInputDevice(event.getDeviceId()) : null; if (inputDevice != null && !inputDevice.isVirtual()) { KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom( inputDevice, keyboardSystemEvent, new int[]{event.getKeyCode()}, event.getMetaState()); } } private void logKeyboardSystemsEvent(KeyEvent event, int keyboardSystemEvent) { mHandler.obtainMessage(MSG_LOG_KEYBOARD_SYSTEM_EVENT, 0, keyboardSystemEvent, event) .sendToTarget(); } // TODO(b/117479243): handle it in InputPolicy // TODO (b/283241997): Add the remaining keyboard shortcut logging after refactoring /** {@inheritDoc} */ @Override public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, Loading Loading @@ -2961,6 +2992,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { switch(keyCode) { case KeyEvent.KEYCODE_HOME: logKeyboardSystemsEvent(event, FrameworkStatsLog .KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME); return handleHomeShortcuts(displayId, focusedToken, event); case KeyEvent.KEYCODE_MENU: // Hijack modified menu keys for debugging features Loading @@ -2978,6 +3011,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_RECENT_APPS: if (down && repeatCount == 0) { showRecentApps(false /* triggeredFromAltTab */); logKeyboardSystemsEvent(event, FrameworkStatsLog .KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS); } return key_consumed; case KeyEvent.KEYCODE_APP_SWITCH: Loading Loading
services/core/java/com/android/server/input/KeyboardMetricsCollector.java 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source 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.server.input; import android.view.InputDevice; import com.android.internal.util.FrameworkStatsLog; /** * Collect Keyboard metrics */ public final class KeyboardMetricsCollector { private static final String TAG = "KeyboardMetricCollector"; /** * 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) { int vendor_id = inputDevice.getVendorId(); int product_id = inputDevice.getProductId(); FrameworkStatsLog.write(FrameworkStatsLog.KEYBOARD_SYSTEMS_EVENT_REPORTED, vendor_id, product_id, keyboardSystemEvent, keyCode, modifierState); } }
services/core/java/com/android/server/policy/PhoneWindowManager.java +35 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,7 @@ import android.hardware.hdmi.HdmiAudioSystemClient; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; import android.hardware.input.InputManager; import android.media.AudioManager; import android.media.AudioManagerInternal; import android.media.AudioSystem; Loading Loading @@ -205,6 +206,7 @@ import com.android.internal.policy.PhoneWindow; import com.android.internal.policy.TransitionAnimation; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.widget.LockPatternUtils; import com.android.server.AccessibilityManagerInternal; import com.android.server.ExtconStateObserver; Loading @@ -215,6 +217,7 @@ import com.android.server.SystemServiceManager; import com.android.server.UiThread; import com.android.server.display.BrightnessUtils; import com.android.server.input.InputManagerInternal; import com.android.server.input.KeyboardMetricsCollector; import com.android.server.inputmethod.InputMethodManagerInternal; import com.android.server.pm.UserManagerInternal; import com.android.server.policy.KeyCombinationManager.TwoKeysCombinationRule; Loading Loading @@ -678,6 +681,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final int MSG_LAUNCH_ASSIST = 23; private static final int MSG_RINGER_TOGGLE_CHORD = 24; private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 25; private static final int MSG_LOG_KEYBOARD_SYSTEM_EVENT = 26; private class PolicyHandler extends Handler { @Override Loading Loading @@ -751,6 +755,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { case MSG_SWITCH_KEYBOARD_LAYOUT: handleSwitchKeyboardLayout(msg.arg1, msg.arg2); break; case MSG_LOG_KEYBOARD_SYSTEM_EVENT: handleKeyboardSystemEvent(msg.arg2, (KeyEvent) msg.obj); break; } } } Loading Loading @@ -2288,6 +2295,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { cancelPendingScreenshotChordAction(); } }); if (mHasFeatureWatch) { mKeyCombinationManager.addRule( new TwoKeysCombinationRule(KEYCODE_POWER, KEYCODE_STEM_PRIMARY) { Loading Loading @@ -2907,7 +2915,30 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, }; /** * Log the keyboard shortcuts without blocking the current thread. * * We won't log keyboard events when the input device is null * or when it is virtual. */ private void handleKeyboardSystemEvent(int keyboardSystemEvent, KeyEvent event) { final InputManager inputManager = mContext.getSystemService(InputManager.class); final InputDevice inputDevice = inputManager != null ? inputManager.getInputDevice(event.getDeviceId()) : null; if (inputDevice != null && !inputDevice.isVirtual()) { KeyboardMetricsCollector.logKeyboardSystemsEventReportedAtom( inputDevice, keyboardSystemEvent, new int[]{event.getKeyCode()}, event.getMetaState()); } } private void logKeyboardSystemsEvent(KeyEvent event, int keyboardSystemEvent) { mHandler.obtainMessage(MSG_LOG_KEYBOARD_SYSTEM_EVENT, 0, keyboardSystemEvent, event) .sendToTarget(); } // TODO(b/117479243): handle it in InputPolicy // TODO (b/283241997): Add the remaining keyboard shortcut logging after refactoring /** {@inheritDoc} */ @Override public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, Loading Loading @@ -2961,6 +2992,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { switch(keyCode) { case KeyEvent.KEYCODE_HOME: logKeyboardSystemsEvent(event, FrameworkStatsLog .KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__HOME); return handleHomeShortcuts(displayId, focusedToken, event); case KeyEvent.KEYCODE_MENU: // Hijack modified menu keys for debugging features Loading @@ -2978,6 +3011,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_RECENT_APPS: if (down && repeatCount == 0) { showRecentApps(false /* triggeredFromAltTab */); logKeyboardSystemsEvent(event, FrameworkStatsLog .KEYBOARD_SYSTEMS_EVENT_REPORTED__KEYBOARD_SYSTEM_EVENT__RECENT_APPS); } return key_consumed; case KeyEvent.KEYCODE_APP_SWITCH: Loading