这篇博客我们分析下Power的持锁,从PowerManager到PowerManagerService再到hal分析。

一、PowerManager的持锁接口

我们先来看下PowerManager对应用提供的接口:

[cpp] view plaincopy
  1. public WakeLock newWakeLock(int levelAndFlags, String tag) {
  2. validateWakeLockParameters(levelAndFlags, tag);//验证wakelock的flag是否有效
  3. return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName());
  4. }

validateWakeLockParameters函数如下:主要对flag没有下面这些flag做过滤

[cpp] view plaincopy
  1. public static void validateWakeLockParameters(int levelAndFlags, String tag) {
  2. switch (levelAndFlags & WAKE_LOCK_LEVEL_MASK) {
  3. case PARTIAL_WAKE_LOCK://cpu锁
  4. case SCREEN_DIM_WAKE_LOCK://屏幕微亮,键盘暗
  5. case SCREEN_BRIGHT_WAKE_LOCK://屏幕亮,键盘暗
  6. case FULL_WAKE_LOCK://全亮
  7. case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
  8. case DOZE_WAKE_LOCK:
  9. case DRAW_WAKE_LOCK:
  10. break;
  11. default:
  12. throw new IllegalArgumentException("Must specify a valid wake lock level.");
  13. }
  14. if (tag == null) {
  15. throw new IllegalArgumentException("The tag must not be null.");
  16. }
  17. }

我们再看WakeLock类,先看下面两个持锁,第二个timeout的持锁,先持锁,然后发送一个延迟消息再解锁。

[cpp] view plaincopy
  1. public void acquire() {
  2. synchronized (mToken) {
  3. acquireLocked();
  4. }
  5. }
  6. public void acquire(long timeout) {
  7. synchronized (mToken) {
  8. acquireLocked();
  9. mHandler.postDelayed(mReleaser, timeout);
  10. }
  11. }
[cpp] view plaincopy
  1. private final Runnable mReleaser = new Runnable() {
  2. public void run() {
  3. release();
  4. }
  5. };

再来看acquireLocked,流程最后是调用了service的acquireWakeLock,但是有一个细节我们注意下,这里有一个mCount的计数。也就是没调用一次这个函数,都会对wakelock的mCount加1。

[cpp] view plaincopy
  1. private void acquireLocked() {
  2. if (!mRefCounted || mCount++ == 0) {
  3. // Do this even if the wake lock is already thought to be held (mHeld == true)
  4. // because non-reference counted wake locks are not always properly released.
  5. // For example, the keyguard's wake lock might be forcibly released by the
  6. // power manager without the keyguard knowing.  A subsequent call to acquire
  7. // should immediately acquire the wake lock once again despite never having
  8. // been explicitly released by the keyguard.
  9. mHandler.removeCallbacks(mReleaser);
  10. Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
  11. try {
  12. mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
  13. mHistoryTag);
  14. } catch (RemoteException e) {
  15. }
  16. mHeld = true;
  17. }
  18. }

我们再来看看release函数,上面说的mCount计数,这里就会对这个计数进行判断,只有当计数为0,才会去调用service的releaseWakeLock函数。

[cpp] view plaincopy
  1. public void release(int flags) {
  2. synchronized (mToken) {
  3. if (!mRefCounted || --mCount == 0) {
  4. mHandler.removeCallbacks(mReleaser);
  5. if (mHeld) {
  6. Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
  7. try {
  8. mService.releaseWakeLock(mToken, flags);
  9. } catch (RemoteException e) {
  10. }
  11. mHeld = false;
  12. }
  13. }
  14. if (mCount < 0) {
  15. throw new RuntimeException("WakeLock under-locked " + mTag);
  16. }
  17. }
  18. }

所以我们总结下,使用PowerManager的wakelock持锁和释放锁。必须成对出现,当持了2次锁,也必须释放两次锁。才会调用service的释放锁,去真正释放。

二、PowerManagerService相关接口

Service的acquireWakeLock函数我们就不看了,主要是对wakelock的flag做验证,然后调用了acquireWakeLockInternal函数:

[cpp] view plaincopy
  1. private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
  2. WorkSource ws, String historyTag, int uid, int pid) {
  3. synchronized (mLock) {
  4. WakeLock wakeLock;
  5. int index = findWakeLockIndexLocked(lock);//查找wakelock,IBinder对象为wakelock唯一性
  6. boolean notifyAcquire;
  7. if (index >= 0) {
  8. wakeLock = mWakeLocks.get(index);
  9. if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
  10. // Update existing wake lock.  This shouldn't happen but is harmless.
  11. notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,
  12. uid, pid, ws, historyTag);
  13. wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);//更新参数
  14. }
  15. notifyAcquire = false;
  16. } else {
  17. wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);//新建
  18. try {
  19. lock.linkToDeath(wakeLock, 0);
  20. } catch (RemoteException ex) {
  21. throw new IllegalArgumentException("Wake lock is already dead.");
  22. }
  23. mWakeLocks.add(wakeLock);
  24. setWakeLockDisabledStateLocked(wakeLock);
  25. notifyAcquire = true;
  26. }
  27. applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);//看是否需要唤醒设备
  28. mDirty |= DIRTY_WAKE_LOCKS;
  29. updatePowerStateLocked();// 更新电源状态
  30. if (notifyAcquire) {
  31. notifyWakeLockAcquiredLocked(wakeLock);
  32. }
  33. }
  34. }

updatePowerStateLocked函数我们放在后面说,我们再来看看applyWakeLockFlagsOnAcquireLocked函数:

[cpp] view plaincopy
  1. private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) {
  2. if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0//wakelock中的flag有这个flag就需要唤醒设备
  3. && isScreenLock(wakeLock)) {
  4. String opPackageName;
  5. int opUid;
  6. if (wakeLock.mWorkSource != null && wakeLock.mWorkSource.getName(0) != null) {
  7. opPackageName = wakeLock.mWorkSource.getName(0);
  8. opUid = wakeLock.mWorkSource.get(0);
  9. } else {
  10. opPackageName = wakeLock.mPackageName;
  11. opUid = wakeLock.mWorkSource != null ? wakeLock.mWorkSource.get(0)
  12. : wakeLock.mOwnerUid;
  13. }
  14. wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), wakeLock.mTag, opUid,
  15. opPackageName, opUid);
  16. }
  17. }

同样release,我们也直接分析releaseWakeLockInternal函数:

[cpp] view plaincopy
  1. private void releaseWakeLockInternal(IBinder lock, int flags) {
  2. synchronized (mLock) {
  3. int index = findWakeLockIndexLocked(lock);//找wakelock
  4. if (index < 0) {
  5. if (DEBUG_LC) {
  6. Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
  7. + " [not found], flags=0x" + Integer.toHexString(flags));
  8. }
  9. return;
  10. }
  11. WakeLock wakeLock = mWakeLocks.get(index);
  12. if (DEBUG_LC) {
  13. Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock)
  14. + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
  15. }
  16. if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {//距离传感器相关
  17. mRequestWaitForNegativeProximity = true;
  18. }
  19. wakeLock.mLock.unlinkToDeath(wakeLock, 0);
  20. removeWakeLockLocked(wakeLock, index);
  21. }
  22. }

removeWakeLockLocked函数,去除wakelock,最后调用updatePowerStateLocked

[cpp] view plaincopy
  1. private void removeWakeLockLocked(WakeLock wakeLock, int index) {
  2. mWakeLocks.remove(index);//去除wakelock
  3. notifyWakeLockReleasedLocked(wakeLock);
  4. applyWakeLockFlagsOnReleaseLocked(wakeLock);//是否触发userActivity
  5. mDirty |= DIRTY_WAKE_LOCKS;
  6. updatePowerStateLocked();
  7. }

applyWakeLockFlagsOnReleaseLocked函数:

[cpp] view plaincopy
  1. private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) {
  2. if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0//有这个flag触发userActivity
  3. && isScreenLock(wakeLock)) {
  4. userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
  5. PowerManager.USER_ACTIVITY_EVENT_OTHER,
  6. PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS,
  7. wakeLock.mOwnerUid);
  8. }
  9. }

下面我们就来看看之前acquire和realease都调用的函数updatePowerStateLocked:

[cpp] view plaincopy
  1. private void updatePowerStateLocked() {
  2. if (!mSystemReady || mDirty == 0) {
  3. return;
  4. }
  5. if (!Thread.holdsLock(mLock)) {
  6. Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
  7. }
  8. Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
  9. try {
  10. // Phase 0: Basic state updates.
  11. updateIsPoweredLocked(mDirty);
  12. updateStayOnLocked(mDirty);
  13. updateScreenBrightnessBoostLocked(mDirty);
  14. // Phase 1: Update wakefulness.
  15. // Loop because the wake lock and user activity computations are influenced
  16. // by changes in wakefulness.
  17. final long now = SystemClock.uptimeMillis();
  18. int dirtyPhase2 = 0;
  19. for (;;) {
  20. int dirtyPhase1 = mDirty;
  21. dirtyPhase2 |= dirtyPhase1;
  22. mDirty = 0;
  23. updateWakeLockSummaryLocked(dirtyPhase1);
  24. updateUserActivitySummaryLocked(now, dirtyPhase1);
  25. if (!updateWakefulnessLocked(dirtyPhase1)) {
  26. break;
  27. }
  28. }
  29. // Phase 2: Update display power state.
  30. boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
  31. // Phase 3: Update dream state (depends on display ready signal).
  32. updateDreamLocked(dirtyPhase2, displayBecameReady);
  33. // Phase 4: Send notifications, if needed.
  34. finishWakefulnessChangeIfNeededLocked();
  35. // Phase 5: Update suspend blocker.
  36. // Because we might release the last suspend blocker here, we need to make sure
  37. // we finished everything else first!
  38. updateSuspendBlockerLocked();
  39. } finally {
  40. Trace.traceEnd(Trace.TRACE_TAG_POWER);
  41. }
  42. }

其实这个函数我们先看下updateWakeLockSummaryLocked函数,根据wakelock来指定mWakeLockSummary

[cpp] view plaincopy
  1. private void updateWakeLockSummaryLocked(int dirty) {
  2. if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS)) != 0) {
  3. mWakeLockSummary = 0;
  4. final int numWakeLocks = mWakeLocks.size();
  5. for (int i = 0; i < numWakeLocks; i++) {
  6. final WakeLock wakeLock = mWakeLocks.get(i);
  7. switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
  8. case PowerManager.PARTIAL_WAKE_LOCK:
  9. if (!wakeLock.mDisabled) {
  10. // We only respect this if the wake lock is not disabled.
  11. mWakeLockSummary |= WAKE_LOCK_CPU;//持cpu锁
  12. }
  13. break;
  14. case PowerManager.FULL_WAKE_LOCK:
  15. mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;
  16. break;
  17. case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
  18. mWakeLockSummary |= WAKE_LOCK_SCREEN_BRIGHT;
  19. break;
  20. case PowerManager.SCREEN_DIM_WAKE_LOCK:
  21. mWakeLockSummary |= WAKE_LOCK_SCREEN_DIM;
  22. break;
  23. case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
  24. mWakeLockSummary |= WAKE_LOCK_PROXIMITY_SCREEN_OFF;
  25. break;
  26. case PowerManager.DOZE_WAKE_LOCK:
  27. mWakeLockSummary |= WAKE_LOCK_DOZE;
  28. break;
  29. case PowerManager.DRAW_WAKE_LOCK:
  30. mWakeLockSummary |= WAKE_LOCK_DRAW;
  31. break;
  32. }
  33. }
  34. // Cancel wake locks that make no sense based on the current state.
  35. if (mWakefulness != WAKEFULNESS_DOZING) {
  36. mWakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
  37. }
  38. if (mWakefulness == WAKEFULNESS_ASLEEP
  39. || (mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
  40. mWakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
  41. | WAKE_LOCK_BUTTON_BRIGHT);
  42. if (mWakefulness == WAKEFULNESS_ASLEEP) {
  43. mWakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
  44. }
  45. }
  46. // Infer implied wake locks where necessary based on the current state.
  47. if ((mWakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
  48. if (mWakefulness == WAKEFULNESS_AWAKE) {
  49. mWakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
  50. } else if (mWakefulness == WAKEFULNESS_DREAMING) {
  51. mWakeLockSummary |= WAKE_LOCK_CPU;
  52. }
  53. }
  54. if ((mWakeLockSummary & WAKE_LOCK_DRAW) != 0) {
  55. mWakeLockSummary |= WAKE_LOCK_CPU;
  56. }
  57. if (DEBUG_SPEW) {
  58. Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
  59. + PowerManagerInternal.wakefulnessToString(mWakefulness)
  60. + ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
  61. }
  62. }
  63. }

最后我们主要看下updateSuspendBlockerLocked这个函数:

[cpp] view plaincopy
  1. private void updateSuspendBlockerLocked() {
  2. final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);//是否需要持锁
  3. final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
  4. final boolean autoSuspend = !needDisplaySuspendBlocker;
  5. final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
  6. // Disable auto-suspend if needed.
  7. // FIXME We should consider just leaving auto-suspend enabled forever since
  8. // we already hold the necessary wakelocks.
  9. if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {//配置是否需要自动持锁开启
  10. setHalAutoSuspendModeLocked(false);
  11. }
  12. // First acquire suspend blockers if needed.
  13. if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
  14. mWakeLockSuspendBlocker.acquire();//wakelock持锁
  15. mHoldingWakeLockSuspendBlocker = true;
  16. }
  17. if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
  18. mDisplaySuspendBlocker.acquire();//Display持锁
  19. mHoldingDisplaySuspendBlocker = true;
  20. }
  21. ......
  22. // Then release suspend blockers if needed.
  23. if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
  24. mWakeLockSuspendBlocker.release();//wakelock锁释放
  25. mHoldingWakeLockSuspendBlocker = false;
  26. }
  27. if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
  28. mDisplaySuspendBlocker.release();//Display锁释放
  29. mHoldingDisplaySuspendBlocker = false;
  30. }
  31. // Enable auto-suspend if needed.
  32. if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {//配置设置&&可以自动持锁
  33. setHalAutoSuspendModeLocked(true);//自动持锁开启
  34. }
  35. }

先来看看needDisPlaySuspendBlockerLocked函数,是否将Display锁释放

[cpp] view plaincopy
  1. private boolean needDisplaySuspendBlockerLocked() {
  2. if (!mDisplayReady) {
  3. return true;//需要持锁
  4. }
  5. if (mDisplayPowerRequest.isBrightOrDim()) {
  6. // If we asked for the screen to be on but it is off due to the proximity
  7. // sensor then we may suspend but only if the configuration allows it.
  8. // On some hardware it may not be safe to suspend because the proximity
  9. // sensor may not be correctly configured as a wake-up source.
  10. if (!mDisplayPowerRequest.useProximitySensor || !mProximityPositive
  11. || !mSuspendWhenScreenOffDueToProximityConfig) {
  12. return true;
  13. }
  14. }
  15. if (mScreenBrightnessBoostInProgress) {
  16. return true;
  17. }
  18. // Let the system suspend if the screen is off or dozing.
  19. return false;
  20. }

这里有两个锁Display和WakeLocks锁,但是这两个锁和之前PowerManager的锁意义不一样,这两个锁是针对hal层的是真正的锁。我们来看下这两个锁。

在PowerManagerService的构造函数中就创建了这两个锁。

[cpp] view plaincopy
  1. mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
  2. mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");

createSuspendBlockerLocked函数就是新建SuspendBlockerImpl对象:

[cpp] view plaincopy
  1. private SuspendBlocker createSuspendBlockerLocked(String name) {
  2. SuspendBlocker suspendBlocker = new SuspendBlockerImpl(name);
  3. mSuspendBlockers.add(suspendBlocker);
  4. return suspendBlocker;
  5. }

再来看看SuspendBlockerImpl 类:

[cpp] view plaincopy
  1. private final class SuspendBlockerImpl implements SuspendBlocker {
  2. private final String mName;
  3. private final String mTraceName;
  4. private int mReferenceCount;
  5. public SuspendBlockerImpl(String name) {
  6. mName = name;
  7. mTraceName = "SuspendBlocker (" + name + ")";
  8. }
  9. @Override
  10. protected void finalize() throws Throwable {
  11. try {
  12. if (mReferenceCount != 0) {
  13. Slog.wtf(TAG, "Suspend blocker \"" + mName
  14. + "\" was finalized without being released!");
  15. mReferenceCount = 0;
  16. nativeReleaseSuspendBlocker(mName);
  17. Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
  18. }
  19. } finally {
  20. super.finalize();
  21. }
  22. }
  23. @Override
  24. public void acquire() {
  25. synchronized (this) {
  26. mReferenceCount += 1;
  27. if (mReferenceCount == 1) {//这里也使用了计数
  28. if (DEBUG_SPEW) {
  29. Slog.d(TAG, "Acquiring suspend blocker \"" + mName + "\".");
  30. }
  31. Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
  32. nativeAcquireSuspendBlocker(mName);//持锁调用hal层函数
  33. }
  34. }
  35. }
  36. @Override
  37. public void release() {
  38. synchronized (this) {
  39. mReferenceCount -= 1;
  40. if (mReferenceCount == 0) {//使用计数
  41. if (DEBUG_SPEW) {
  42. Slog.d(TAG, "Releasing suspend blocker \"" + mName + "\".");
  43. }
  44. nativeReleaseSuspendBlocker(mName);//释放锁调用hal层
  45. Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
  46. } else if (mReferenceCount < 0) {
  47. Slog.wtf(TAG, "Suspend blocker \"" + mName
  48. + "\" was released without being acquired!", new Throwable());
  49. mReferenceCount = 0;
  50. }
  51. }
  52. }

三、hal层持锁相关函数

hal层的持锁和释放锁的函数如下,在com_android_server_power_PowerManagerService.cpp文件

[cpp] view plaincopy
  1. static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
  2. ScopedUtfChars name(env, nameStr);
  3. acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
  4. }
  5. static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
  6. ScopedUtfChars name(env, nameStr);
  7. release_wake_lock(name.c_str());
  8. }

我们再看看power.c的代码,在hardware目录下。先来看持锁:

[cpp] view plaincopy
  1. int
  2. acquire_wake_lock(int lock, const char* id)
  3. {
  4. initialize_fds();
  5. if (g_error) return g_error;
  6. int fd;
  7. if (lock == PARTIAL_WAKE_LOCK) {
  8. fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];
  9. }
  10. else {
  11. return EINVAL;
  12. }
  13. return write(fd, id, strlen(id));
  14. }

先来看initialize_fds函数,调用open_file_descriptors函数:

[cpp] view plaincopy
  1. static inline void
  2. initialize_fds(void)
  3. {
  4. if (g_initialized == 0) {
  5. if(open_file_descriptors(NEW_PATHS) < 0)
  6. open_file_descriptors(OLD_PATHS);
  7. g_initialized = 1;
  8. }
  9. }

我们先来看看NEW_PATHS

[cpp] view plaincopy
  1. const char * const NEW_PATHS[] = {
  2. "/sys/power/wake_lock",
  3. "/sys/power/wake_unlock",
  4. };

再来看看open_file_descriptors函数:

[cpp] view plaincopy
  1. static int
  2. open_file_descriptors(const char * const paths[])
  3. {
  4. int i;
  5. for (i=0; i<OUR_FD_COUNT; i++) {
  6. int fd = open(paths[i], O_RDWR | O_CLOEXEC);
  7. if (fd < 0) {
  8. fprintf(stderr, "fatal error opening \"%s\"\n", paths[i]);
  9. g_error = errno;
  10. return -1;
  11. }
  12. g_fds[i] = fd;//填充g_fds,一个是wake_lock另一个是wake_unlock
  13. }
  14. g_error = 0;
  15. return 0;
  16. }

现在再来看看这两个函数

[cpp] view plaincopy
  1. int
  2. acquire_wake_lock(int lock, const char* id)
  3. {
  4. initialize_fds();
  5. if (g_error) return g_error;
  6. int fd;
  7. if (lock == PARTIAL_WAKE_LOCK) {
  8. fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];//获取wake_lock的fd
  9. }
  10. else {
  11. return EINVAL;
  12. }
  13. return write(fd, id, strlen(id));//往里面写值
  14. }
  15. int
  16. release_wake_lock(const char* id)
  17. {
  18. initialize_fds();
  19. if (g_error) return g_error;
  20. ssize_t len = write(g_fds[RELEASE_WAKE_LOCK], id, strlen(id));//获取wake_unlock的fd,往里面写值
  21. return len >= 0;
  22. }

这样看上层PowerManager的两个锁是否存在我们可以查看/sys/power/wake_lock和/sys/power/wake_unlock这两个目录。

[html] view plaincopy
  1. root@lte26007:/sys/power # cat wake_lock
  2. PowerManagerService.Display PowerManagerService.WakeLocks
[html] view plaincopy
  1. root@lte26007:/sys/power # cat wake_unlock
  2. KeyEvents radio-interface

如果灭屏了,Display锁会释放

[html] view plaincopy
  1. root@lte26007:/sys/power # cat wake_unlock
  2. KeyEvents PowerManagerService.Broadcasts PowerManagerService.Display radio-interface

autosuspend我们这里也就不讲了。

四、总结

这篇博客我们主要分析了从PowerManager的持锁,然后到PowerManagerService的一些逻辑处理。最后由PowerManagerService调用hal层真正的锁来让cpu保持工作。

原文地址: http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/kc58236582/article/details/51564328

Android6.0 wakelock深入分析相关推荐

  1. android adbd分析,android6.0 adbd深入分析(三)adb root重启adbd流程

    上篇博客中分析过adb root pc到adbd的流程,这篇博客我们再来讲下adb root是adbd重启并且获取root的流程.我们再来回顾之前的函数: void restart_root_serv ...

  2. 零死角玩转Android6.0系统Healthd深入分析

    零死角玩转Android6.0系统Healthd深入分析 概述 Healthd是android4.4之后提出来的一种中介模型,该模型向下监听来自底层的电池事件,向上传递电池数据信息给Framework ...

  3. (原创)android6.0系统 PowerManager深入分析

    概述 一直以来,电源管理是电子产品设计中非常重要的环节,也是任何电子设备中最为重要的系统模块之一,优秀的电源管理方案,能够提供持久的续航能力,良好的用户体验,更能提升电子产品的竞争力. 移动设备的电量 ...

  4. (原创)android6.0系统 PowerManager深入分析(很具体)

    概述 一直以来,电源管理是电子产品设计中很重要的环节.也是不论什么电子设备中最为重要的系统模块之中的一个,优秀的电源管理方案.可以提供持久的续航能力,良好的用户体验.更能提升电子产品的竞争力. 移动设 ...

  5. Android6.0的SMS(短信)源码分析--短信接收

    1     SMS接收流程 Android6.0中对短信的处理比起老版本还是变化有点大的.在分析源代码之前,我们可以先猜测一下Android中接收短信的大致流程.首先根据之前分析phone应用的经验, ...

  6. android6.0中app crash流程分析

    要根据这个流程分析一下如何在应用中截获系统的app crash弹框,然后做到更人性化 基于Android 6.0的源码剖析, 分析Android应用Crash是如何处理的. /frameworks/b ...

  7. android 蓝牙找不到电脑,Android6.0 蓝牙搜索不到设备原因

    原因: 为提供更高的数据保护 Android6.0版本上增加了关于Wifi和蓝牙的权限,以下是官方文档说明: 图1 修改方法: 在AndroidManifest 中添加权限 或者 注意 如果targe ...

  8. 编译可在Nexus5上运行的CyanogenMod13.0 ROM(基于Android6.0)

    编译可在Nexus5上运行的CyanogenMod13.0 ROM (基于Android6.0) 作者:寻禹@阿里聚安全 前言 下文中无特殊说明时CM代表CyanogenMod的缩写. 下文中说的&q ...

  9. android6.0麦克风权限,android 6.0权限检测以及6.0以下,麦克风、相机权限判断

    android 6.0以上权限 android 6.0以上权限,我是通过PermissionsDispatcher进行申请,操作的,具体使用方法,见PermissionsDispatcher,Andr ...

最新文章

  1. php和python哪个学起来简单一点-Php和python php和python哪个容易学
  2. usaco The Castle(flood fill)
  3. Linux备份压缩命令
  4. PAT1053 住房空置率 (20 分)
  5. hibernate session的load和get方法
  6. window.atob()与window.btoa()方法实现编码与解码
  7. 如何使WordPress博客添加多个sidebar侧边栏
  8. linux 对象 调出r_[转载]linux系统下安装R包
  9. java.lang.IllegalStateException: Unable to read meta-data for class 问题的解决
  10. java CPU 占用过高
  11. 2018,人生是一条蛇,它咬着自己的尾巴
  12. 电子墨水+android+平板,请推荐一款电子墨水屏的安卓平板
  13. linux huge模式设置,Linux HugePages 配置步骤
  14. sCrypt 合约中的椭圆曲线算法:第二部分
  15. 贸易合规服务市场现状研究分析报告 -
  16. iOS关闭键盘的两种简单方法
  17. 2020-08《信息资源管理 02378》真卷(独家文字版),圈定章节考点+统计真题分布
  18. Educoder Java高级特性 - JDBC(上)
  19. 福昕阅读器文档无法高亮的问题
  20. JAVA8 Stream的系列操作,Optional使用---- java养成

热门文章

  1. Visual C# 2008+SQL Server 2005 数据库与网络开发--9.1.1 SQL Server 2005中的XML功能
  2. Python学习笔记:TypeError: not all arguments converted during string formatting
  3. Python学习笔记:基础
  4. Sublime Text
  5. 安装CCS5时仿真驱动出现问题的解决方法
  6. 视频分类/动作识别数据库研究现状
  7. 科大星云诗社动态20210410
  8. 科大星云诗社动态20210427
  9. 科大星云诗社动态20210819
  10. 科大星云诗社动态20201122