临时白名单介绍
相关常量
临时白名单列表介绍
前两个临时白名单可以豁免后台启动Service、豁免uid后台1min后进入idle状态等,最后一个临时白名单可以后台启动FGS。
// 由于高优先级消息而暂时允许逃避后台检查的一组应用程序 ID,短信/彩信
@CompositeRWLock({"this", "mProcLock"})
int[] mDeviceIdleTempAllowlist = new int[0];
// 暂时绕过省电模式的临时白名单,通知
@CompositeRWLock({"this", "mProcLock"})
final PendingTempAllowlists mPendingTempAllowlist = new PendingTempAllowlists(this);
// 允许从后台启动 FGS 的 临时白名单
@CompositeRWLock({"this", "mProcLock"})
final FgsTempAllowList<FgsTempAllowListItem> mFgsStartTempAllowList =
new FgsTempAllowList();
// 当FGS从后台启动时允许具有使用中权限的 uid 列表
private final FgsTempAllowList<String> mFgsWhileInUseTempAllowList =
new FgsTempAllowList();
临时白名单的Duration
// 当前应用在30s内启动过FGS
private static final int DEFAULT_SERVICE_START_FOREGROUND_TIMEOUT_MS = 30 * 1000;
// locale/timezone/boot/package等广播
private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 20 * 1000;
出于特定原因在短时间内将应用程序添加到临时允许列表。 临时允许列表与永久允许列表分开保存,应用程序会在预定时间后自动从临时允许列表中删除。
// 最大临时白名单豁免时间为5min
private static final long DEFAULT_MAX_TEMP_APP_ALLOWLIST_DURATION_MS = 5 * 60 * 1000L;
// 彩信60s
private static final long DEFAULT_MMS_TEMP_APP_ALLOWLIST_DURATION_MS = 60 * 1000L;
// 短信 20s
private static final long DEFAULT_SMS_TEMP_APP_ALLOWLIST_DURATION_MS = 20 * 1000L;
// 通知30s
private static final long DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS = 30 * 1000L;
临时白名单的reason code
/**
* The list of BG-FGS-Launch and temp-allow-list reason code.
* @hide
*/
@IntDef(flag = true, prefix = { "REASON_" }, value = {
......
// temp and system allow list reasons.
REASON_GEOFENCING,
REASON_PUSH_MESSAGING,
REASON_PUSH_MESSAGING_OVER_QUOTA,
REASON_ACTIVITY_RECOGNITION,
REASON_ACCOUNT_TRANSFER,
REASON_BOOT_COMPLETED,
REASON_PRE_BOOT_COMPLETED,
REASON_LOCKED_BOOT_COMPLETED,
REASON_BLUETOOTH_BROADCAST,
REASON_TIMEZONE_CHANGED,
REASON_TIME_CHANGED,
REASON_LOCALE_CHANGED,
REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
REASON_REFRESH_SAFETY_SOURCES,
REASON_SYSTEM_ALLOW_LISTED,
REASON_ALARM_MANAGER_ALARM_CLOCK,
REASON_ALARM_MANAGER_WHILE_IDLE,
REASON_SERVICE_LAUNCH,
REASON_KEY_CHAIN,
REASON_PACKAGE_VERIFIER,
REASON_SYNC_MANAGER,
REASON_DOMAIN_VERIFICATION_V1,
REASON_DOMAIN_VERIFICATION_V2,
REASON_VPN,
REASON_NOTIFICATION_SERVICE,
REASON_PACKAGE_REPLACED,
REASON_LOCATION_PROVIDER,
REASON_MEDIA_BUTTON,
REASON_EVENT_SMS, //
REASON_EVENT_MMS,
REASON_SHELL,
REASON_MEDIA_SESSION_CALLBACK,
REASON_ROLE_DIALER,
REASON_ROLE_EMERGENCY,
REASON_SYSTEM_MODULE,
REASON_CARRIER_PRIVILEGED_APP,
REASON_OPT_OUT_REQUESTED,
REASON_DPO_PROTECTED_APP,
REASON_DISALLOW_APPS_CONTROL,
REASON_ACTIVE_DEVICE_ADMIN,
REASON_MEDIA_NOTIFICATION_TRANSFER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ReasonCode {}
临时白名单之间关系
一般添加mPendingTempAllowlist或mDeviceIdleTempAllowlist白名单时也会根据type是否是TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED来添加mFgsStartTempAllowList白名单。
// 允许临时白名单行为,并允许前台服务从后台启动。
public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0;
mPendingTempAllowlist & mFgsStartTempAllowList
调用tempAllowlistUidLocked方法设置临时白名单时,会存在同时添加到mPendingTempAllowlist和 mFgsStartTempAllowList白名单的场景。
@GuardedBy("this")
void tempAllowlistUidLocked(int targetUid, long duration, @ReasonCode int reasonCode,
String reason, @TempAllowListType int type, int callingUid) {
synchronized (mProcLock) {
......
// 添加到临时Pending白名单中
mPendingTempAllowlist.put(targetUid,
new PendingTempAllowlist(targetUid, duration, reasonCode, reason, type,
callingUid));
// 设置当前uid的curAllowlist
setUidTempAllowlistStateLSP(targetUid, true);
mUiHandler.obtainMessage(PUSH_TEMP_ALLOWLIST_UI_MSG).sendToTarget();
// 添加到允许从后台启动 FGS 的 临时白名单
if (type == TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
mFgsStartTempAllowList.add(targetUid, duration,
new FgsTempAllowListItem(duration, reasonCode, reason, callingUid));
}
}
}
查找tempAllowlistUidLocked的调用地方如下,主要是三个场景:广播、Service、PendingIntent通知。
mDeviceIdleTempAllowlist & mFgsStartTempAllowList
添加TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED类型的白名单会触发mDeviceIdleTempAllowlist的更新。
@Override
public void updateDeviceIdleTempAllowlist(@Nullable int[] appids, int changingUid,
boolean adding, long durationMs, @TempAllowListType int type,
@ReasonCode int reasonCode, @Nullable String reason, int callingUid) {
synchronized (ActivityManagerService.this) {
synchronized (mProcLock) {
if (appids != null) {
// 更新device idle临时白名单
mDeviceIdleTempAllowlist = appids;
}
if (adding) {
if (type == TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED) {
// 更新后台启动FGS的临时白名单
mFgsStartTempAllowList.add(changingUid, durationMs,
new FgsTempAllowListItem(durationMs, reasonCode, reason,
callingUid));
}
} else {
mFgsStartTempAllowList.removeUid(changingUid);
}
// 设置当前uid的curAllowListed为true,避免uid处于idle状态
setAppIdTempAllowlistStateLSP(changingUid, adding);
}
}
}
调用场景涉及范围较大,暂不列出。
常见添加场景总结
加入原因 | 持续时间 | 原因Code |
---|---|---|
fg-service-launch | 30s | REASON_SERVICE_LAUNCH |
接收特殊广播 | 20s | REASON_LOCALE_CHANGED |
REASON_TIMEZONE_CHANGED | ||
REASON_TIME_CHANGED | ||
REASON_BOOT_COMPLETED | ||
REASON_PRE_BOOT_COMPLETED | ||
REASON_LOCKED_BOOT_COMPLETED | ||
REASON_PACKAGE_REPLACED | ||
REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED | ||
蓝牙 | 10s | REASON_BLUETOOTH_BROADCAST |
定位 | 10s | REASON_LOCATION_PROVIDER |
NotificationManagerService | 30s | REASON_NOTIFICATION_SERVICE |
地理围栏 | 30s | REASON_GEOFENCING |
推送app | 60s | REASON_PUSH_MESSAGING |
后台启动FGS的临时白名单
当前应用在30s内启动过FGS
if (r.fgRequired) {
// 30s,调用了如上面说的AMS的tempAllowlistUidLocked
mAm.tempAllowlistUidLocked(r.appInfo.uid,
mAm.mConstants.mServiceStartForegroundTimeoutMs, REASON_SERVICE_LAUNCH,
"fg-service-launch",
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
r.mRecentCallingUid);
}
应用收到系统的 PendingIntent 通知
用户对与您的应用程序相关的 UI 元素执行操作。 例如,他们可能会与气泡、通知、小部件或活动进行交互。
// temporarily allow apps to perform extra work when their pending intents are launched
if (notification.allPendingIntents != null) {
final int intentCount = notification.allPendingIntents.size();
if (intentCount > 0) {
// 30s
final long duration = LocalServices.getService(
DeviceIdleInternal.class).getNotificationAllowlistDuration();
for (int i = 0; i < intentCount; i++) {
PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
if (pendingIntent != null) {
// 设置duration
mAmi.setPendingIntentAllowlistDuration(pendingIntent.getTarget(),
ALLOWLIST_TOKEN, duration,
// FGS 启动
TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
REASON_NOTIFICATION_SERVICE,
"NotificationManagerService");
}
}
}
}
先设置Duration,然后在send时去设置临时白名单
// allowlistToken为target
// 这里的reason为NotificationManagerService
// reasonCode为REASON_NOTIFICATION_SERVICE
// type为TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED
// duration为30s
void setAllowlistDurationLocked(IBinder allowlistToken, long duration, int type,
@ReasonCode int reasonCode, @Nullable String reason) {
if (duration > 0) {
if (mAllowlistDuration == null) {
mAllowlistDuration = new ArrayMap<>();
}
mAllowlistDuration.put(allowlistToken,
new TempAllowListDuration(duration, type, reasonCode, reason));
} else if (mAllowlistDuration != null) {
mAllowlistDuration.remove(allowlistToken);
if (mAllowlistDuration.size() <= 0) {
mAllowlistDuration = null;
}
}
this.stringName = null;
}
PendingIntent发送时会通过校验,通知AMS设置临时白名单
public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken,
IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo,
String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) {
.......
synchronized (controller.mLock) {
......
// 如果在通知入队时已经设置了duration
if (mAllowlistDuration != null) {
duration = mAllowlistDuration.get(allowlistToken);
}
.......
}
......
try {
// 调用AMS接口tempAllowlistForPendingIntent设置临时白名单
if (duration != null) {
.......
controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid,
uid, duration.duration, duration.type, duration.reasonCode, tag.toString());
}
....
应用在广播接收器中接收特殊广播
设置一个持续时间,系统应在该持续时间内将应用程序临时放置在电池白名单中,在此广播被传送到它时,指定临时白名单类型。
以下列举的广播并不是全部,还有一些boot、alarm、media、package、bluetooth等广播没有一一列举出来,遇到具体问题再具体分析即可。
// 要求应用拥有以下三个权限中的其中一个:
@RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND})
public void setTemporaryAppAllowlist(long duration, @TempAllowListType int type,
@ReasonCode int reasonCode, @Nullable String reason) {
mTemporaryAppAllowlistDuration = duration;
mTemporaryAppAllowlistType = type;
mTemporaryAppAllowlistReasonCode = reasonCode;
mTemporaryAppAllowlistReason = reason;
if (!isTemporaryAppAllowlistSet()) {
resetTemporaryAppAllowlist();
}
}
void maybeScheduleTempAllowlistLocked(int uid, BroadcastRecord r,
@Nullable BroadcastOptions brOptions) {
if (brOptions == null || brOptions.getTemporaryAppAllowlistDuration() <= 0) {
return;
}
long duration = brOptions.getTemporaryAppAllowlistDuration();
final @TempAllowListType int type = brOptions.getTemporaryAppAllowlistType();
final @ReasonCode int reasonCode = brOptions.getTemporaryAppAllowlistReasonCode();
final String reason = brOptions.getTemporaryAppAllowlistReason();
.......
mService.tempAllowlistUidLocked(uid, duration, reasonCode, b.toString(), type,r.callingUid);
}
添加到临时白名单的时机:分发给app之前触发更新或添加
接收ACTION_LOCALE_CHANGED/ACTION_TIMEZONE_CHANGED/ACTION_TIME_CHANGED
您的应用在广播接收器中接收 ACTION_TIMEZONE_CHANGED、ACTION_TIME_CHANGED 或 ACTION_LOCALE_CHANGED 意图操作。
@Override
public void broadcastGlobalConfigurationChanged(int changes, boolean initLocale) {
synchronized (ActivityManagerService.this) {
......
if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
.......
final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
// 20s
bOptions.setTemporaryAppAllowlist(mInternal.getBootTimeTempAllowListDuration(),
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
PowerExemptionManager.REASON_LOCALE_CHANGED, "");
......
}
void setTimeZoneImpl(String tz) {
......
if (timeZoneWasChanged) {
.....
Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
.....
mOptsTimeBroadcast.setTemporaryAppAllowlist(
mActivityManagerInternal.getBootTimeTempAllowListDuration(),
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
PowerExemptionManager.REASON_TIMEZONE_CHANGED, "");
getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
null /* receiverPermission */, mOptsTimeBroadcast.toBundle());
}
}
Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
......
mOptsTimeBroadcast.setTemporaryAppAllowlist(
mActivityManagerInternal.getBootTimeTempAllowListDuration(),
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
PowerExemptionManager.REASON_TIME_CHANGED, "");
接收BOOT_COMPLETED/PACKAGE_REPLACED等广播
设备重启并在广播接收器中接收到 ACTION_BOOT_COMPLETED、ACTION_PRE_BOOT_COMPLETED、ACTION_LOCKED_BOOT_COMPLETED 或 ACTION_MY_PACKAGE_REPLACED 意图操作后。
final BroadcastOptions bOptions = getTemporaryAppAllowlistBroadcastOptions(
REASON_LOCKED_BOOT_COMPLETED);
public @NonNull BroadcastOptions getTemporaryAppAllowlistBroadcastOptions(
@PowerExemptionManager.ReasonCode int reasonCode) {
long duration = 10_000;
if (mAmInternal != null) {
duration = mAmInternal.getBootTimeTempAllowListDuration();
}
final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
bOptions.setTemporaryAppAllowlist(duration,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
reasonCode, "");
return bOptions;
}
// 10s
mPm.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null /*package*/, null /*extras*/, 0 /*flags*/,
packageName /*targetPackage*/,
null /*finishedReceiver*/, updateUserIds, instantUserIds,
null /*broadcastAllowList*/,
mBroadcastHelper.getTemporaryAppAllowlistBroadcastOptions(
REASON_PACKAGE_REPLACED).toBundle());
接收ACTION_BLE_STATE_CHANGED蓝牙广播
您的应用程序接收需要 BLUETOOTH_CONNECT 或 BLUETOOTH_SCAN 权限的蓝牙广播。
private void sendBleStateChanged(int prevState, int newState) {
......
// Send broadcast message to everyone else
Intent intent = new Intent(BluetoothAdapter.ACTION_BLE_STATE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL, null, getTempAllowlistBroadcastOptions());
}
static @NonNull Bundle getTempAllowlistBroadcastOptions() {
final long duration = 10_000;
final BroadcastOptions bOptions = BroadcastOptions.makeBasic();
bOptions.setTemporaryAppAllowlist(duration,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
PowerExemptionManager.REASON_BLUETOOTH_BROADCAST, "");
return bOptions.toBundle();
}
应用接收位置改变事件
@Override
public void deliverOnLocationChanged(LocationResult locationResult,
@Nullable IRemoteCallback onCompleteCallback)
throws PendingIntent.CanceledException {
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setDontSendToRestrictedApps(true);
// allows apps to start a fg service in response to a location PI
options.setTemporaryAppAllowlist(TEMPORARY_APP_ALLOWLIST_DURATION_MS,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
REASON_LOCATION_PROVIDER,
"");
Intent intent = new Intent().putExtra(KEY_LOCATION_CHANGED,
locationResult.getLastLocation());
......
PendingIntentSender.send(mPendingIntent, mContext, intent, callback,
options.toBundle());
}
应用收到与地理围栏事件
您的应用收到与地理围栏或活动识别转换相关的事件。
PowerExemptionManager powerEM = context.getSystemService(PowerExemptionManager.class);
powerEM.addToTemporaryAllowList(packageName, PowerExemptionManager.REASON_GEOFENCING, "", Const.TEMP_ALLOW_DURATION_MS);
void addPowerSaveTempAllowlistAppChecked(String packageName, long duration,
int userId, @ReasonCode int reasonCode, @Nullable String reason)
throws RemoteException {
......
final long token = Binder.clearCallingIdentity();
try {
@TempAllowListType int type = getTempAllowListType(reasonCode,
TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED);
if (type != TEMPORARY_ALLOW_LIST_TYPE_NONE) {
addPowerSaveTempAllowlistAppInternal(callingUid,
packageName, duration, type, userId, true, reasonCode, reason);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
应用是推送App
您的应用使用 Firebase 云消息传递接收高优先级消息。
mAmService.tempAllowlistUidLocked(record.getUid(),
PUSH_SERVICE_WHITELIST_TIMEOUT,
PowerExemptionManager.REASON_PUSH_MESSAGING,
"push-service-launch",
PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
callingUid);
…More
设备空闲临时白名单
短信/彩信
@UserHandleAware
@RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
public long addToTemporaryAllowListForEvent(@NonNull String packageName,
@ReasonCode int reasonCode, @Nullable String reason, @AllowListEvent int event) {
try {
switch (event) {
case EVENT_MMS:
return mService.addPowerSaveTempWhitelistAppForMms(
packageName, mContext.getUserId(), reasonCode, reason);
case EVENT_SMS:
return mService.addPowerSaveTempWhitelistAppForSms(
packageName, mContext.getUserId(), reasonCode, reason);
case EVENT_UNSPECIFIED:
default:
return mService.whitelistAppTemporarily(
packageName, mContext.getUserId(), reasonCode, reason);
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
主要是调用power相关的接口设置,具体设置流程如下时序图
地理围栏
具体调用见 应用收到与地理围栏事件
@UserHandleAware
@RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
public void addToTemporaryAllowList(@NonNull String packageName, @ReasonCode int reasonCode,
@Nullable String reason, long durationMs) {
try {
mService.addPowerSaveTempWhitelistApp(packageName, durationMs, mContext.getUserId(),
reasonCode, reason);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
当前Uid是否处于白名单
Uid是否处于白名单作用
uid是否处于白名单影响当前uid是否会被idle;idle的app会有后台Service限制。
// procState >= PROCESS_STATE_TRANSIENT_BACKGROUND 8
if (ActivityManager.isProcStateBackground(uidRec.getCurProcState())
&& !uidRec.isCurAllowListed()) {
// UID 现在在后台(不在临时许可名单上)。 它之前是否在前台(或在临时许可名单上)?
if (!ActivityManager.isProcStateBackground(uidRec.getSetProcState())
|| uidRec.isSetAllowListed()) {
// 这里传入的elapsedRealtime而不是uptimeMillis,谷歌代码曾出过问题,
uidRec.setLastBackgroundTime(nowElapsed);
if (!mService.mHandler.hasMessages(IDLE_UIDS_MSG)) {
// post 1min后的消息到handler中去执行idle操作
mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
mConstants.BACKGROUND_SETTLE_TIME);
}
}
if (uidRec.isIdle() && !uidRec.isSetIdle()) {
uidChange |= UidRecord.CHANGE_IDLE;
becameIdle.add(uidRec);
}
设置是否处于白名单
设置uid是否处于白名单有如下三处:
setAppIdTempAllowlistStateLSP
设置mDeviceIdleTempAllowlist名单的时候会更新当前uid的curAllowListed ,具体调用见mDeviceIdleTempAllowlist
@GuardedBy({"mService", "mProcLock"})
void setAppIdTempAllowlistStateLSP(int uid, boolean onAllowlist) {
boolean changed = false;
for (int i = mActiveUids.size() - 1; i >= 0; i--) {
final UidRecord uidRec = mActiveUids.valueAt(i);
if (uidRec.getUid() == uid && uidRec.isCurAllowListed() != onAllowlist) {
// 设置当前uid的curAllowListed,如果是加入白名单,这里为true
// 可用作判断当前uid的状态是否为idle
uidRec.setCurAllowListed(onAllowlist);
changed = true;
}
}
if (changed) {
updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
}
}
setUidTempAllowlistStateLSP
设置mPendingTempAllowlist白名单时也会设置当前uid的白名单属性为true;具体调用见 mPendingTempAllowlist
@GuardedBy({"mService", "mProcLock"})
void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) {
boolean changed = false;
final UidRecord uidRec = mActiveUids.get(uid);
if (uidRec != null && uidRec.isCurAllowListed() != onAllowlist) {
uidRec.setCurAllowListed(onAllowlist);
updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST);
}
}
addProcessNameLocked
同样如果创建添加进程的时候,当前uid存在于mDeviceIdleTempAllowlist或者mPendingTempAllowlist白名单中,直接设置当前uid的curAllowListed为true。
if (Arrays.binarySearch(mService.mDeviceIdleTempAllowlist,
UserHandle.getAppId(proc.uid)) >= 0
|| mService.mPendingTempAllowlist.indexOfKey(proc.uid) >= 0) {
uidRec.setCurAllowListed(true);
uidRec.setSetAllowListed(true);
}