按键事件分发
关机流程: ViewRootImpl -> PhoneWindowManager -> GlobalAction -> StatusBarManagerService -> commandQueue -> GlobalActionImpl
dispatchUnhandledKey -> interceptFallback -> interceptKeyBeforeQueueing
按键的时间源头: InputDispatcher.cpp 参考文章
底层从eventhub事件传递看一下文章。
Android输入系统(三)——InputReader的加工类型和InputDispatcher的分发过程(基于Android 13)_一切皆是定数的博客-CSDN博客
1. InputDispatcherFactory.cpp
-
com_android_server_input_InputManagerService.cpp NativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper) : mLooper(looper), mInteractive(true) { JNIEnv* env = jniEnv(); mServiceObj = env->NewGlobalRef(serviceObj); { AutoMutex _l(mLock); mLocked.systemUiLightsOut = false; mLocked.pointerSpeed = 0; mLocked.pointerGesturesEnabled = true; mLocked.showTouches = false; mLocked.pointerCapture = false; mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT; } mInteractive = true; InputManager* im = new InputManager(this, this); mInputManager = im; defaultServiceManager()->addService(String16("inputflinger"), im); }
InputManager::InputManager( const sp<InputReaderPolicyInterface>& readerPolicy, const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { mDispatcher = createInputDispatcher(dispatcherPolicy); mClassifier = new InputClassifier(mDispatcher); mReader = createInputReader(readerPolicy, mClassifier); }
namespace android { sp<InputDispatcherInterface> createInputDispatcher( const sp<InputDispatcherPolicyInterface>& policy) { return new android::inputdispatcher::InputDispatcher(policy); } }
2. InputDispatcher.cpp
-
InputDispatcher.cpp InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) : mPolicy(policy),
3. InputManagerService.java
-
InputManagerService // Native callback. private long interceptKeyBeforeDispatching(IBinder focus, KeyEvent event, int policyFlags) { return mWindowManagerCallbacks.interceptKeyBeforeDispatching(focus, event, policyFlags); }
/** * Provides an opportunity for the window manager policy to process a key before * ordinary dispatch. */ @Override public long interceptKeyBeforeDispatching( IBinder focusedToken, KeyEvent event, int policyFlags) { return mService.mPolicy.interceptKeyBeforeDispatching(focusedToken, event, policyFlags); }
WindowManagerService.java private WindowManagerService(Context context, InputManagerService inputManager, boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy, ActivityTaskManagerService atm, DisplayWindowSettingsProvider displayWindowSettingsProvider, Supplier<SurfaceControl.Transaction> transactionFactory, Supplier<Surface> surfaceFactory, Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
SystemServer.java wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore, new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
4. PhoneWindowManager
-
// TODO(b/117479243): handle it in InputPolicy /** {@inheritDoc} */ @Override public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event, int policyFlags) { ``` case KeyEvent.KEYCODE_POWER: { EventLogTags.writeInterceptPower( KeyEvent.actionToString(event.getAction()), mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter); // Any activity on the power button stops the accessibility shortcut cancelPendingAccessibilityShortcutAction(); result &= ~ACTION_PASS_TO_USER; isWakeKey = false; // wake-up will be handled separately if (down) { interceptPowerKeyDown(event, interactive); } else { interceptPowerKeyUp(event, interactive, canceled); } break; } ``` }
private void powerLongPress() { final int behavior = getResolvedLongPressOnPowerBehavior(); switch (behavior) { case LONG_PRESS_POWER_NOTHING: break; case LONG_PRESS_POWER_GLOBAL_ACTIONS: mPowerKeyHandled = true; performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false, "Power - Long Press - Global Actions"); showGlobalActionsInternal(); break;
void showGlobalActionsInternal() { if (mGlobalActions == null) { mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs); } final boolean keyguardShowing = isKeyguardShowingAndNotOccluded(); mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); // since it took two seconds of long press to bring this up, // poke the wake lock so they have some time to see the dialog. mPowerManager.userActivity(SystemClock.uptimeMillis(), false); }
5.GlobalActions
-
public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) { if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned); if (mGlobalActionsProvider != null && mGlobalActionsProvider.isGlobalActionsDisabled()) { return; } mKeyguardShowing = keyguardShowing; mDeviceProvisioned = deviceProvisioned; mShowing = true; if (mGlobalActionsAvailable) { mHandler.postDelayed(mShowTimeout, 5000); mGlobalActionsProvider.showGlobalActions(); // mGlobalActionsProvider 就是 statusbarmanagerservice } else { // SysUI isn't alive, show legacy menu. ensureLegacyCreated(); mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned); } }
6.StatusBarManagerService
StatusBarManagerService.java
@Override
public void showGlobalActions() {
if (mBar != null) {
try {
// IStatusBar mBar
mBar.showGlobalActionsMenu();
} catch (RemoteException ex) {}
}
}
@Override
public RegisterStatusBarResult registerStatusBar(IStatusBar bar) {
enforceStatusBarService();
Slog.i(TAG, "registerStatusBar bar=" + bar);
mBar = bar;
7. statusbar (systemui)
RegisterStatusBarResult result = null;
try {
// protected IStatusBarService mBarService;
// mBarService = IStatusBarService.Stub.asInterface(
// ServiceManager.getService(Context.STATUS_BAR_SERVICE));
result = mBarService.registerStatusBar(mCommandQueue);
} catch (RemoteException ex) {
ex.rethrowFromSystemServer();
}
8.commonqueue (systemui )
public class CommandQueue extends IStatusBar.Stub {
@Override
public void showGlobalActionsMenu() {
synchronized (mLock) {
mHandler.removeMessages(MSG_SHOW_GLOBAL_ACTIONS);
mHandler.obtainMessage(MSG_SHOW_GLOBAL_ACTIONS).sendToTarget();
}
}
}
case MSG_SHOW_GLOBAL_ACTIONS:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).handleShowGlobalActionsMenu();
}
break
9.GlobalActionsComponent.java
@Override
public void handleShowGlobalActionsMenu() {
mStatusBarKeyguardViewManager.setGlobalActionsVisible(true);
mExtension.get().showGlobalActions(this);
}
10. GlobalActionImpl
@Override
public void showGlobalActions(GlobalActionsManager manager) {
if (mDisabled) return;
mGlobalActionsDialog = mGlobalActionsDialogLazy.get();
mGlobalActionsDialog.showOrHideDialog(mKeyguardStateController.isShowing(),
mDeviceProvisionedController.isDeviceProvisioned());
}
11. GlobalActionDialogLite
就是 dialog 此后就不再分析
StatusBarManagerService 和 SystemUI 的 CommandQueue 进程间通信。