事件处理主要都是在 PhoneWindowManager.java 中,电源键处理在 PhoneWindowManager#interceptKeyBeforeQueueing() 中:
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { // 省略部分代码...... if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { Log.d(TAG,"handleKeyGesture +000"); handleKeyGesture(event, interactiveAndOn); } // 省略部分代码...... } private void handleKeyGesture(KeyEvent event, boolean interactive) { // 省略部分代码...... if (event.getKeyCode() == KEYCODE_POWER && event.getAction() == KeyEvent.ACTION_DOWN) { mPowerKeyHandled = handleCameraGesture(event, interactive); if (mPowerKeyHandled) { // handled by camera gesture. mSingleKeyGestureDetector.reset(); return; } } mSingleKeyGestureDetector.interceptKey(event, interactive); } // The camera gesture will be detected by GestureLauncherService. private boolean handleCameraGesture(KeyEvent event, boolean interactive) { // camera gesture. // 省略部分代码...... final boolean intercept = mGestureLauncherService.interceptPowerKeyDown(event, interactive, outLaunched); // 省略部分代码...... }
接着看GestureLauncherService.java
public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive, MutableBoolean outLaunched) { // 省略部分代码...... if (launchCamera) { Slog.i(TAG, "Power button double tap gesture detected, launching camera. Interval=" + powerTapInterval + "ms"); launchCamera = handleCameraGesture(false /* useWakelock */, StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP); if (launchCamera) { mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) powerTapInterval); mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); } } else if (launchEmergencyGesture) { Slog.i(TAG, "Emergency gesture detected, launching."); launchEmergencyGesture = handleEmergencyGesture(); mUiEventLogger.log(GestureLauncherEvent.GESTURE_EMERGENCY_TAP_POWER); } // 省略部分代码...... } @VisibleForTesting boolean handleCameraGesture(boolean useWakelock, int source) { // 省略部分代码...... if (useWakelock) { // Make sure we don't sleep too early mWakeLock.acquire(500L); } StatusBarManagerInternal service = LocalServices.getService( StatusBarManagerInternal.class); service.onCameraLaunchGestureDetected(source); return true; // 省略部分代码...... }
StatusBarManagerInternal.java 是一个 interface 接口,实现在 StatusBarManagerService.java 。
StatusBarManagerService#onCameraLaunchGestureDetected()
@Override public void onCameraLaunchGestureDetected(int source) { if (mBar != null) { try { mBar.onCameraLaunchGestureDetected(source); } catch (RemoteException e) { } } }
mBar 是 IStatusBar 对象,被 CommandQueue.java 继承;CentralSurfacesCommandQueueCallbacks 又继承了实现了 CommandQueue.Callbacks,最终下一步会调用到 CentralSurfacesCommandQueueCallbacks#onCameraLaunchGestureDetected()
public void onCameraLaunchGestureDetected(int source) { mCentralSurfaces.setLastCameraLaunchSource(source); if (mCentralSurfaces.isGoingToSleep()) { if (CentralSurfaces.DEBUG_CAMERA_LIFT) { Slog.d(CentralSurfaces.TAG, "Finish going to sleep before launching camera"); } mCentralSurfaces.setLaunchCameraOnFinishedGoingToSleep(true); return; } if (!mNotificationPanelViewController.canCameraGestureBeLaunched()) { if (CentralSurfaces.DEBUG_CAMERA_LIFT) { Slog.d(CentralSurfaces.TAG, "Can't launch camera right now"); } return; } if (!mCentralSurfaces.isDeviceInteractive()) { mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH, "com.android.systemui:CAMERA_GESTURE"); } vibrateForCameraGesture(); if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) { Log.v(CentralSurfaces.TAG, "Camera launch"); // 屏蔽人脸或者指纹解锁 mKeyguardUpdateMonitor.onCameraLaunched(); } if (!mStatusBarKeyguardViewManager.isShowing()) { final Intent cameraIntent = CameraIntents.getInsecureCameraIntent(mContext); mCentralSurfaces.startActivityDismissingKeyguard(cameraIntent, false /* onlyProvisioned */, true /* dismissShade */, true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0, null /* animationController */, UserHandle.CURRENT); } else { if (!mCentralSurfaces.isDeviceInteractive()) { // 当我们立即启动相机并且弹跳器启动时,避免稀松布闪烁 mCentralSurfaces.acquireGestureWakeLock( CentralSurfaces.LAUNCH_TRANSITION_TIMEOUT_MS + 1000L); } if (isWakingUpOrAwake()) { if (CentralSurfaces.DEBUG_CAMERA_LIFT) { Slog.d(CentralSurfaces.TAG, "Launching camera"); } if (mStatusBarKeyguardViewManager.isBouncerShowing()) { mStatusBarKeyguardViewManager.reset(true /* hide */); } // 启动相机 mNotificationPanelViewController.launchCamera(mCentralSurfaces.isDeviceInteractive() /* animate */, source); mCentralSurfaces.updateScrimController(); } else { if (CentralSurfaces.DEBUG_CAMERA_LIFT) { Slog.d(CentralSurfaces.TAG, "Deferring until screen turns on"); } mCentralSurfaces.setLaunchCameraOnFinishedWaking(true); } } }
再看 NotificationPanelViewController#launchCamera():
public void launchCamera(boolean animate, int source) { if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) { mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP; } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE) { mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_WIGGLE; } else if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER) { mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER; } else { // Default. mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE; } if (!isFullyCollapsed()) { setLaunchingAffordance(true); } else { animate = false; } mAffordanceHasPreview = mKeyguardBottomArea.getRightPreview() != null; // 启动相机 mAffordanceHelper.launchAffordance( animate, mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); }
接着看 KeyguardAffordanceHelper#launchAffordance():
public void launchAffordance(boolean animate, boolean left) { if (mSwipingInProgress) { // We don't want to mess with the state if the user is actually swiping already. return; } KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon; KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon; startSwiping(targetView); // Do not animate the circle expanding if the affordance isn't visible, // otherwise the circle will be meaningless. if (targetView.getVisibility() != View.VISIBLE) { animate = false; } if (animate) { fling(0, false, !left); // 这里面会回调 KeyguardAffordanceHelperCallback#onAnimationToSideStarted() 方法,去启动相机,并且里面有个动画。 updateIcon(otherView, 0.0f, 0, true, false, true, false); } else { mCallback.onAnimationToSideStarted(!left, mTranslation, 0); mTranslation = left ? mCallback.getMaxTranslationDistance() : mCallback.getMaxTranslationDistance(); updateIcon(otherView, 0.0f, 0.0f, false, false, true, false); targetView.instantFinishAnimation(); mFlingEndListener.onAnimationEnd(null); mAnimationEndRunnable.run(); } }
当动画执行完成,则会执行 mAnimationEndRunnable.run(),进而回调到:KeyguardAffordanceHelperCallback#onAnimationToSideEnded(): 方法里
public void onAnimationToSideEnded() { mIsLaunchTransitionRunning = false; mIsLaunchTransitionFinished = true; if (mLaunchAnimationEndRunnable != null) { // 这里会去销毁密码锁界面、图案锁界面; mLaunchAnimationEndRunnable.run(); mLaunchAnimationEndRunnable = null; } mCentralSurfaces.readyForKeyguardDone(); }
这里补充个流程: 在未解锁的情况下,打开临时占用的app,比如 相机,紧急拨号等会调用如下函数:
public void setOccluded(boolean occluded, boolean animate) { final boolean isOccluding = !mOccluded && occluded; final boolean isUnOccluding = mOccluded && !occluded; setOccludedAndUpdateStates(occluded); if (mShowing && isOccluding) { SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED, SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__OCCLUDED); if (mCentralSurfaces.isInLaunchTransition()) { final Runnable endRunnable = new Runnable() { @Override public void run() { ///M: [ALPS01807921] /// mOccluded may be changed before the runnable is executed. if (mOccluded) { mNotificationShadeWindowController.setKeyguardOccluded(mOccluded); reset(true /* hideBouncerWhenShowing */); } else { Log.d(TAG, "setOccluded.run() - mOccluded was set to false") ; } } }; mCentralSurfaces.fadeKeyguardAfterLaunchTransition( null /* beforeFading */, endRunnable, endRunnable); return; } // 省略部分代码...... }