欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 创投人物 > Android 14 Power键亮灭屏流程

Android 14 Power键亮灭屏流程

2024/10/24 16:24:37 来源:https://blog.csdn.net/weixin_41028555/article/details/140637402  浏览:    关键词:Android 14 Power键亮灭屏流程

Android14中Power键的事件分发和Android10的是不一样的,这里并没有经过interceptKeyBeforeDispatching方法,而是直接走到了interceptKeyBeforeQueueing方法

PhoneWindowManager中的堆栈如下

07-06 08:59:04.481  1844  1984 D WindowManager: interceptKeyTq keycode=26 down=true
07-06 08:59:04.481  1844  1984 W System.err: java.lang.Exception
07-06 08:59:04.481  1844  1984 W System.err: 	at com.android.server.policy.PhoneWindowManager.interceptKeyBeforeQueueing(PhoneWindowManager.java:4127)
07-06 08:59:04.481  1844  1984 W System.err: 	at com.android.server.wm.InputManagerCallback.interceptKeyBeforeQueueing(InputManagerCallback.java:149)
07-06 08:59:04.481  1844  1984 W System.err: 	at com.android.server.input.InputManagerService.interceptKeyBeforeQueueing(InputManagerService.java:2476)

当用户点击物理按键Power键时,input模块会分发此事件,jni层的input相关的堆栈如下

07-06 08:59:04.481  1844  1984 D NativeInputManager:   #00 pc 000000000007e62c  /system/lib64/libandroid_servers.so (android::NativeInputManager::interceptKeyBeforeQueueing(android::KeyEvent const&, unsigned int&)+108) (BuildId: a244f886fcc4e4d7951cb0b0dd8e0a93)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #01 pc 00000000000ac5d0  /system/lib64/libinputflinger.so (android::inputdispatcher::InputDispatcher::notifyKey(android::NotifyKeyArgs const&)+372) (BuildId: a55568bcb9c61a30bcd4f9eba5623696)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #02 pc 0000000000007cd4  /system/lib64/libinputflinger_base.so (android::QueuedInputListener::flush()+132) (BuildId: a9c65a12bbe41d35ccac4bea02eabbf0)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #03 pc 0000000000007cd4  /system/lib64/libinputflinger_base.so (android::QueuedInputListener::flush()+132) (BuildId: a9c65a12bbe41d35ccac4bea02eabbf0)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #04 pc 0000000000007cd4  /system/lib64/libinputflinger_base.so (android::QueuedInputListener::flush()+132) (BuildId: a9c65a12bbe41d35ccac4bea02eabbf0)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #05 pc 00000000000a0d54  /system/lib64/libinputreader.so (android::InputReader::loopOnce()+1424) (BuildId: 7171b6e142e1b4551a0406d673f063e5)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #06 pc 000000000000ad14  /system/lib64/libinputflinger_base.so (android::(anonymous namespace)::InputThreadImpl::threadLoop()+28) (BuildId: a9c65a12bbe41d35ccac4bea02eabbf0)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #07 pc 00000000000142d0  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+288) (BuildId: 6df8048e2f2c69be0a5d8ee3149d683d)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #08 pc 00000000000ebc40  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+144) (BuildId: af0fa43783211a0f2494f720559e5d5c)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #09 pc 00000000000c3644  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 50118287324a156bc7be11d3d940c7be)
07-06 08:59:04.481  1844  1984 D NativeInputManager:   #10 pc 000000000005cfa4  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68) (BuildId: 50118287324a156bc7be11d3d940c7be)

整个流程图如下:

ecb88a9527a4460d97c2331988816f8d.png
InputManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

    // Native callback.@SuppressWarnings("unused")private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {synchronized (mFocusEventDebugViewLock) {if (mFocusEventDebugView != null) {mFocusEventDebugView.reportEvent(event);}}return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags);}
private WindowManagerCallbacks mWindowManagerCallbacks;

mWindowManagerCallbacks定义如上,我们可以看到WindowManagerCallbacks只是一个接口,没有具体的实现

​
public interface WindowManagerCallbacks extends LidSwitchCallback {/*** This callback is invoked when an event first arrives to InputDispatcher and before it is* placed onto InputDispatcher's queue. If this event is intercepted, it will never be* processed by InputDispacher.* @param event The key event that's arriving to InputDispatcher* @param policyFlags The policy flags* @return the flags that tell InputDispatcher how to handle the event (for example, whether* to pass it to the user)*/int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
}​

查找代码会发现InputManagerCallback实现了WindowManagerCallbacks,然后就到了InputManagerCallback这里

InputManagerCallback.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java

 final class InputManagerCallback implements InputManagerService.WindowManagerCallbacks {
.../*** Provides an opportunity for the window manager policy to intercept early key* processing as soon as the key has been read from the device.*/@Overridepublic int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);}

然后就走到了PhoneWindowManager中

PhoneWindowManager.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    @Overridepublic int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
//获取键值final int keyCode = event.getKeyCode();
//获取当前是否是按键downfinal boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
//是否是wake keyboolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0|| event.isWakeKey();
...final boolean interactive = (policyFlags & FLAG_INTERACTIVE) != 0;
//此按键是否取消final boolean canceled = event.isCanceled();
//获取屏幕的IDfinal int displayId = event.getDisplayId();final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
...// Handle special keys.switch (keyCode) {
...
//走进Power按键的处理逻辑case KeyEvent.KEYCODE_POWER: {EventLogTags.writeInterceptPower(KeyEvent.actionToString(event.getAction()),mPowerKeyHandled ? 1 : 0,mSingleKeyGestureDetector.getKeyPressCounter(KeyEvent.KEYCODE_POWER));// Any activity on the power button stops the accessibility shortcut
//这个意思是此事件只有系统层可以接收,不下发给appresult &= ~ACTION_PASS_TO_USER;isWakeKey = false; // wake-up will be handled separatelyif (down) {interceptPowerKeyDown(event, interactiveAndOn);} else {interceptPowerKeyUp(event, canceled);}break;}
...
//使用震动反馈if (useHapticFeedback) {performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,"Virtual Key - Press");}if (isWakeKey) {wakeUpFromWakeKey(event);}
...
}

然后就走到了power down这里的逻辑

PhoneWindowManager.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {// Hold a wake lock until the power key is released.
//申请wake lock锁,申请这个锁才能亮屏哦!!!if (!mPowerKeyWakeLock.isHeld()) {mPowerKeyWakeLock.acquire();}
//会走到WMS的onPowerKeyDown方法
//mRoot.forAllDisplayPolicies(p -> p.onPowerKeyDown(isScreenOn));mWindowManagerFuncs.onPowerKeyDown(interactive);// Stop ringing or end call if configured to do so when power is pressed.TelecomManager telecomManager = getTelecommService();boolean hungUp = false;if (telecomManager != null) {if (telecomManager.isRinging()) {// Pressing Power while there's a ringing incoming// call should silence the ringer.
//如果当前电话正在响铃, 按下power键就会静音telecomManager.silenceRinger();} else if ((mIncallPowerBehavior& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0&& telecomManager.isInCall() && interactive) {// Otherwise, if "Power button ends call" is enabled,// the Power button will hang up any current active call.
//如果正在打电话,按下就是挂断hungUp = telecomManager.endCall();}}
//return true if the proximity sensor was successfully ignored and we should consume the key event.---Powerfinal boolean handledByPowerManager = mPowerManagerInternal.interceptPowerKeyDown(event);// Inform the StatusBar; but do not allow it to consume the event.sendSystemKeyToStatusBarAsync(event);// If the power key has still not yet been handled, then detect short// press, long press, or multi press and decide what to do.mPowerKeyHandled = mPowerKeyHandled || hungUp|| handledByPowerManager || mKeyCombinationManager.isPowerKeyIntercepted();if (!mPowerKeyHandled) {if (!interactive) {wakeUpFromPowerKey(event.getDownTime());}} else {// handled by another power key policy.if (mSingleKeyGestureDetector.isKeyIntercepted(KEYCODE_POWER)) {Slog.d(TAG, "Skip power key gesture for other policy has handled it.");mSingleKeyGestureDetector.reset();}}}

如果mPowerKeyHandled为false,也就是没有消费掉这个power事件,则,走进wakeUpFromWakeKey逻辑。

PhoneWindowManager.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    private void wakeUpFromWakeKey(KeyEvent event) {
//亮屏, 原因是WAKE_REASON_WAKE_KEY, details是"android.policy:KEY"if (wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,PowerManager.WAKE_REASON_WAKE_KEY, "android.policy:KEY")) {// Start HOME with "reason" extra if sleeping for more than mWakeUpToLastStateTimeoutif (shouldWakeUpWithHomeIntent() && event.getKeyCode() == KEYCODE_HOME) {startDockOrHome(DEFAULT_DISPLAY, /*fromHomeKey*/ true, /*wakenFromDreams*/ true,PowerManager.wakeReasonToString(PowerManager.WAKE_REASON_WAKE_KEY));}}}

PhoneWindowManager.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

    private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,String details) {final boolean theaterModeEnabled = isTheaterModeEnabled();if (!wakeInTheaterMode && theaterModeEnabled) {return false;}if (theaterModeEnabled) {Settings.Global.putInt(mContext.getContentResolver(),Settings.Global.THEATER_MODE_ON, 0);}mPowerManager.wakeUp(wakeTime, reason, details);return true;}

后续流程图如下:

e1461ef4ec24461ea73c91c813b926c3.png

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com