一. 屏幕的唤醒
首先inputread在读取到有keyboard事件上报后,会调用到keydispatch的notifykey,去询问wm是否会对这次按键特殊处理,如果WM不处理,则此处会点亮或者熄灭屏幕。
inputReader.cpp KeyboardInputMapper::processKey
getDispatcher()->notifyKey
inputDispacher.cpp InputDispatcher::notifyKey
mPolicy->interceptKeyBeforeQueueing
com_android_server_inputManager.cpp NativeInputManager::interceptKeyBeforeQueueing
env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
when, action, flags, keyCode, scanCode, policyFlags, isScreenOn); //此处gCallbacksClassInfo中的各种方法就是InputManager的对应的方法,在JNI初始化的时候就注册了,详情请参看register_android_server_InputManager函数,通过jniRegisterNativeMethods将inputmanager的各种callback注册到gCallbacksClassInfo中。
返回的wmaction就是后面WM对此次按键事件的policy,通过此返回值,此处会决定下一步的动作。
InputManager.java interceptKeyBeforeQueueing
mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing
WindowmanagerService.java InputMonitor::interceptKeyBeforeQueueing
mPolicy.interceptKeyBeforeQueueing
PhonewindowManager.java interceptKeyBeforeQueueing
//摘录部分代码:
public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
int keyCode, int scanCode, int policyFlags, boolean isScreenOn) {
final boolean down = action == KeyEvent.ACTION_DOWN;
final boolean canceled = (flags & KeyEvent.FLAG_CANCELED) != 0;
final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
// If screen is off then we treat the case where the keyguard is open but hidden
// the same as if it were open and in front.
// This will prevent any keys other than the power button from waking the screen
// when the keyguard is hidden by another activity.
final boolean keyguardActive = (isScreenOn ?
mKeyguardMediator.isShowingAndNotHidden() :
mKeyguardMediator.isShowing());
int result; //result即为返回到wmaction
if (isScreenOn || isInjected) {
// When the screen is on or if the key is injected pass the key to the application.
result = ACTION_PASS_TO_USER;
} else {//我们现在走的应该是这个
// When the screen is off and the key is not injected, determine whether
// to wake the device but don't pass the key to the application.
result = 0;
final boolean isWakeKey = (policyFlags
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
if (down && isWakeKey) {
if (keyguardActive) {
//也就是说,如果当前屏幕是灭的,且按的键是可以唤醒屏幕的,那么WM会首先将此次按键传递给keyguard,由keyguard来唤醒屏幕,并作出相应的动作,否则就自己点亮屏幕,通过返回的policy来通知下层。
// If the keyguard is showing, let it decide what to do with the wake key.
mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
} else {
// Otherwise, wake the device ourselves.
result |= ACTION_POKE_USER_ACTIVITY;
}
}
}
....................
}
keyguarViewMediator.java onWakeKeyWhenKeyguardShowingTq
wakeWhenReadyLocked