修改系统行为,让屏幕超时后,不去休眠。
frameworks\base\services\core\java\com\android\server\power\PowerManagerService,电源管理类,屏蔽休眠在此方法中修改。关键函数如下
@VisibleForTesting
void setWakefulnessLocked(int wakefulness, int reason) {
if (mWakefulness != wakefulness) {
mWakefulness = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
if (mNotifier != null) {
mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
}
}
}
重点屏蔽调用这个函数的方法,即在调用这几个函数的方法开头处,如果不需要休眠,则直接返回false。
setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);//这个不用屏蔽
setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);
setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
比方说调用setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);方法的方法是reallyGoToSleepNoUpdateLocked(),则在方法开头处就根据情况直接返回,不去执行休眠方法。
// Done dozing, drop everything and go to sleep.
private boolean reallyGoToSleepNoUpdateLocked(long eventTime, int uid) {
if (DEBUG_SPEW) {
Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime
+ ", uid=" + uid);
}
if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
|| !mBootCompleted || !mSystemReady) {
return false;
}
// add by zzh @{
boolean needSleep = SystemProperties.getBoolean("persist.sys.powersave.open", true);
if (!needSleep) {
Log.i("zzh", "reallyGoToSleepNoUpdateLocked no need sleep");
return false;
}
// @}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallyGoToSleep");
try {
Slog.i(TAG, "Sleeping (uid " + uid +")...");
setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return true;
}
以上修改完成后,我们仍然可以知道屏幕什么时候超时,这样我们可以在超时后做一些自己的逻辑,比如通知app层,去做灭屏(只是单纯将屏幕亮度设为0)。屏幕超时后具体执行休眠代码的位置:
/**
* Handler for asynchronous operations performed by the power manager.
*/
private final class PowerManagerHandler extends Handler {
public PowerManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_USER_ACTIVITY_TIMEOUT:
// add by zzh @{
boolean needSleep = SystemProperties.getBoolean("persist.sys.powersave.open", true);
// @}
// condition and else block add by zzh
if (needSleep)
handleUserActivityTimeout();
else
sendTimeoutBroadcast();
break;
case MSG_SANDMAN:
handleSandman();
break;
case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
handleScreenBrightnessBoostTimeout();
break;
case MSG_CHECK_FOR_LONG_WAKELOCKS:
checkForLongWakeLocks();
break;
}
}
}
// add by zzh
public void sendTimeoutBroadcast() {
Log.i("xxx zzh", "sendTimeoutBroadcast execute");
mContext.sendBroadcast(new Intent("company.power.save.timout"));
}