【功耗异常】手机休眠时长已过仍无法息屏

现象

项目中发现手机无法正常息屏,不管等多久,除非按电源键手动息屏。

原因

Android的唤醒机制漏洞导致,具体可以查看:
唤醒锁: 检测 Android* 应用中的 No-Sleep(无法进入睡眠)问题
https://software.intel.com/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)

  1. FULL_WAKE_LOCK:表示保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯
FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
  1. 其中uid=10130,为pid=10494:茄子快传(com.lenovo.anyshare)

故上述可能是由于com.lenovo.anyshare出现没有即使释放FULL_WAKE_LOCK导致。

于是我们直接kill掉com.lenovo.anyshare进程,kill可以强制释放唤醒锁,结果机器正常息屏
故判定该问题由三方应用未正常释放唤醒锁导致,撞到了“No-Sleep”的问题了

目前android没有合理的解决方案,故目前只能依赖三方应用代码的健壮性。
其实外国大牛有给一些解决方案…

结语

本文经验贴,方便快速定位问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值