【Android休眠】之Android对PowerKey事件的处理(1)代码流程

版本信息:
Linux 3.10
Android 4.4
http://blog.csdn.net/u013686019/article/details/53691879

Android休眠在framework的处理涉及两个系统服务,InputManagerServicePowerManagerServiceInputManagerService负责处理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();
}

它们之间关系如下图:

【Android休眠】之Android对PowerKey事件的处理(1)代码流程_第1张图片


由于这两个服务涉及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 = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast(im);
}

NativeInputManager::NativeInputManager(jobject contextObj,jobject serviceObj, const sp& looper) :
        mLooper(looper) {
    mInputManager = new InputManager(eventHub, this, this);
}

4、Input事件的Manager:

InputManager.cpp (frameworks\base\services\input)
InputManager::InputManager(
        const sp& eventHub,
        const sp& readerPolicy,
        const sp& 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& reader) :
        Thread(/*canCallJava*/ true), mReader(reader) {
}

InputDispatcher.cpp (frameworks\base\services\input)
InputDispatcherThread::InputDispatcherThread(const sp& 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& 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源码,Android休眠)