//创建电源锁

[cpp] view plain copy

PowerManagerService.java

mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");

mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");


private SuspendBlocker createSuspendBlockerLocked(String name) {
SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
mSuspendBlockers.add(suspendBlocker);
return suspendBlocker;
}

//电源锁操作类的实现

[cpp] view plain copy

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) {
if (DEBUG_SPEW) {
Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
}
nativeAcquireSuspendBlocker(mName);
}
}
}

@Override
public void release() {
synchronized (this) {
mReferenceCount -= 1;
if (mReferenceCount == 0) {
if (DEBUG_SPEW) {
Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
}
nativeReleaseSuspendBlocker(mName);
} else if (mReferenceCount < 0) {
Log.wtf(TAG, "Suspend blocker \"" + mName
+ "\" was released without being acquired!", new Throwable());
mReferenceCount = 0;
}
}
}


}

//JNI层函数实现电源锁的获取

[cpp] view plain copy

com_android_server_power_PowerManagerService.cpp

static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
ScopedUtfChars name(env, nameStr);
acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
}


//将电源锁写入到相应的文件中,相当于获得了电源锁

power.c

[cpp] view plain copy

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));
}

//打开记录电源锁的文件

[cpp] view plain copy

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;
}
}

//记录电源锁的文件路径

[cpp] view plain copy

const char * const OLD_PATHS[] = {
"/sys/android_power/acquire_partial_wake_lock",
"/sys/android_power/release_wake_lock",
};

const char * const NEW_PATHS[] = {
"/sys/power/wake_lock",
"/sys/power/wake_unlock",
};

到现在为止,我们的代码流程已经走了一大半了,我们一开始介绍的android的上面几层Framework层、JNI层、HAL层都已经介绍了。下面就应该是和kernel层进行交互了。
但是在android/hardware/libhardware_legacy/power/power.c中的acquire_wake_lock()函数似乎没法和kernel层进行通信啊?最后的返回语句return write(fd, id, strlen(id))是一个系统调用,这里就实现了与kernel的交互。
kernel/power/main.c中的power_attr宏很多地方用到:

[cpp] view plain copy
  1. #definepower_attr(_name)\
  2. staticstructkobj_attribute_name##_attr={\
  3. .attr={\
  4. .name=__stringify(_name),\
  5. .mode=0644,\
  6. },\
  7. .show=_name##_show,\
  8. .store=_name##_store,\
  9. }
[cpp] view plain copy
  1. #ifdefCONFIG_USER_WAKELOCK
  2. power_attr(wake_lock);
  3. power_attr(wake_unlock);
  4. #endif
default y
User-space wake lock api. Write "lockname" or "lockname timeout"
to /sys/power/wake_lock lock and if needed create a wake lock.
Write "lockname" to /sys/power/wake_unlock to unlock a user wake
lock.
[cpp] view plain copy
  1. #ifdefCONFIG_PM_WAKELOCKS
  2. power_attr(wake_lock);
  3. power_attr(wake_unlock);
  4. #endif
default n
Allow user space to create, activate and deactivate wakeup source
objects with the help of a sysfs-based interface.
宏展开,等价于:
[cpp] view plain copy
  1. staticstructkobj_attributewake_lock_attr={
  2. .attr={
  3. .name=“wake_lock”,
  4. .mode=0644,
  5. },
  6. .show=wake_lock_show,
  7. .store=wake_lock_store,
  8. }
[cpp] view plain copy
  1. staticstructkobj_attributewake_unlock_attr={
  2. .attr={
  3. .name=“wake_unlock”,
  4. .mode=0644,
  5. },
  6. .show=wake_unlock_show,
  7. .store=wake_unlock_store,
  8. }
show和store函数的源码位于kernel/power/userwakelock.c。
[cpp] view plain copy
  1. staticstructattribute*g[]={
  2. &state_attr.attr,
  3. #ifdefCONFIG_PM_TRACE
  4. &pm_trace_attr.attr,
  5. &pm_trace_dev_match_attr.attr,
  6. #endif
  7. #ifdefCONFIG_PM_SLEEP
  8. &pm_async_attr.attr,
  9. &wakeup_count_attr.attr,
  10. #ifdefCONFIG_USER_WAKELOCK
  11. &wake_lock_attr.attr,
  12. &wake_unlock_attr.attr,
  13. #endif
  14. #ifdefCONFIG_PM_AUTOSLEEP
  15. &autosleep_attr.attr,
  16. #endif
  17. #ifdefCONFIG_PM_WAKELOCKS
  18. &wake_lock_attr.attr,
  19. &wake_unlock_attr.attr,
  20. #endif
  21. #ifdefCONFIG_PM_DEBUG
  22. &pm_test_attr.attr,
  23. #endif
  24. #ifdefCONFIG_PM_SLEEP_DEBUG
  25. &pm_print_times_attr.attr,
  26. #endif
  27. #endif
  28. #ifdefCONFIG_FREEZER
  29. &pm_freeze_timeout_attr.attr,
  30. #endif
  31. NULL,
  32. };
[cpp] view plain copy
  1. staticstructattribute_groupattr_group={
  2. .attrs=g,
  3. };
pm_init()->
error = sysfs_create_group(power_kobj, &attr_group);
好了,我们该回到原来我们产生疑问的地方了这时我们还得关注其中的另一个函数acquire_wake_lock()->initialize_fds()。 [cpp] view plain copy
  1. initialize_fds(void)
  2. {
  3. //XXX:shouldbethis:
  4. //pthread_once(&g_initialized,open_file_descriptors);
  5. //XXX:notthis:
  6. if(g_initialized==0){
  7. if(open_file_descriptors(NEW_PATHS)<0)
  8. open_file_descriptors(OLD_PATHS);
  9. g_initialized=1;
  10. }
  11. }

其实这个函数中最核心的步骤就是open_file_descriptors(NEW_PATHS),顺序打开NEW_PATHS[ ]中的文件:

[cpp] view plain copy
  1. staticint
  2. open_file_descriptors(constchar*constpaths[])
  3. {
  4. inti;
  5. for(i=0;i<OUR_FD_COUNT;i++){
  6. intfd=open(paths[i],O_RDWR);
  7. if(fd<0){
  8. fprintf(stderr,"fatalerroropening\"%s\"\n",paths[i]);
  9. g_error=errno;
  10. return-1;
  11. }
  12. g_fds[i]=fd;
  13. }
  14. g_error=0;
  15. return0;
  16. }
[cpp] view plain copy
  1. constchar*constNEW_PATHS[]={
  2. "/sys/power/wake_lock",
  3. "/sys/power/wake_unlock",
  4. };

总之经过着一系列的步骤后,最终我们将在 return write(fd, id, strlen(id));时调用android/kernel/kernel/power/userwakelock.c 中的 wake_lock_store()函数。

[cpp] view plain copy
  1. ssize_twake_lock_store(
  2. structkobject*kobj,structkobj_attribute*attr,
  3. constchar*buf,size_tn)
  4. {
  5. longtimeout;
  6. structuser_wake_lock*l;
  7. mutex_lock(&tree_lock);
  8. l=lookup_wake_lock_name(buf,1,&timeout);
  9. if(IS_ERR(l)){
  10. n=PTR_ERR(l);
  11. gotobad_name;
  12. }
  13. if(debug_mask&DEBUG_ACCESS)
  14. pr_info("wake_lock_store:%s,timeout%ld\n",l->name,timeout);
  15. if(timeout)
  16. wake_lock_timeout(&l->wake_lock,timeout);
  17. else
  18. wake_lock(&l->wake_lock);
  19. bad_name:
  20. mutex_unlock(&tree_lock);
  21. returnn;
  22. }
[cpp] view plain copy
  1. structrb_rootuser_wake_locks;
  2. staticstructuser_wake_lock*lookup_wake_lock_name(
  3. constchar*buf,intallocate,long*timeoutptr)
  4. {
  5. structrb_node**p=&user_wake_locks.rb_node;
  6. structrb_node*parent=NULL;
  7. structuser_wake_lock*l;
  8. intdiff;
  9. u64timeout;
  10. intname_len;
  11. constchar*arg;
  12. /*Findlengthoflocknameandstartofoptionaltimeoutstring*/
  13. arg=buf;
  14. while(*arg&&!isspace(*arg))
  15. arg++;
  16. //lockname的长度
  17. name_len=arg-buf;
  18. if(!name_len)
  19. gotobad_arg;
  20. while(isspace(*arg))
  21. arg++;
  22. /*Processtimeoutstring*/
  23. if(timeoutptr&&*arg){
  24. //(char**)&arg存储的是解析string的结束字符
  25. timeout=simple_strtoull(arg,(char**)&arg,0);
  26. while(isspace(*arg))
  27. arg++;
  28. //如果解析string的结束字符不是’\0’
  29. if(*arg)
  30. gotobad_arg;
  31. /*converttimeoutfromnanosecondstojiffies>0*/
  32. timeout+=(NSEC_PER_SEC/HZ)-1;
  33. //do_div(a,b)的返回值是余数,商保存到a中
  34. do_div(timeout,(NSEC_PER_SEC/HZ));
  35. if(timeout<=0)
  36. timeout=1;
  37. *timeoutptr=timeout;
  38. }elseif(*arg)
  39. //timeoutptr为NULL
  40. gotobad_arg;
  41. elseif(timeoutptr)
  42. //*arg为0,没有timeout
  43. *timeoutptr=0;
  44. /*Lookupwakelockinrbtree*/
  45. //对于一颗空的红黑树,略过while。wakelock按照name从小到大的顺序存储到user_wake_locks红黑树中
  46. while(*p){
  47. parent=*p;
  48. l=rb_entry(parent,structuser_wake_lock,node);
  49. diff=strncmp(buf,l->name,name_len);
  50. //如果buf是l->name的子串,那么l->name[name_len]就不会为0,但是buf[name_len]会为0
  51. if(!diff&&l->name[name_len])
  52. diff=-1;
  53. if(debug_mask&DEBUG_ERROR)
  54. pr_info("lookup_wake_lock_name:compare%.*s%s%d\n",
  55. name_len,buf,l->name,diff);
  56. if(diff<0)
  57. p=&(*p)->rb_left;
  58. elseif(diff>0)
  59. p=&(*p)->rb_right;
  60. else
  61. returnl;
  62. }
  63. /*Allocateandaddnewwakelocktorbtree*/
  64. //allocate为0,表示不需要分配新的wakelock,只在rbtree上查找,找不到就出错了
  65. if(!allocate){
  66. if(debug_mask&DEBUG_ERROR)
  67. pr_info("lookup_wake_lock_name:%.*snotfound\n",
  68. name_len,buf);
  69. returnERR_PTR(-EINVAL);
  70. }
  71. l=kzalloc(sizeof(*l)+name_len+1,GFP_KERNEL);
  72. if(l==NULL){
  73. if(debug_mask&DEBUG_FAILURE)
  74. pr_err("lookup_wake_lock_name:failedtoallocate"
  75. "memoryfor%.*s\n",name_len,buf);
  76. returnERR_PTR(-ENOMEM);
  77. }
  78. memcpy(l->name,buf,name_len);
  79. if(debug_mask&DEBUG_NEW)
  80. pr_info("lookup_wake_lock_name:newwakelock%s\n",l->name);
  81. wake_lock_init(&l->wake_lock,WAKE_LOCK_SUSPEND,l->name);
  82. //插入结点,并染成红色
  83. rb_link_node(&l->node,parent,p);
  84. rb_insert_color(&l->node,&user_wake_locks);
  85. returnl;
  86. bad_arg:
  87. if(debug_mask&DEBUG_ERROR)
  88. pr_info("lookup_wake_lock_name:wakelock,%.*s,badarg,%s\n",
  89. name_len,buf,arg);
  90. returnERR_PTR(-EINVAL);
  91. }

wake_lock_store()执行的基本流程为:首先调用lookup_wake_lock_name()来获得指定的唤醒锁,若延迟参数timeout为零的话,就调用 wake_lock()否则就调用wake_lock_timeout(),但不管调用哪个最后都会调用到android/kernel/kernel/power/wakelock.c中的函数static void wake_lock_internal()。

[cpp] view plain copy
  1. staticvoidwake_lock_internal(
  2. structwake_lock*lock,longtimeout,inthas_timeout)
  3. {
  4. inttype;
  5. unsignedlongirqflags;
  6. longexpire_in;
  7. spin_lock_irqsave(&list_lock,irqflags);
  8. type=lock->flags&WAKE_LOCK_TYPE_MASK;
  9. //检查type是否合法
  10. BUG_ON(type>=WAKE_LOCK_TYPE_COUNT);
  11. //检查是否初始化过
  12. BUG_ON(!(lock->flags&WAKE_LOCK_INITIALIZED));
  13. #ifdefCONFIG_WAKELOCK_STAT
  14. if(type==WAKE_LOCK_SUSPEND&&wait_for_wakeup){
  15. if(debug_mask&DEBUG_WAKEUP)
  16. pr_info("wakeupwakelock:%s\n",lock->name);
  17. wait_for_wakeup=0;
  18. lock->stat.wakeup_count++;
  19. }
  20. if((lock->flags&WAKE_LOCK_AUTO_EXPIRE)&&
  21. (long)(lock->expires-jiffies)<=0){
  22. wake_unlock_stat_locked(lock,0);
  23. lock->stat.last_time=ktime_get();
  24. }
  25. #endif
  26. if(!(lock->flags&WAKE_LOCK_ACTIVE)){
  27. lock->flags|=WAKE_LOCK_ACTIVE;
  28. #ifdefCONFIG_WAKELOCK_STAT
  29. lock->stat.last_time=ktime_get();
  30. #endif
  31. }
  32. //从inactive_locks上删除
  33. list_del(&lock->link);
  34. if(has_timeout){
  35. if(debug_mask&DEBUG_WAKE_LOCK)
  36. pr_info("wake_lock:%s,type%d,timeout%ld.%03lu\n",
  37. lock->name,type,timeout/HZ,
  38. (timeout%HZ)*MSEC_PER_SEC/HZ);
  39. lock->expires=jiffies+timeout;
  40. lock->flags|=WAKE_LOCK_AUTO_EXPIRE;
  41. list_add_tail(&lock->link,&active_wake_locks[type]);
  42. }else{
  43. if(debug_mask&DEBUG_WAKE_LOCK)
  44. pr_info("wake_lock:%s,type%d\n",lock->name,type);
  45. lock->expires=LONG_MAX;
  46. lock->flags&=~WAKE_LOCK_AUTO_EXPIRE;
  47. list_add(&lock->link,&active_wake_locks[type]);
  48. }
  49. if(type==WAKE_LOCK_SUSPEND){
  50. current_event_num++;
  51. #ifdefCONFIG_WAKELOCK_STAT
  52. if(lock==&main_wake_lock)
  53. update_sleep_wait_stats_locked(1);
  54. elseif(!wake_lock_active(&main_wake_lock))
  55. update_sleep_wait_stats_locked(0);
  56. #endif
  57. if(has_timeout)
  58. expire_in=has_wake_lock_locked(type);
  59. else
  60. expire_in=-1;
  61. if(expire_in>0){
  62. if(debug_mask&DEBUG_EXPIRE)
  63. pr_info("wake_lock:%s,startexpiretimer,"
  64. "%ld\n",lock->name,expire_in);
  65. mod_timer(&expire_timer,jiffies+expire_in);
  66. }else{
  67. if(del_timer(&expire_timer))
  68. if(debug_mask&DEBUG_EXPIRE)
  69. pr_info("wake_lock:%s,stopexpiretimer\n",
  70. lock->name);
  71. if(expire_in==0)
  72. queue_work(suspend_work_queue,&suspend_work);
  73. }
  74. }
  75. spin_unlock_irqrestore(&list_lock,irqflags);
  76. }

//电源锁的使用

[cpp] view plain copy

/**
* Updates the suspend blocker that keeps the CPU alive.
*
* This function must have no other side-effects.
*/
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;
}
}



//判断是否处于亮屏或者正在变化阶段

[cpp] view plain copy private boolean needDisplaySuspendBlocker() {

//正处于变化阶段
if (!mDisplayReady) {
return true;
}
if (mDisplayPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {

//有疑问?
// If we asked for the screen to be on but it is off due to the proximity
// sensor then we may suspend but only if the configuration allows it.
// On some hardware it may not be safe to suspend because the proximity
// sensor may not be correctly configured as a wake-up source.
if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
|| !mSuspendWhenScreenOffDueToProximityConfig) {
return true;
}
}
return false;
}

更多相关文章

  1. JAVA按钮显示用户名+密码
  2. 五分钟学会之AsyncTask
  3. Android组播域名服务
  4. Service详解一
  5. 地图测试
  6. Android通过广播接收者调用服务内方法
  7. Android(安卓)开发游戏中的SurfaceView,Callback,SurfaceHolder
  8. setonClickListener()的解释
  9. handler机制(二)源码分析

随机推荐

  1. 历年阿里巴巴面试题集,蚂蚁金服Android面
  2. Android(安卓)Framework 框架系列之 App
  3. Android(安卓)内存泄露的检查分析方法
  4. Android(安卓)UI性能优化——理论篇
  5. Android中的底部弹窗
  6. 翻译CodePath Android(安卓)CliffNotes
  7. Android(安卓)Studio 基础 之 简单获取手
  8. 【Android实战之旅 003】Android(安卓)UI
  9. Android性能优化之Debug GPU Overdraw
  10. Notification通知栏图标5.0以后效果不同