PowerManager之UserActivity

本文深入探讨了在Android设备中,当屏幕亮度设置为15秒时,通过按下菜单键触发UserActivity事件的过程及影响。解释了screenOffTimeout、screenDimDuration和screenButtonLightDuration三个关键时间参数的作用,以及它们如何相互作用,导致屏幕从亮变暗直至关闭的流程。通过具体实例,直观展示了UserActivity事件触发后的屏幕变化过程。

1.何时发生UserActivity

如果我们在Settings中设置sleep时间为15s,那么15秒内如果没有任何操作,屏幕就会熄灭(当然,没有WakeLock未被释放是前提)。如果在这个时间内用户有操作:touch屏幕或者按下菜单键、返回键等,那么这时就会调用PowerManagerService的UserActivity方法,这样会重置那个timeout的时间。

这里有三个重要的时间,参考下图:


首先是screenOffTimeout,一般地,就是设置中的sleep时间,用户可选,有15s、30s、1min、2mins等。device admin和window manager可以override这个时间(PowerManager提供了相应的接口),但是override有要求:必须大于10s,并小于设置中的15s,否则是无意义的,如果这里override了,那么这个就是最终的结果,如果没有override,那么以setting中的为准。在我们后来的讨论中都假设用户选择了15s,而且没有override,所以screenOffTimeout=15s。

其次是screenDimDuration,它代表屏幕亮度处于dim的持续时间(屏幕的变化:bright--dim--off),它是0.2*15s=3s。如果用户在settings中设置的不是15s,而是1min,那么1min*0.2=12s,当大于7s时,取7s。

最后是screenButtonLightDuration,它代表button持续点亮的时间,是0.3*15s=4.5s,它也有最大值:8s。

好了,假设在屏幕点亮状态下,我按下了menu键会怎么样呢?会触发UserActivity,同时User activity event type是USER_ACTIVITY_EVENT_BUTTON,那么从按下menu键开始后,button处于点亮状态,screen处于bright首先button的背光持续4.5s点亮,之后熄灭,经过7.5s后screen由bright变为dim,持续3s后,screen off。



j


services/core/java/com/android/server/power/PowerManagerService.java @GuardedBy("mLock") private boolean userActivityNoUpdateLocked(final PowerGroup powerGroup, long eventTime, @PowerManager.UserActivityEvent int event, int flags, int uid) { final int groupId = powerGroup.getGroupId(); ... //判断事件时间是否合理,判断系统是否准备好了 if (eventTime < powerGroup.getLastSleepTimeLocked() || eventTime < powerGroup.getLastWakeTimeLocked() || !mSystemReady) { return false; } //#ifdef OPLUS_EXTENSION_HOOK //Xinyu.Cen@ANDROID.POWER, 2024/05/24, add for Feature 7084655 //Here define valid inject useractivityevent is (normal event + 100) int injectEvent = event - 100; if ((injectEvent >= PowerManager.USER_ACTIVITY_EVENT_OTHER) && (injectEvent <= PowerManager.USER_ACTIVITY_EVENT_DEVICE_STATE)) { return false; } //判断当前更新的是否是默认显示组 if (powerGroup.getGroupId() == Display.DEFAULT_DISPLAY_GROUP) { mPmsExt.onUserActivityNoUpdateLocked(isGloballyInteractiveInternal(), event, uid); } //#endif /* OPLUS_EXTENSION_HOOK */ Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity"); try { //mLastInteractivePowerHintTime为 上次耗电增强 的活动时间 if (eventTime > mLastInteractivePowerHintTime) { setPowerBoostInternal(Boost.INTERACTION, 0); mLastInteractivePowerHintTime = eventTime; } //向系统其他组件通知用户活动 //Notifier.onUserActivity里面发送的消息 // 最终会被Notifier.sendUserActivity方法处理 //sendUserActivity方法主要通知电话服务,IMS,PMS,屏幕朝下检测器, //屏幕变暗检测器 更新用户活动时间 mNotifier.onUserActivity(powerGroup.getGroupId(), event, uid); //更新用户活动时间,这个类主要检测用户注意力 是否在手机 mAttentionDetector.onUserActivity(eventTime, event); if (mScreenTimeoutOverridePolicy != null) { mScreenTimeoutOverridePolicy.onUserActivity(mWakeLockSummary, event); } //mUserInactiveOverrideFromWindowManager表示 //由WMS确认由其他方式 让设备处于活动 if (mUserInactiveOverrideFromWindowManager) { mUserInactiveOverrideFromWindowManager = false; mOverriddenTimeout = -1; } //获取PowerGroup的唤醒状态 final int wakefulness = powerGroup.getWakefulnessLocked(); /** * 如果当前是休眠状态,或者处于DOZE状态 * 此时用户活动无效,不在计算超时时间,直接返回 * 亮屏不会走 */ if (wakefulness == WAKEFULNESS_ASLEEP || wakefulness == WAKEFULNESS_DOZING || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) { return false; } /** * 更新当前用户电源状态的配置文件的活动时间 * ProfilePowerState的UserId为实际用户Id * 这里涉及到多用户系统, 它和appId,uid,userId三个数值有关,他们关系如下: * uid = userId * 100,000 + appId,0<appId<100,000 *大多数情况下userId = 0 一般1用户都没有启动多用户的功能 */ maybeUpdateForegroundProfileLastActivityLocked(eventTime); // 在亮屏流程中 这里flags 为0 就不会进来 (这里如果进去了 应该是说明 用户活动没有改变) if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) { if (eventTime > powerGroup.getLastUserActivityTimeNoChangeLightsLocked() && eventTime > powerGroup.getLastUserActivityTimeLocked()) { powerGroup.setLastUserActivityTimeNoChangeLightsLocked(eventTime, event); mDirty |= DIRTY_USER_ACTIVITY; if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) { mDirty |= DIRTY_QUIESCENT; } return true; } } else { if (eventTime > powerGroup.getLastUserActivityTimeLocked()) { //更新powerGroup用户最后一次活动时间 powerGroup.setLastUserActivityTimeLocked(eventTime, event); //增加标志位,表示 用户活动发生变化 mDirty |= DIRTY_USER_ACTIVITY; //如果event 是PowerManager.USER_ACTIVITY_EVENT_BUTTON // 标志位就增加 DIRTY_QUIESCENT 表示系统静止状态发生了改变 if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) { mDirty |= DIRTY_QUIESCENT; } //通知客制化更新用户活动 if (powerGroup.getGroupId() == Display.DEFAULT_DISPLAY_GROUP) { mPmsExt.userActivityNoUpdateChangeLightsLocked(); } //#endif /* OPLUS_EXTENSION_HOOK */ return true; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } return false; } 分析这段代码的主要功能是什么
09-13
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值