临时白名单

临时白名单介绍

相关常量

临时白名单列表介绍

前两个临时白名单可以豁免后台启动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());
            } 
          ....

应用在广播接收器中接收特殊广播

设置一个持续时间,系统应在该持续时间内将应用程序临时放置在电池白名单中,在此广播被传送到它时,指定临时白名单类型。

扫描二维码关注公众号,回复: 15059168 查看本文章

以下列举的广播并不是全部,还有一些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);
}

猜你喜欢

转载自blog.csdn.net/xiaoyantan/article/details/128529908