受不了xxxx恶心人的行为,遂搬迁至博客园。 始发:2016-12-16 13:08:47 版本信息: Linux:3.10 Android: 4.4
Android休眠在framework的处理涉及两个系统服务,InputManagerService和PowerManagerService。InputManagerService负责处理PowerKey产生的Input事件,根据事件类型调用PowerManagerService的休眠、唤醒接口:
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执行具体的休眠、唤醒动作:
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服务加载:
SystemServer.java (frameworks\base\services\java\com\android\server) InputManagerService inputManager = null; inputManager = new InputManagerService(context, wmHandler); inputManager.start();
2、InputManagerService Java:
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:
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:
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,事件读取、分发:
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事件上报:
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:
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的休眠接口:
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:
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执行休眠,对了,就是释放锁:
/** * 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休眠】之休眠锁的获取和释放