事件处理主要都是在 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;
}
// 省略部分代码......
}
网友评论