最近好好学习看了看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() 的这个函数