上篇博客分析了Doze模式下WakeLock,这篇我们分析Alarm。
白名单
首先我们从白名单开始,在DeviceIdleController中会设置alarm的白名单。
public final class LocalService {
public void setDeviceIdleUserWhitelist(int[] appids) {
setDeviceIdleUserWhitelistImpl(appids);
}
}
最终就是设置到了mDeviceUserWhiteList中。
void setDeviceIdleUserWhitelistImpl(int[] appids) {
synchronized (mLock) {
mDeviceIdleUserWhitelist = appids;
}
}
然后我们再看AlarmMangerService设置Alarm的set函数中有如下代码,当uid不是应用的uid或者。在白名单中能找到该uid,会将flags或上FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED标志(这个标志就是应用白名单的象征)。
public void set(String callingPackage,
int type, long triggerAtTime, long windowLength, long interval, int flags,
PendingIntent operation, IAlarmListener directReceiver, String listenerTag,
WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) {
......
} else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
|| Arrays.binarySearch(mDeviceIdleUserWhitelist,
UserHandle.getAppId(callingUid)) >= 0)) {
flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
}
setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver,
listenerTag, flags, workSource, alarmClock, callingUid, callingPackage);
}
setIdleUntil函数激活Alarm的Doze模式
在DeviceIdleController中是调用了AlarmManager的setIdleUntil函数激活了AlarmManagerService的Doze模式
public void setIdleUntil(int type, long triggerAtMillis, String tag, OnAlarmListener listener,
Handler targetHandler) {
setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_IDLE_UNTIL, null,
listener, tag, targetHandler, null, null);
}
我们先再来看看set函数,这里面对Doze模式相关的flag做了很多处理
@Override
public void set(String callingPackage,
int type, long triggerAtTime, long windowLength, long interval, int flags,
PendingIntent operation, IAlarmListener directReceiver, String listenerTag,
WorkSource workSource, AlarmManager.AlarmClockInfo alarmClock) {
......
// No incoming callers can