admin管理员组文章数量:1577558
现象
项目中发现手机无法正常息屏,不管等多久,除非按电源键手动息屏。
原因
Android的唤醒机制漏洞导致,具体可以查看:
唤醒锁: 检测 Android* 应用中的 No-Sleep(无法进入睡眠)问题
https://software.intel/zh-cn/android/articles/wakelocks-detect-no-sleep-issues-in-android-applications
具体现象
Log现象
01 12:21:07.167700 2065 7178 D PowerManagerService: updateDisplayPowerStateLocked: mDisplayReady=true, policy=2, mWakefulness=1, mWakeLockSummary=0x1, mUserActivitySummary=0x2, mBootCompleted=true, mScreenBrightnessBoostInProgress=false
01-01 12:21:07.167757 2065 7178 D PowerManagerService: Acquiring suspend blocker “PowerManagerService.WakeLocks”.
01-01 12:21:07.167848 2065 7178 D PowerManagerNotifier: onWakeLockAcquired: flags=1, tag=”dexopt“, packageName=android, ownerUid=1000, ownerPid=2065, workSource=WorkSource{10075}
01-01 12:21:07.386959 2065 2191 D PowerManagerService: handleUserActivityTimeout
01-01 12:21:07.387092 2065 2191 D PowerManagerService: updateUserActivitySummaryLocked: mWakefulness=Awake, mUserActivitySummary=0x4, nextTimeout=-1 (1321308 ms ago)
// 发生异常时无法走入“Bed time…”函数
01-01 12:21:07.387126 2065 2191 D PowerManagerService: updateWakefulnessLocked: Bed time…
相关代码
frameworks/base/services/core/java/com/android/server/powe/PowerManagerService.java
/**
* Updates the wakefulness of the device.
*
* This is the function that decides whether the device should start dreaming
* based on the current wake locks and user activity state. It may modify mDirty
* if the wakefulness changes.
*
* Returns true if the wakefulness changed and we need to restart power state calculation.
*/
private boolean updateWakefulnessLocked(int dirty) {
boolean changed = false;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED1958 | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE1959 | DIRTY_DOCK_STATE)) != 0) {
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
}
final long time = SystemClock.uptimeMillis();
if (shouldNapAtBedTimeLocked()) {
changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
} else {
changed = goToSleepNoUpdateLocked(time,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
}
}
}
return changed;
}
分析
这个场景类似我们开着视频app看电影,视频类app工作时会持唤醒锁,保存屏幕长亮。
但是异常现象是空空的,怀疑唤醒锁被持有且没被释放。
这里可以查看关键字:“wakelock list dump: mLocks ”
10-10 09:21:46.917181 2065 2361 D PowerManagerService: wakelock list dump: mLocks.size=3:
10-10 09:21:46.917242 2065 2361 D PowerManagerService: No.0: FULL_WAKE_LOCK ‘ShareActivity’activated(flags=805306394, uid=10130, pid=10494) total=3573633ms)
10-10 09:21:46.917287 2065 2361 D PowerManagerService: No.1: PARTIAL_WAKE_LOCK ‘SCREEN_FROZEN’activated(flags=1, uid=1000, pid=2065) total=2319333ms)
10-10 09:21:46.917339 2065 2361 D PowerManagerService: No.2: PARTIAL_WAKE_LOCK ‘PhoneWindowManager.mPowerKeyWakeLock’activated(flags=1, uid=1000, pid=2065) total=188ms)
上述uid=1000为系统进程可以不看,关键看uid为第三方的日志信息
PowerManagerService: No.0: FULL_WAKE_LOCK ‘ShareActivity’activated(flags=805306394, uid=10130, pid=10494) total=3573633ms)
- FULL_WAKE_LOCK:表示保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯
FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
- 其中uid=10130,为pid=10494:茄子快传(com.lenovo.anyshare)
故上述可能是由于com.lenovo.anyshare出现没有即使释放FULL_WAKE_LOCK导致。
于是我们直接kill掉com.lenovo.anyshare进程,kill可以强制释放唤醒锁,结果机器正常息屏
故判定该问题由三方应用未正常释放唤醒锁导致,撞到了“No-Sleep”的问题了
目前android没有合理的解决方案,故目前只能依赖三方应用代码的健壮性。
其实外国大牛有给一些解决方案…
结语
本文经验贴,方便快速定位问题
版权声明:本文标题:【功耗异常】手机休眠时长已过仍无法息屏 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1727798888a1130595.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论