Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178870
  • 博文数量: 27
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 618
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-15 09:12
文章分类
文章存档

2014年(17)

2013年(10)

我的朋友

分类: Android平台

2014-01-23 16:10:32

最近好好学习看了看Android 关于睡眠的代码,从Framewake到Native到Kernel 学习了下,下面先对Framewake Native Kernel 做个简单总结: 按照自己看代码的理解和网上看得知识,如果不对,希望大牛们可以帮我指出来

以前从来没有看过上层的代码,最近看了之后,发现上层的代码结构复杂程度和KERNEL有一拼,但是封装的很好,学习了

言归正传:
我暂时把APP Framewake Native JNI看作成上层,底层包含kernel

需要先明白两个类的关系,第一个是PowerManager,还有一个是PowerManagerService,第一个是提供给上层APP调用的封装接口,第二个是具体的实现,
他们两个关联文件是 IPowerManager.aidl ,由于没有经验找了半天IPowerManager.cpp,后来发现跟IPowerManager.cpp半毛钱关系都没有,PowerManagerService继承了
IPowerManager类,并且实现了相关的方法,具体接口定义都存在IPowerManager.aidl中,看到这里是不是很迫不及待写个应用去尝试调用PowerManager去创建一个锁了,不让系统睡,哇哈哈
frameworks/base/services/java/com/android/server/power/PowerManagerService.cpp 这个目录下所有的文件都比较重要,这个会编译到 services 中
frameworks/base/core/java/android/os/IPowerManager.aidl
frameworks/base/core/java/android/os/IPowerManager.java

我们需要看看给APP提供那些接口呢? 这里不一一列举,就说几个,左边就是APP可以调用的接口,而右边是PowerManagerService对应的实现方法,这里有一个很重要的问题,
他们两个是通过什么通信呢?没错,是使用binder,我没有看过,还不太明白,以后再说。

PowerManager

PowerManagerService

goToSleep(long time)

goToSleep(long eventTime, int reason)

isScreenOn()

isScreenOn()

reboot(String reason)

reboot(boolean confirm, String reason, boolean wait)

userActivity(long when, boolean noChangeLights)

userActivity(long eventTime, int event, int flags)

wakeUp(long time)

wakeUp(long eventTime)


我们先跟随goToSleep函数吧,这个是在PowerManager.cpp中的
479     public void goToSleep(long time) {
480         try {
481             mService.goToSleep(time, GO_TO_SLEEP_REASON_USER);                                                                             
482         } catch (RemoteException e) {
483         }
484     }

其中的mService就是PowerManagerService类中的goToSleep方法,

 988     public void goToSleep(long eventTime, int reason) {
 989         if (eventTime > SystemClock.uptimeMillis()) {
 990             throw new IllegalArgumentException("event time must not be in the future");
 991         }
 992
 993         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
 994
 995         final long ident = Binder.clearCallingIdentity();
 996         try {
 997             goToSleepInternal(eventTime, reason);
 998         } finally {
 999             Binder.restoreCallingIdentity(ident);
1000         }
1001     }

这个函数主要权限检查,然后调用自己类中的goToSleepInternel方法,

1008     private void goToSleepInternal(long eventTime, int reason) {
1009         synchronized (mLock) {
1010             if (goToSleepNoUpdateLocked(eventTime, reason)) {
1011                 updatePowerStateLocked();
1012                 mDisplayPowerController.requestButtonLedState(false);
1013             }
1014         }
1015     }

goToSleepNoUpdateLocked()和updatePowerStateLocked(),而goToSleepNoUpdateLocked是goToSleep功能的计算者,来决定是否要休眠,而updatePowerStateLocked函数算是功能的执行者,而且这个执行者同时负责执行了很多其他的功能,这里就不都贴两段代码了,因为太长了,下面简单的介绍下,

goToSleepNoUpdateLocked函数的主要功能就是进行必要属性的赋值,在PowerManagerService代码可以看到各种NoUpdateLocked这样的后缀,都类似与goToSleepNoUpdateLocked方法,只不过进行必要属性更新/

updatePowerStateLocked函数
1114     private void updatePowerStateLocked() {
1115         if (!mSystemReady || mDirty == 0) {                   //检查系统是否准备好了
1116             return;
1117         }                                                                                                                                 
1118
1119         // Phase 0: Basic state updates.                         //基本状态更新,检查是否插着充电器
1120         updateIsPoweredLocked(mDirty);
1121         updateStayOnLocked(mDirty);
1122
1123         // Phase 1: Update wakefulness.
1124         // Loop because the wake lock and user activity computations are influenced
1125         // by changes in wakefulness.
1126         final long now = SystemClock.uptimeMillis();
1127         int dirtyPhase2 = 0;
1128         for (;;) {
1129             int dirtyPhase1 = mDirty;
1130             dirtyPhase2 |= dirtyPhase1;
1131             mDirty = 0;
1132
1133             updateWakeLockSummaryLocked(dirtyPhase1);
1134             updateUserActivitySummaryLocked(now, dirtyPhase1);
1135             if (!updateWakefulnessLocked(dirtyPhase1)) {
1136                 break;
1137             }
1138         }
1139
1140         // Phase 2: Update dreams and display power state.                   //dream和display状态的更新
1141         updateDreamLocked(dirtyPhase2);
1142         updateDisplayPowerStateLocked(dirtyPhase2);
1143
1144         // Phase 3: Send notifications, if needed.                                    
1145         if (mDisplayReady) {
1146             sendPendingNotificationsLocked();
1147         }
1148
1149         // Phase 4: Update suspend blocker.                                              //suspend blocker的更新
1150         // Because we might release the last suspend blocker here, we need to make sure
1151         // we finished everything else first!
1152         updateSuspendBlockerLocked();                        //真正的执行者
1153     }

这段函数看得不仔细,大概可以看出来的都表明出来了,最后updateSuspendBlockerLocked是继续往下调用

1768     private void updateSuspendBlockerLocked() {
1769         boolean wantCpu = isCpuNeededLocked();
1770         if (wantCpu != mHoldingWakeLockSuspendBlocker) {
1771             mHoldingWakeLockSuspendBlocker = wantCpu;
1772             if (wantCpu) {
1773                 if (DEBUG) {
1774                     Slog.d(TAG, "updateSuspendBlockerLocked: Acquiring suspend blocker.");
1775                 }
1776                 mWakeLockSuspendBlocker.acquire();                                                                                        
1777             } else {
1778                 if (DEBUG) {
1779                     Slog.d(TAG, "updateSuspendBlockerLocked: Releasing suspend blocker.");
1780                 }
1781                 mWakeLockSuspendBlocker.release();
1782             }
1783         }
1784     }

其中的mWakeLockSuspendBlocker.acquire() 函数就是执行,加锁过程,
2579         public void acquire() {                                                                                                           
2580             synchronized (this) {
2581                 mReferenceCount += 1;
2582                 if (mReferenceCount == 1) {
2583                     nativeAcquireSuspendBlocker(mName);
2584                 }
2585             }
2586         }

这个时候调用的函数nativeAcquireSuspendBlocker就是JNI接口函数,函数位置在:
frameworks/base/services/jni/com_android_server_power_PowerManagerService.cpp,这个统一编译成libandroid_servers.so供FarmeWork使用,JNI真是个牛叉的玩意。
还没有结束呢,早着呢,系统刚刚走了一半的路,我们继续跟随:
JNI里面的实现
160 static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass clazz, jstring nameStr) {
161     ScopedUtfChars name(env, nameStr);
162     acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());                                                                                    
163 }

这个函数调用的acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str())是真正干活的吗?不是的,它调用了power.c中的acquire_wake_lock(),话说我看到这个函数,好熟悉啊,终于到了底层了,这个文件存在:
hardware/libhardware_legacy/power/power.c 这个文件会被编译成libpower.so。

现在我们再看看power.c中的acquire_wake_lock()实现,
 93 int
 94 acquire_wake_lock(int lock, const char* id)
 95 {
 96     initialize_fds();
 97
 98 //    ALOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id);
 99
100     if (g_error) return g_error;
101
102     int fd;                                                                                                                                
103
104     if (lock == PARTIAL_WAKE_LOCK) {
105         fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
106     }
107     else {
108         return EINVAL;
109     }
110
111     return write(fd, id, strlen(id));
112 }

^_^,没错,这个就是真正要往/sys/power/wake_lock 节点写值的函数了,走了这一大段路,终于走到了头?不是的,只能说上层已经把想要干什么活告诉了driver,现在要轮到driver干活了。

我们只是简单的分析了下,APP调用的过程,当然也有可能和系统别的模块交互,PowerManagerService不仅可以被动接受用户的操作请求,也可以主动的去监听一些重要的属性变化和重要的时间发生,在PowerManagerService主要注册这几个Reciver,看下
BatteryReceiver ACTION_BATTERY_CHANGED handleBatterStateChangeLocked()
BootCompleteReceiver ACTION_BOOT_COMPLETED startWatchingForBootAnimationFinished()
userSwitchReceiver ACTION_USER_SWITCHED handleSettingsChangedLocked
DockReceiver ACTION_DOCK_EVENT updatePowerStateLocked
DreamReceiver ACTION_DREAMING_STARTED
ACTION_DREAMING_STOPPED

scheduleSandmanLocked


不管什么接口调用最终都会是用以接口updatePowerStateLocked这个是不会变化的,因为对于JNI都是统一的,不管什么请求,都是调用JNI提供的标准接口



上面的图盗用网络。
下面一篇我介绍下学习的updatePowerStateLocked() 的这个函数

阅读(7396) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~