1 2 3 4 5 6 7 | 受不了xxxx恶心人的行为,遂搬迁至博客园。 始发: 2016 - 12 - 16 13 : 08 : 47 版本信息: Linux: 3.10 Android: 4.4 |
Android休眠在framework的处理涉及两个系统服务,InputManagerService和PowerManagerService。InputManagerService负责处理PowerKey产生的Input事件,根据事件类型调用PowerManagerService的休眠、唤醒接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags) { if (wmActions & WM_ACTION_GO_TO_SLEEP) { ALOGD( "handleInterceptActions: Going to sleep." ); android_server_PowerManagerService_goToSleep(when); } if (wmActions & WM_ACTION_WAKE_UP) { ALOGD( "handleInterceptActions: Waking up." ); android_server_PowerManagerService_wakeUp(when); } if (wmActions & WM_ACTION_PASS_TO_USER) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } } |
PowerManagerService执行具体的休眠、唤醒动作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | private void goToSleepInternal( long eventTime, int reason) { Slog.i(TAG, "goToSleepInternal, reason: " + reason); synchronized (mLock) { if (goToSleepNoUpdateLocked(eventTime, reason)) { updatePowerStateLocked(); } } } } private void updatePowerStateLocked() { // Phase 0: Basic state updates. // Phase 1: Update wakefulness. // Loop because the wake lock and user activity computations are influenced // by changes in wakefulness. // Phase 2: Update dreams and display power state. // Phase 3: Send notifications, if needed. // Phase 4: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } |
它们之间关系如下图:
由于这两个服务涉及framework最核心的功能且其代码实现繁复,这里只贴出其处理流程,具体细节其他篇幅再续。本篇目的:始知此事要躬行,如果有意弄清流程,提供一个参照。
1、InputManagerService服务加载:
1 2 3 4 | SystemServer.java (frameworks\base\services\java\com\android\server) InputManagerService inputManager = null ; inputManager = new InputManagerService(context, wmHandler); inputManager.start(); |
2、InputManagerService Java:
1 2 3 4 5 6 | InputManagerService.java (frameworks\base\services\java\com\android\server\input) public class InputManagerService { public InputManagerService(Context context, Handler handler) { mPtr = nativeInit( this , mContext, mHandler.getLooper().getQueue()); } } |
3、InputManagerService的JNI:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | com_android_server_input_InputManagerService.cpp (frameworks\base\services\jni) static jint nativeInit(JNIEnv* env, jclass clazz, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper()); im->incStrong(0); return reinterpret_cast <jint>(im); } NativeInputManager::NativeInputManager(jobject contextObj,jobject serviceObj, const sp<Looper>& looper) : mLooper(looper) { mInputManager = new InputManager(eventHub, this , this ); } |
4、Input事件的Manager:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | InputManager.cpp (frameworks\base\services\input) InputManager::InputManager( const sp<EventHubInterface>& eventHub, const sp<InputReaderPolicyInterface>& readerPolicy, const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) { mDispatcher = new InputDispatcher(dispatcherPolicy); mReader = new InputReader(eventHub, readerPolicy, mDispatcher); initialize(); } // InputReaderThread:事件读取 // InputDispatcherThread:事件分发 void InputManager::initialize() { mReaderThread = new InputReaderThread(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher); } status_t InputManager::start() { status_t result = mDispatcherThread->run( "InputDispatcher" , PRIORITY_URGENT_DISPLAY); result = mReaderThread->run( "InputReader" , PRIORITY_URGENT_DISPLAY); return OK; } |
5,事件读取、分发:
1 2 3 4 5 6 7 8 9 | InputReader.cpp (frameworks\base\services\input) InputReaderThread::InputReaderThread( const sp<InputReaderInterface>& reader) : Thread( /*canCallJava*/ true ), mReader(reader) { } InputDispatcher.cpp (frameworks\base\services\input) InputDispatcherThread::InputDispatcherThread( const sp<InputDispatcherInterface>& dispatcher) : Thread( /*canCallJava*/ true ), mDispatcher(dispatcher) { } |
6、PowerKey事件上报:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | InputReader.cpp (frameworks\base\services\input) void InputReader::loopOnce() { size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); { // acquire lock AutoMutex _l(mLock); if (count) { processEventsLocked(mEventBuffer, count); } } // release lock } void InputReader::processEventsLocked( const RawEvent* rawEvents, size_t count) { int32_t type = rawEvent->type; size_t batchSize = 1; if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) { ALOGD( "BatchSize: %d Count: %d" , batchSize, count); processEventsForDeviceLocked(deviceId, rawEvent, batchSize); } } void InputReader::processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count) { InputDevice* device = mDevices.valueAt(deviceIndex); device->process(rawEvents, count); } void InputDevice::process( const RawEvent* rawEvents, size_t count) { ALOGD( "InputDevice::process" ); size_t numMappers = mMappers.size(); for ( const RawEvent* rawEvent = rawEvents; count--; rawEvent++) { ALOGD( "Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld" , rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value, rawEvent->when); if (mDropUntilNextSync) { } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) { } else { ALOGD( "InputDevice::process else" ); for ( size_t i = 0; i < numMappers; i++) { InputMapper* mapper = mMappers[i]; mapper->process(rawEvent); } } } } void KeyboardInputMapper::process( const RawEvent* rawEvent) { ALOGI( "KeyboardInputMapper::process" ); switch (rawEvent->type) { case EV_KEY: { // #define EV_KEY 0x01 int32_t scanCode = rawEvent->code; int32_t usageCode = mCurrentHidUsage; mCurrentHidUsage = 0; if (isKeyboardOrGamepadKey(scanCode)) { int32_t keyCode; uint32_t flags; processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags); } break ; } } } void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) { // processkey, down=1, keyCode=26, policyFlags=1 ALOGI( "processkey, down=%d, keyCode=%d, policyFlags=%d, " , down, keyCode, policyFlags); if (down) { // Rotate key codes according to orientation if needed. } NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime); getListener()->notifyKey(&args); } InputListener.cpp (frameworks\base\services\input) void NotifyKeyArgs::notify( const sp<InputListenerInterface>& listener) const { ALOGD( "notify" ); listener->notifyKey( this ); } |
7、构建KeyEvent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | InputDispatcher.cpp (frameworks\base\services\input) void InputDispatcher::notifyKey( const NotifyKeyArgs* args) { ALOGD( "notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, " "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld" , args->eventTime, args->deviceId, args->source, args->policyFlags, args->action, args->flags, args->keyCode, args->scanCode, args->metaState, args->downTime); if (!validateKeyEvent(args->action)) { return ; } uint32_t policyFlags = args->policyFlags; int32_t flags = args->flags; int32_t metaState = args->metaState; KeyEvent event; event.initialize(args->deviceId, args->source, args->action, flags, args->keyCode, args->scanCode, metaState, 0, args->downTime, args->eventTime); mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags); } |
8、KeyEvent处理并调用PowerManagerService的休眠接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | com_android_server_input_InputManagerService.cpp (frameworks\base\services\jni) void NativeInputManager::interceptKeyBeforeQueueing( const KeyEvent* keyEvent, uint32_t& policyFlags) { ALOGD( "interceptKeyBeforeQueueing: policyFlags = %d\n" , policyFlags); if ((policyFlags & POLICY_FLAG_TRUSTED)) { nsecs_t when = keyEvent->getEventTime(); bool isScreenOn = this ->isScreenOn(); bool isScreenBright = this ->isScreenBright(); JNIEnv* env = jniEnv(); jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); jint wmActions; if (keyEventObj) { wmActions = env->CallIntMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeQueueing, keyEventObj, policyFlags, isScreenOn); if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing" )) { wmActions = 0; } android_view_KeyEvent_recycle(env, keyEventObj); env->DeleteLocalRef(keyEventObj); } handleInterceptActions(wmActions, when, /*byref*/ policyFlags); } } void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags) { if (wmActions & WM_ACTION_GO_TO_SLEEP) { ALOGD( "handleInterceptActions: Going to sleep." ); android_server_PowerManagerService_goToSleep(when); } if (wmActions & WM_ACTION_WAKE_UP) { ALOGD( "handleInterceptActions: Waking up." ); android_server_PowerManagerService_wakeUp(when); } if (wmActions & WM_ACTION_PASS_TO_USER) { policyFlags |= POLICY_FLAG_PASS_TO_USER; } else { ALOGD( "handleInterceptActions: Not passing key to user." ); } } com_android_server_power_PowerManagerService.cpp (frameworks\base\services\jni) void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) { if (gPowerManagerServiceObj) { JNIEnv* env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleepFromNative, nanoseconds_to_milliseconds(eventTime), 0); checkAndClearExceptionFromCallback(env, "goToSleepFromNative" ); } } |
9、由于是从PowerKey发起休眠/唤醒动作,所以使用的是goToSleepFromNative:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | PowerManagerService.java (frameworks\base\services\java\com\android\server\power) private void goToSleepFromNative( long eventTime, int reason) { Slog.i(TAG, "goToSleepFromNative, reason: " + reason); if (reason != PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN && reason != PowerManager.GO_TO_SLEEP_REASON_TIMEOUT) { if (mDisplayManager.isWfdConnect()) { mHandler.sendEmptyMessage(MSG_DISABLE_WIFI_FOR_WIFIP2P); return ; } } goToSleepInternal(eventTime, reason); } private void goToSleepInternal( long eventTime, int reason) { Slog.i(TAG, "goToSleepInternal, reason: " + reason); synchronized (mLock) { if (goToSleepNoUpdateLocked(eventTime, reason)) { updatePowerStateLocked(); } } } } /** * This is the main function that performs power state transitions. * We centralize them here so that we can recompute the power state completely * each time something important changes, and ensure that we do it the same * way each time. The point is to gather all of the transition logic here. */ private void updatePowerStateLocked() { // Phase 0: Basic state updates. // Phase 1: Update wakefulness. // Loop because the wake lock and user activity computations are influenced // by changes in wakefulness. // Phase 2: Update dreams and display power state. // Phase 3: Send notifications, if needed. // Phase 4: Update suspend blocker. // Because we might release the last suspend blocker here, we need to make sure // we finished everything else first! updateSuspendBlockerLocked(); } |
10、PowerManagerService执行休眠,对了,就是释放锁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * Updates the suspend blocker that keeps the CPU alive. */ private void updateSuspendBlockerLocked() { final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0); final boolean needDisplaySuspendBlocker = needDisplaySuspendBlocker(); // First acquire suspend blockers if needed. if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.acquire(); mHoldingWakeLockSuspendBlocker = true ; } if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.acquire(); mHoldingDisplaySuspendBlocker = true ; } // Then release suspend blockers if needed. if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) { mWakeLockSuspendBlocker.release(); mHoldingWakeLockSuspendBlocker = false ; } if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) { mDisplaySuspendBlocker.release(); mHoldingDisplaySuspendBlocker = false ; } } |
至于锁释放是如何和内核交互的,参见:【Android休眠】之休眠锁的获取和释放
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!