赞
踩
一、PowerManagerService
引起休眠动作(进入休眠前执行一些必要的操作)的事件有两个:
PowerKey事件,通过JNI调用PowerManagerService中的goToSleepFromNative()方法
Timeout,指【设置->显示->休眠】中设置的Timeout数值
Android休眠在PowerManagerService中的流程如下图:
图示:最终都会调用到updatePowerStateLocked()方法,在更新一些标志的状态、发送休眠通知后,调用updateSuspendBlockerLocked()执行休眠锁的释放动作。
- /**
- * PowerManagerService设置了很多的标志位,用来标识某个事件的状态是否发生改变,比如:
- * DIRTY_SETTINGS,一旦系统设置发生变化,DIRTY_SETTINGS位就会被设置,
- * 处理函数检测到DIRTY_SETTINGS被置位,就进行相应的动作
- * dirty:包含了所有发生变化的标志
- */
- private void updateUserActivitySummaryLocked(long now, int dirty) {
- // Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
- // 1、消息队列中含有尚未处理的MSG_USER_ACTIVITY_TIMEOUT,就移除,避免重复进入休眠操作
- mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
-
- long nextTimeout = 0;
- // 2、mWakefulness != WAKEFULNESS_ASLEEP:当前醒着
- if (mWakefulness != WAKEFULNESS_ASLEEP) {
- // 3、获取Timeout的值,比如30s
- final int screenOffTimeout = getScreenOffTimeoutLocked();
- // 屏幕在熄灭前,会先变暗一段时间,这段时间叫DimDuration,计算方式:
- // SCREEN_DIM_DURATION = 7s,MAXIMUM_SCREEN_DIM_RATIO = 0.2
- // Math.min(SCREEN_DIM_DURATION, (int)(screenOffTimeout * MAXIMUM_SCREEN_DIM_RATIO))
- // 4、获取DimDuration的值,30s x 0.2 = 6s
- final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
-
- mUserActivitySummary = 0;
- // 5、mLastUserActivityTime >= mLastWakeTime: 用户最后使用机器的时间在上次唤醒时间之后
- if (mLastUserActivityTime >= mLastWakeTime) {
- // nextTimeout:此处指到屏幕Dim的时间间隔
- // 6、nextTimeout的时间:BASE + 30 - 6 = BASE + 24
- nextTimeout = mLastUserActivityTime
- + screenOffTimeout - screenDimDuration;
- if (now < nextTimeout) {
- // now在屏幕Dim之前,说明屏幕亮着,设置flag
- mUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;
- } else {
- // extTimeout:此处指到屏幕熄灭的时间间隔
- //7、nextTimeout的时间:BASE + 30 = BASE + 30
- nextTimeout = mLastUserActivityTime + screenOffTimeout;
- // 8、now处于屏幕Dim之后、屏幕熄灭之前设置DIM flag
- if (now < nextTimeout) {
- mUserActivitySummary |= USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0
- && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
- if (now < nextTimeout
- && mDisplayPowerRequest.screenState
- != DisplayPowerRequest.SCREEN_STATE_OFF) {
- mUserActivitySummary = mDisplayPowerRequest.screenState
- == DisplayPowerRequest.SCREEN_STATE_BRIGHT ?
- USER_ACTIVITY_SCREEN_BRIGHT : USER_ACTIVITY_SCREEN_DIM;
- }
- }
- // mUserActivitySummary发生了改变
- if (mUserActivitySummary != 0) {
- Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY_TIMEOUT);
- Slog.i(TAG, "updateUserActivitySummaryLocked, send MSG_USER_ACTIVITY_TIMEOUT");
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, nextTimeout);
- }
- } else {
- mUserActivitySummary = 0;
- }
- }
- }
-
-
- MSG_USER_ACTIVITY_TIMEOUT事件处理:
-
- private final class PowerManagerHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_USER_ACTIVITY_TIMEOUT:
- handleUserActivityTimeout();
- break;
- }
- }
-
- /**
- * Called when a user activity timeout has occurred.
- * Simply indicates that something about user activity has changed so that the new
- * state can be recomputed when the power state is updated.
- */
- private void handleUserActivityTimeout() { // runs on handler thread
- mDirty |= DIRTY_USER_ACTIVITY;
- updatePowerStateLocked();
- }
-
-
- 三、PowerManagerService中休眠锁的获取/释放
- 这部分代码清晰,直接看下:
-
- private void updatePowerStateLocked() {
- if (!mSystemReady || mDirty == 0) {
- return;
- }
- // Phase 0: Basic state updates.
-
- // Phase 1: Update 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();
- }
-
- /**
- * 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;
- }
- }
-
- private final class SuspendBlockerImpl implements SuspendBlocker {
- private final String mName;
- private int mReferenceCount;
-
- public SuspendBlockerImpl(String name) {
- mName = name;
- }
-
- @Override
- public void acquire() {
- synchronized (this) {
- mReferenceCount += 1;
- if (mReferenceCount == 1) {
- nativeAcquireSuspendBlocker(mName);
- }
- }
- }
-
- @Override
- public void release() {
- synchronized (this) {
- mReferenceCount -= 1;
- if (mReferenceCount == 0) {
-
- nativeReleaseSuspendBlocker(mName);
- }
- }
- }
- }
-
- 休眠锁的获取和释放,最终通过JNI方式读写/sys/power/wake_lock、/sys/power/wake_unlock:
-
- // 1、JNI接口
- com_android_server_power_PowerManagerService.cpp (frameworks\base\services\jni)
- static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
- ScopedUtfChars name(env, nameStr);
- acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
- }
-
- // 2、定义要操作的文件
- power.c (hardware\libhardware_legacy\power)
- const char * const NEW_PATHS[] = {
- "/sys/power/wake_lock",
- "/sys/power/wake_unlock",
- };
-
- // 3、初始化设备节点
- static inline void initialize_fds(void)
- {
- if (g_initialized == 0) {
- if(open_file_descriptors(NEW_PATHS) < 0)
- open_file_descriptors(OLD_PATHS);
- g_initialized = 1;
- }
- }
-
- static int open_file_descriptors(const char * const paths[])
- {
- int i;
- for (i=0; i<OUR_FD_COUNT; i++) {
- int fd = open(paths[i], O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);
- g_error = errno;
- return -1;
- }
- g_fds[i] = fd;
- }
-
- g_error = 0;
- return 0;
- }
-
- // 4、id即为锁的名字,之后就是读写设备
- int acquire_wake_lock(int lock, const char* id)
- {
- initialize_fds();
-
- if (g_error) return g_error;
-
- int fd;
-
- if (lock == PARTIAL_WAKE_LOCK) {
- fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
- }
- else {
- return EINVAL;
- }
-
- return write(fd, id, strlen(id));
- }
-
MSG_USER_ACTIVITY_TIMEOUT事件处理:
- private final class PowerManagerHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_USER_ACTIVITY_TIMEOUT:
- handleUserActivityTimeout();
- break;
- }
- }
-
- /**
- * Called when a user activity timeout has occurred.
- * Simply indicates that something about user activity has changed so that the new
- * state can be recomputed when the power state is updated.
- */
- private void handleUserActivityTimeout() { // runs on handler thread
- mDirty |= DIRTY_USER_ACTIVITY;
- updatePowerStateLocked();
- }
这部分代码清晰,直接看下:
- private void updatePowerStateLocked() {
- if (!mSystemReady || mDirty == 0) {
- return;
- }
- // Phase 0: Basic state updates.
-
- // Phase 1: Update 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();
- }
-
- /**
- * 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;
- }
- }
-
- private final class SuspendBlockerImpl implements SuspendBlocker {
- private final String mName;
- private int mReferenceCount;
-
- public SuspendBlockerImpl(String name) {
- mName = name;
- }
-
- @Override
- public void acquire() {
- synchronized (this) {
- mReferenceCount += 1;
- if (mReferenceCount == 1) {
- nativeAcquireSuspendBlocker(mName);
- }
- }
- }
-
- @Override
- public void release() {
- synchronized (this) {
- mReferenceCount -= 1;
- if (mReferenceCount == 0) {
-
- nativeReleaseSuspendBlocker(mName);
- }
- }
- }
- }
休眠锁的获取和释放,最终通过JNI方式读写/sys/power/wake_lock、/sys/power/wake_unlock:
- // 1、JNI接口
- com_android_server_power_PowerManagerService.cpp (frameworks\base\services\jni)
- static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
- ScopedUtfChars name(env, nameStr);
- acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
- }
-
- // 2、定义要操作的文件
- power.c (hardware\libhardware_legacy\power)
- const char * const NEW_PATHS[] = {
- "/sys/power/wake_lock",
- "/sys/power/wake_unlock",
- };
-
- // 3、初始化设备节点
- static inline void initialize_fds(void)
- {
- if (g_initialized == 0) {
- if(open_file_descriptors(NEW_PATHS) < 0)
- open_file_descriptors(OLD_PATHS);
- g_initialized = 1;
- }
- }
-
- static int open_file_descriptors(const char * const paths[])
- {
- int i;
- for (i=0; i<OUR_FD_COUNT; i++) {
- int fd = open(paths[i], O_RDWR);
- if (fd < 0) {
- fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);
- g_error = errno;
- return -1;
- }
- g_fds[i] = fd;
- }
-
- g_error = 0;
- return 0;
- }
-
- // 4、id即为锁的名字,之后就是读写设备
- int acquire_wake_lock(int lock, const char* id)
- {
- initialize_fds();
-
- if (g_error) return g_error;
-
- int fd;
-
- if (lock == PARTIAL_WAKE_LOCK) {
- fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
- }
- else {
- return EINVAL;
- }
-
- return write(fd, id, strlen(id));
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。