Linux 3.10Android 4.4

http://blog.csdn.net/u013686019/article/details/53691895

一、PowerManagerService

引起休眠动作(进入休眠前执行一些必要的操作)的事件有两个:

  • PowerKey事件,通过JNI调用PowerManagerService中的goToSleepFromNative()方法
  • Timeout,指【设置->显示->休眠】中设置的Timeout数值

Android休眠在PowerManagerService中的流程如下图:



图示:最终都会调用到updatePowerStateLocked()方法,在更新一些标志的状态、发送休眠通知后,调用updateSuspendBlockerLocked()执行休眠锁的释放动作


二、PowerManagerService中Timeout处理流程

/** * 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的值,比如30sfinal 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 = 6sfinal int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);mUserActivitySummary = 0;// 5、mLastUserActivityTime >= mLastWakeTime: 用户最后使用机器的时间在上次唤醒时间之后if (mLastUserActivityTime >= mLastWakeTime) {// nextTimeout:此处指到屏幕Dim的时间间隔// 6、nextTimeout的时间:BASE + 30 - 6 = BASE + 24nextTimeout = mLastUserActivityTime+ screenOffTimeout - screenDimDuration;if (now < nextTimeout) {// now在屏幕Dim之前,说明屏幕亮着,设置flagmUserActivitySummary |= USER_ACTIVITY_SCREEN_BRIGHT;} else {// extTimeout:此处指到屏幕熄灭的时间间隔//7、nextTimeout的时间:BASE + 30 = BASE + 30nextTimeout = mLastUserActivityTime + screenOffTimeout;// 8、now处于屏幕Dim之后、屏幕熄灭之前设置DIM flagif (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 {@Overridepublic 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 threadmDirty |= 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;}@Overridepublic void acquire() {synchronized (this) {mReferenceCount += 1;if (mReferenceCount == 1) {nativeAcquireSuspendBlocker(mName);}}}@Overridepublic 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

更多相关文章

  1. android 获取程序的安装时间
  2. Android(安卓)剩余可用时长的计算公式
  3. React native WebView 适配Android(安卓)和 Ios的问题
  4. 自己实现个Android下仿IOS的时间选择器、时间控件Time-Selector
  5. Android(安卓)Studio菜鸟开发————TimePicker DataPicker 日
  6. android View的点击事件分发机制的简单认知
  7. android 开发故障记录
  8. 让我们创建屏幕- Android(安卓)UI布局和控件
  9. Android程序监听Home键

随机推荐

  1. Android(安卓)修改Menu背景
  2. 【移动开发】Android中异步加载数据(二)Asy
  3. android 自定义资源id,aapt2,public.xml,支
  4. Android(安卓)Studio 3.0找不到Android(
  5. 拖动条(seekbar)
  6. Android动态申请权限整理
  7. Android(安卓)Common method
  8. Android中的排序,颠倒。
  9. Android按下录音录音动画效果 ,自定义Vie
  10. android 9 第三方app默认拥有权限