android13#settings#reset2

53 阅读21分钟

1.简介

上篇主要学习了reset相关的ui,这篇详细学习下3种reset都清除了哪些数据

1.1.reset network

上篇小节3,最终跳转到ResetNetworkConfirm页面处理

  • 相关代码见小节2和3

1.2.reset app preference

上篇2.4

  • 相关代码见小节4到12

image.png

1.3.factory reset

见上篇5.3,最终跳转页面MainClearConfirm,功能代码也在上篇小节10到12分析了,基本交给底层 c库处理了。

2.ResetNetworkConfirm.java

2.1.startMonitorSubscriptionChange

onCreate里会调用,监听sim卡的状态变化

    private void startMonitorSubscriptionChange(SubscriptionManager mgr) {
        if (mgr == null) {
            return;
        }
        // update monitor listener
        mSubscriptionsChangedListener = new OnSubscriptionsChangedListener(
                Looper.getMainLooper()) {
            @Override
            public void onSubscriptionsChanged() {
                //先获取我们要reset的sim的相关id
                int subId = mResetNetworkRequest.getResetApnSubId();
                SubscriptionManager mgr = getSubscriptionManager();
                if (isSubscriptionRemainActive(mgr, subId)) {
                //sim卡依旧是活动的
                    return;
                }
               //要reset的sim已经不再活动了,那么停止监听,关闭页面
                stopMonitorSubscriptionChange(mgr);
                mActivity.finish();
            }
        };
        mgr.addOnSubscriptionsChangedListener(
                mActivity.getMainExecutor(), mSubscriptionsChangedListener);
    }

2.1.onClick

        public void onClick(View v) {

            // abandon execution if subscription no longer active
            int subId = mResetNetworkRequest.getResetApnSubId();
            if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                说明有选中的sim卡
                SubscriptionManager mgr = getSubscriptionManager();
                
                stopMonitorSubscriptionChange(mgr);
                if (!isSubscriptionRemainActive(mgr, subId)) {
                //sim卡已经不活动了,关闭页面
                    mActivity.finish();
                    return;
                }
            }

            //显示loading
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }

            mProgressDialog = getProgressDialog(mActivity);
            mProgressDialog.show();
            //开始reset操作,具体见2.3
            mResetNetworkTask = new ResetNetworkTask(mActivity);
            mResetNetworkTask.execute();
        }

2.3.doInBackground

        mResetNetworkRequest = new ResetNetworkRequest(args);
        
        protected Boolean doInBackground(Void... params) {
            final AtomicBoolean resetEsimSuccess = new AtomicBoolean(true);

            String resetEsimPackageName = mResetNetworkRequest.getResetEsimPackageName();
            //转换成builder,见3.1
            ResetNetworkOperationBuilder builder = mResetNetworkRequest
                    .toResetNetworkOperationBuilder(mContext, Looper.getMainLooper());
            if (resetEsimPackageName != null) {
                //有虚拟sim卡的话,添加对应的任务
                builder = builder.resetEsim(resetEsimPackageName,
                        success -> { resetEsimSuccess.set(success); }
                        );
            }
            //开始执行所有的任务,见3.3
            builder.build().run();

            boolean isResetSucceed = resetEsimSuccess.get();
            return isResetSucceed;
        }

3.ResetNetworkOperationBuilder.java

3.1.ResetNetworkRequest.java

根据请求的option,添加对应的任务,具体任务见3.4到3.10

    public ResetNetworkOperationBuilder toResetNetworkOperationBuilder(Context context,
            Looper looper) {
        // Follow specific order based on previous design within file ResetNetworkConfirm.java
        ResetNetworkOperationBuilder builder = new ResetNetworkOperationBuilder(context);
        if ((mResetOptions & RESET_CONNECTIVITY_MANAGER) != 0) {
            builder.resetConnectivityManager();
        }
        if ((mResetOptions & RESET_VPN_MANAGER) != 0) {
            builder.resetVpnManager();
        }
        if ((mResetOptions & RESET_WIFI_MANAGER) != 0) {
            builder.resetWifiManager();
        }
        if ((mResetOptions & RESET_WIFI_P2P_MANAGER) != 0) {
            builder.resetWifiP2pManager(looper);
        }
        if (mResetEsimPackageName != null) {
            builder.resetEsim(mResetEsimPackageName);
        }
        if (mResetTelephonyManager != INVALID_SUBSCRIPTION_ID) {
            builder.resetTelephonyAndNetworkPolicyManager(mResetTelephonyManager);
        }
        if ((mResetOptions & RESET_BLUETOOTH_MANAGER) != 0) {
            builder.resetBluetoothManager();
        }
        if (mResetApn != INVALID_SUBSCRIPTION_ID) {
            builder.resetApn(mResetApn);
        }
        return builder;
    }

3.2.attachSystemServiceWork

根据服务名字,获取对应的系统服务,然后传递给第二个参数,并把runnable加入集合

    protected <T> void attachSystemServiceWork(String serviceName, Consumer<T> serviceAccess) {
        T service = (T) mContext.getSystemService(serviceName);
        if (service == null) {
            return;
        }
        Runnable runnable = () -> {
            if (!DRY_RUN) {
                serviceAccess.accept(service);
            }
        };
        //加入集合
        mResetSequence.add(runnable);
    }

3.3.build

返回一个runnable,里边就是循环3.2方法添加的reset集合,执行对应的run方法

    public Runnable build() {
        return () -> mResetSequence.forEach(runnable -> runnable.run());
    }

下边看下常用的任务都干啥了,可以看到,都是交给对应的Manager处理了,细节不研究了。

3.4.resetConnectivityManager

    public ResetNetworkOperationBuilder resetConnectivityManager() {
        attachSystemServiceWork(Context.CONNECTIVITY_SERVICE,
                (Consumer<ConnectivityManager>) cm -> {
                        cm.factoryReset();
                });
        return this;
    }

3.5.resetVpnManager

    public ResetNetworkOperationBuilder resetVpnManager() {
        attachSystemServiceWork(Context.VPN_MANAGEMENT_SERVICE,
                (Consumer<VpnManager>) vpnManager -> {
                        vpnManager.factoryReset();
                });
        return this;
    }

3.6.resetWifiManager

    public ResetNetworkOperationBuilder resetWifiManager() {
        attachSystemServiceWork(Context.WIFI_SERVICE,
                (Consumer<WifiManager>) wifiManager -> {
                        wifiManager.factoryReset();
                });
        return this;
    }

3.7.resetWifiP2pManager

    public ResetNetworkOperationBuilder resetWifiP2pManager(Looper callbackLooper) {
        attachSystemServiceWork(Context.WIFI_P2P_SERVICE,
                (Consumer<WifiP2pManager>) wifiP2pManager -> {
                        WifiP2pManager.Channel channel = wifiP2pManager.initialize(
                                mContext, callbackLooper, null /* listener */);
                        if (channel != null) {
                            wifiP2pManager.factoryReset(channel, null /* listener */);
                        }
                });
        return this;
    }

3.8.resetBluetoothManager

    public ResetNetworkOperationBuilder resetBluetoothManager() {
        attachSystemServiceWork(Context.BLUETOOTH_SERVICE,
                (Consumer<BluetoothManager>) btManager -> {
                        BluetoothAdapter btAdapter = btManager.getAdapter();
                        if (btAdapter != null) {
                            btAdapter.clearBluetooth();
                        }
                });
        return this;
    }

3.9.resetTelephonyAndNetworkPolicyManager

    public ResetNetworkOperationBuilder resetTelephonyAndNetworkPolicyManager(
            int subscriptionId) {
        final AtomicReference<String> subscriberId = new AtomicReference<String>();
        attachSystemServiceWork(Context.TELEPHONY_SERVICE,
                (Consumer<TelephonyManager>) tm -> {
                        TelephonyManager subIdTm = tm.createForSubscriptionId(subscriptionId);
                        subscriberId.set(subIdTm.getSubscriberId());
                        subIdTm.resetSettings();
                });
        attachSystemServiceWork(Context.NETWORK_POLICY_SERVICE,
                (Consumer<NetworkPolicyManager>) policyManager -> {
                        policyManager.factoryReset(subscriberId.get());
                });
        return this;
    }

3.10.resetApn

拼接相应的uri进行删除操作

    public ResetNetworkOperationBuilder resetApn(int subscriptionId) {
        Runnable runnable = () -> {
            //"content://telephony/carriers/restore"
            Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI);

            if (SubscriptionManager.isUsableSubscriptionId(subscriptionId)) {
                uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(subscriptionId));
            }

            if (!DRY_RUN) {
                ContentResolver resolver = mContext.getContentResolver();
                resolver.delete(uri, null, null);
            }

        };
        mResetSequence.add(runnable);
        return this;
    }

4.NotificationManagerService.java

4.1.clearData

  • mConditionProviders,mListeners,mAssistants对象都是继承的ManagedServices.java
        public void clearData(String packageName, int uid, boolean fromApp) throws RemoteException {
            boolean packagesChanged = false;
            checkCallerIsSystem();
            // Cancel posted notifications
            final int userId = UserHandle.getUserId(uid);
            //根据包名和用户id删除相关的通知
            cancelAllNotificationsInt(MY_UID, MY_PID, packageName, null, 0, 0, true,
                    UserHandle.getUserId(Binder.getCallingUid()), REASON_CLEAR_DATA, null);

            //见补充1
            packagesChanged |=
                    mConditionProviders.resetPackage(packageName, userId);

            // 见补充2
            ArrayMap<Boolean, ArrayList<ComponentName>> changedListeners =
                    mListeners.resetComponents(packageName, userId);
            packagesChanged |= changedListeners.get(true).size() > 0
                    || changedListeners.get(false).size() > 0;

            // When a listener is enabled, we enable the dnd package as a secondary
            for (int i = 0; i < changedListeners.get(true).size(); i++) {
                mConditionProviders.setPackageOrComponentEnabled(
                        changedListeners.get(true).get(i).getPackageName(),
                        userId, false, true);
            }

            // Assistant,见5.1
            ArrayMap<Boolean, ArrayList<ComponentName>> changedAssistants =
                    mAssistants.resetComponents(packageName, userId);
            packagesChanged |= changedAssistants.get(true).size() > 0
                    || changedAssistants.get(false).size() > 0;

            //assitant只enable一个,所以从1开始,把其他的都disable掉
            for (int i = 1; i < changedAssistants.get(true).size(); i++) {
                mAssistants.setPackageOrComponentEnabled(
                        changedAssistants.get(true).get(i).flattenToString(),
                        userId, true, false);
            }

            // When the default assistant is enabled, we enable the dnd package as a secondary
            if (changedAssistants.get(true).size() > 0) {
                //we want only one assistant active
                mConditionProviders
                        .setPackageOrComponentEnabled(
                                changedAssistants.get(true).get(0).getPackageName(),
                                userId, false, true);

            }

            // Snoozing ,见补充3,清除snoozing通知
            mSnoozeHelper.clearData(UserHandle.getUserId(uid), packageName);

            // Reset notification preferences
            if (!fromApp) {
            //补充4
                mPreferencesHelper.clearData(packageName, uid);
            }

            if (packagesChanged) {
            //发送包改变的广播
                getContext().sendBroadcastAsUser(new Intent(
                                ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
                                .setPackage(packageName)
                                .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT),
                        UserHandle.of(userId), null);
            }

            handleSavePolicyFile();//补充5
        }

>1.resetPackage

重置组件的状态

//ConditionProviders.java

    boolean resetPackage(String packageName, int userId) {
        boolean isAllowed = super.isPackageOrComponentAllowed(packageName, userId);
        boolean isDefault = super.isDefaultComponentOrPackage(packageName);
        if (!isAllowed && isDefault) {
        //见5.3,使组件可用
            setPackageOrComponentEnabled(packageName, userId, true, true);
        }
        if (isAllowed && !isDefault) {
        //使组件不可用
            setPackageOrComponentEnabled(packageName, userId, true, false);
        }
        return !isAllowed && isDefault;
    }

>2.resetComponents

见父类5.1

    public class NotificationListeners extends ManagedServices {
    //..
    

>3.clearData

SnoozeHelper.java

    protected void clearData(int userId, String pkg) {
        synchronized (mLock) {
            int n = mSnoozedNotifications.size();
            for (int i = n - 1; i >= 0; i--) {
                final NotificationRecord record = mSnoozedNotifications.valueAt(i);
                //包名和userId一样
                if (record.getUserId() == userId && record.getSbn().getPackageName().equals(pkg)) {
                //移除数据
                    mSnoozedNotifications.removeAt(i);
                    String trimmedKey = getTrimmedString(record.getKey());
                    mPersistedSnoozedNotificationsWithContext.remove(trimmedKey);
                    mPersistedSnoozedNotifications.remove(trimmedKey);
                    Runnable runnable = () -> {
                        final PendingIntent pi = createPendingIntent(record.getKey());
                        //清除通知
                        mAm.cancel(pi);
                    };
                    runnable.run();
                }
            }
        }
    }

>4.PreferencesHelper.java

    public void clearData(String pkg, int uid) {
        synchronized (mPackagePreferences) {
            PackagePreferences p = getPackagePreferencesLocked(pkg, uid);
            if (p != null) {
                p.channels = new ArrayMap<>();
                p.groups = new ArrayMap<>();
                p.delegate = null;
                p.lockedAppFields = DEFAULT_LOCKED_APP_FIELDS;
                p.bubblePreference = DEFAULT_BUBBLE_PREFERENCE;
                p.importance = DEFAULT_IMPORTANCE;
                p.priority = DEFAULT_PRIORITY;
                p.visibility = DEFAULT_VISIBILITY;
                p.showBadge = DEFAULT_SHOW_BADGE;
            }
        }
    }

>5.handleSavePolicyFile

mPolicyFile的文件路径如下,/data/system/notification_policy.xml

final File systemDir = new File(Environment.getDataDirectory(), "system");
new File(systemDir, "notification_policy.xml")

最终执行这个runnable,clearData里已经重置了各种设置,这里走后进行保存

    private final class SavePolicyFileRunnable implements Runnable {
        @Override
        public void run() {
            synchronized (mPolicyFile) {
                final FileOutputStream stream;
                try {
                    stream = mPolicyFile.startWrite();
                } catch (IOException e) {
                    return;
                }

                try {
                //把新的策略写入文件里
                    writePolicyXml(stream, false /*forBackup*/, UserHandle.USER_ALL);
                    mPolicyFile.finishWrite(stream);
                } catch (IOException e) {
                    mPolicyFile.failWrite(stream);
                }
            }
            BackupManager.dataChanged(getContext().getPackageName());
        }
    }

5.ManagedServices.java

5.1.resetComponents

    ArrayMap<Boolean, ArrayList<ComponentName>> resetComponents(String packageName, int userId) {
        // components that we want to enable
        ArrayList<ComponentName> componentsToEnable =
                new ArrayList<>(mDefaultComponents.size());

        // components that were removed
        ArrayList<ComponentName> disabledComponents =
                new ArrayList<>(mDefaultComponents.size());

        // all components that are enabled now
        ArraySet<ComponentName> enabledComponents =
                new ArraySet<>(getAllowedComponents(userId));

        boolean changed = false;

        synchronized (mDefaultsLock) {
            // record all components that are enabled but should not be by default
            for (int i = 0; i < mDefaultComponents.size() && enabledComponents.size() > 0; i++) {
                ComponentName currentDefault = mDefaultComponents.valueAt(i);
                if (packageName.equals(currentDefault.getPackageName())
                        && !enabledComponents.contains(currentDefault)) {
                   //找到包名对应的默认组件,不在enable集合里,添加进入     
                    componentsToEnable.add(currentDefault);
                }
            }
            synchronized (mApproved) {
                final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(
                        userId);
                if (approvedByType != null) {
                    final int M = approvedByType.size();
                    for (int j = 0; j < M; j++) {
                        final ArraySet<String> approved = approvedByType.valueAt(j);
                        
                        for (int i = 0; i < enabledComponents.size(); i++) {
                            ComponentName currentComponent = enabledComponents.valueAt(i);
                            if (packageName.equals(currentComponent.getPackageName())
                                    && !mDefaultComponents.contains(currentComponent)) {
                            //在enabled组件里,不在default组件里
                                if (approved.remove(currentComponent.flattenToString())) {
                                //移除组件,加入到disabled集合组件
                                    disabledComponents.add(currentComponent);
                                    //从userSet里移除,见补充1
                                    clearUserSetFlagLocked(currentComponent, userId);
                                    changed = true;
                                }
                            }
                        }
                        //把enabled组件加入approved集合里
                        for (int i = 0; i < componentsToEnable.size(); i++) {
                            ComponentName candidate = componentsToEnable.get(i);
                            changed |= approved.add(candidate.flattenToString());
                        }
                    }

                }
            }
        }
        //数据发生变化,重新绑定服务
        if (changed) rebindServices(false, USER_ALL);
        //封装数据返回
        ArrayMap<Boolean, ArrayList<ComponentName>> changes = new ArrayMap<>();
        changes.put(true, componentsToEnable);
        changes.put(false, disabledComponents);

        return changes;
    }

>1.clearUserSetFlagLocked

    private boolean clearUserSetFlagLocked(ComponentName component, int userId) {
        String approvedValue = getApprovedValue(component.flattenToString());
        ArraySet<String> userSet = mUserSetServices.get(userId);
        return userSet != null && userSet.remove(approvedValue);
    }

5.2.rebindServices

  • 每当包更改、用户切换或安全设置更改时调用。(例如在我们的广播接收器中响应user_switch)
    protected void rebindServices(boolean forceRebind, int userToRebind) {
        IntArray userIds = mUserProfiles.getCurrentProfileIds();
        if (userToRebind != USER_ALL) {
            userIds = new IntArray(1);
            userIds.add(userToRebind);
        }

        final SparseArray<Set<ComponentName>> componentsToBind = new SparseArray<>();
        final SparseArray<Set<ComponentName>> componentsToUnbind = new SparseArray<>();

        synchronized (mMutex) {
            final SparseArray<ArraySet<ComponentName>> approvedComponentsByUser =
                    getAllowedComponents(userIds);
            final Set<ManagedServiceInfo> removableBoundServices = getRemovableConnectedServices();

            //补充3
            populateComponentsToBind(componentsToBind, userIds, approvedComponentsByUser);

            //补充4
            populateComponentsToUnbind(
                    forceRebind, removableBoundServices, componentsToBind, componentsToUnbind);
        }
        //补充5
        unbindFromServices(componentsToUnbind);
        //补充6
        bindToServices(componentsToBind);
    }

>1.getAllowedComponents

    protected SparseArray<ArraySet<ComponentName>> getAllowedComponents(IntArray userIds) {
        final int nUserIds = userIds.size();
        final SparseArray<ArraySet<ComponentName>> componentsByUser = new SparseArray<>();

        for (int i = 0; i < nUserIds; ++i) {
            final int userId = userIds.get(i);
            synchronized (mApproved) {
                final ArrayMap<Boolean, ArraySet<String>> approvedLists = mApproved.get(userId);
                if (approvedLists != null) {
                    final int N = approvedLists.size();
                    for (int j = 0; j < N; j++) {
                        ArraySet<ComponentName> approvedByUser = componentsByUser.get(userId);
                        if (approvedByUser == null) {
                            approvedByUser = new ArraySet<>();
                            componentsByUser.put(userId, approvedByUser);
                        }
                        approvedByUser.addAll(
                                loadComponentNamesFromValues(approvedLists.valueAt(j), userId));
                    }
                }
            }
        }
        return componentsByUser;
    }

>2.getRemovableConnectedServices

获取要移除的已连接服务

    protected Set<ManagedServiceInfo> getRemovableConnectedServices() {
        final Set<ManagedServiceInfo> removableBoundServices = new ArraySet<>();
        for (ManagedServiceInfo service : mServices) {
            if (!service.isSystem && !service.isGuest(this)) {
            //非系统,这个service就是当前的ManagedServices
                removableBoundServices.add(service);
            }
        }
        return removableBoundServices;
    }

>3.populateComponentsToBind

获取要绑定的组件

    protected void populateComponentsToBind(SparseArray<Set<ComponentName>> componentsToBind,
            final IntArray activeUsers,
            SparseArray<ArraySet<ComponentName>> approvedComponentsByUser) {
        mEnabledServicesForCurrentProfiles.clear();
        mEnabledServicesPackageNames.clear();
        final int nUserIds = activeUsers.size();

        for (int i = 0; i < nUserIds; ++i) {
            final int userId = activeUsers.get(i);
            final ArraySet<ComponentName> userComponents = approvedComponentsByUser.get(userId);
            if (null == userComponents) {
                componentsToBind.put(userId, new ArraySet<>());
                continue;
            }

            final Set<ComponentName> add = new HashSet<>(userComponents);
            //移除不需要运行的组件
            add.removeAll(mSnoozingForCurrentProfiles);

            componentsToBind.put(userId, add);
            //enabled服务集合添加数据
            mEnabledServicesForCurrentProfiles.addAll(userComponents);

            for (int j = 0; j < userComponents.size(); j++) {
                final ComponentName component = userComponents.valueAt(j);
                //添加包名
                mEnabledServicesPackageNames.add(component.getPackageName());
            }
        }
    }

>4.populateComponentsToUnbind

获取要解除绑定的组件

    protected void populateComponentsToUnbind(
            boolean forceRebind,
            Set<ManagedServiceInfo> removableBoundServices,
            SparseArray<Set<ComponentName>> allowedComponentsToBind,
            SparseArray<Set<ComponentName>> componentsToUnbind) {
        for (ManagedServiceInfo info : removableBoundServices) {
            final Set<ComponentName> allowedComponents = allowedComponentsToBind.get(info.userid);
            if (allowedComponents != null) {
            //强制重新绑定,或者不在allowed组件里
                if (forceRebind || !allowedComponents.contains(info.component)) {
                    Set<ComponentName> toUnbind =
                            componentsToUnbind.get(info.userid, new ArraySet<>());
                    toUnbind.add(info.component);
                    componentsToUnbind.put(info.userid, toUnbind);
                }
            }
        }
    }

>5.unbindFromServices

unbind提供的组件

    protected void unbindFromServices(SparseArray<Set<ComponentName>> componentsToUnbind) {
        for (int i = 0; i < componentsToUnbind.size(); i++) {
            final int userId = componentsToUnbind.keyAt(i);
            final Set<ComponentName> removableComponents = componentsToUnbind.get(userId);
            for (ComponentName cn : removableComponents) {
                //最终就是拿到ServiceConnection,调用context的unbindService方法
                unregisterService(cn, userId);
            }
        }
    }

>6.bindToServices

    private void bindToServices(SparseArray<Set<ComponentName>> componentsToBind) {
        for (int i = 0; i < componentsToBind.size(); i++) {
            final int userId = componentsToBind.keyAt(i);
            final Set<ComponentName> add = componentsToBind.get(userId);
            for (ComponentName component : add) {
                try {
                    ServiceInfo info = mPm.getServiceInfo(component,
                            PackageManager.GET_META_DATA
                                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                            userId);
                    if (info == null) {
                       //无法获取服务信息
                        continue;
                    }
                    if (!mConfig.bindPermission.equals(info.permission)) {
                       //权限问题
                        continue;
                    }
                    registerService(info, userId);//见补充7
                } 
            }
        }
    }

>7.registerServiceLocked

    private void registerServiceLocked(final ComponentName name, final int userid,
            final boolean isSystem) {

        final Pair<ComponentName, Integer> servicesBindingTag = Pair.create(name, userid);
        if (mServicesBound.contains(servicesBindingTag)) {
            //组件已经绑定过了
            return;
        }
        //加入集合,方便下次判断
        mServicesBound.add(servicesBindingTag);

        final int N = mServices.size();
        for (int i = N - 1; i >= 0; i--) {
            final ManagedServiceInfo info = mServices.get(i);
            if (name.equals(info.component)
                && info.userid == userid) {
                //移除解绑旧的服务
                removeServiceLocked(i);
                if (info.connection != null) {
                    unbindService(info.connection, info.component, info.userid);
                }
            }
        }

        Intent intent = new Intent(mConfig.serviceInterface);
        intent.setComponent(name);

        intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);

        final PendingIntent pendingIntent = PendingIntent.getActivity(
            mContext, 0, new Intent(mConfig.settingsAction), PendingIntent.FLAG_IMMUTABLE);
        intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);

        ApplicationInfo appInfo = null;
        try {
            appInfo = mContext.getPackageManager().getApplicationInfo(
                name.getPackageName(), 0);
        } 
        final int targetSdkVersion =
            appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
        final int uid = appInfo != null ? appInfo.uid : -1;

        try {
            ServiceConnection serviceConnection = new ServiceConnection() {
                IInterface mService;

                @Override
                public void onServiceConnected(ComponentName name, IBinder binder) {
                    boolean added = false;
                    ManagedServiceInfo info = null;
                    synchronized (mMutex) {
                        //从rebinding里移除
                        mServicesRebinding.remove(servicesBindingTag);
                        try {
                            mService = asInterface(binder);
                            //绑定成功以后,实例化一个serviceInfo对象,加入集合
                            info = newServiceInfo(mService, name,
                                userid, isSystem, this, targetSdkVersion, uid);
                            binder.linkToDeath(info, 0);
                            added = mServices.add(info);
                        } 
                    }
                    if (added) {
                        onServiceAdded(info);
                    }
                }

                @Override
                public void onServiceDisconnected(ComponentName name) {
                   
                }

                @Override
                public void onBindingDied(ComponentName name) {
                    //
                    synchronized (mMutex) {
                        unbindService(this, name, userid);
                        if (!mServicesRebinding.contains(servicesBindingTag)) {
                        //延迟10秒重新注册服务
                            mServicesRebinding.add(servicesBindingTag);
                            mHandler.postDelayed(() ->
                                    reregisterService(name, userid),
                                    ON_BINDING_DIED_REBIND_DELAY_MS);
                        }
                    }
                }

                @Override
                public void onNullBinding(ComponentName name) {
                    mContext.unbindService(this);
                }
            };
            //执行bind操作
            if (!mContext.bindServiceAsUser(intent,
                    serviceConnection,
                    getBindFlags(),
                    new UserHandle(userid))) {
                 //绑定失败,移除
                mServicesBound.remove(servicesBindingTag);
                return;
            }
        } catch (SecurityException ex) {
            //异常,移除
            mServicesBound.remove(servicesBindingTag);
        }
    }

5.3.setPackageOrComponentEnabled

  • enabled 为true,添加数据,为false,删除数据
    protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
            boolean isPrimary, boolean enabled) {
        setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled, true);
    }

    protected void setPackageOrComponentEnabled(String pkgOrComponent, int userId,
            boolean isPrimary, boolean enabled, boolean userSet) {
        synchronized (mApproved) {
            ArrayMap<Boolean, ArraySet<String>> allowedByType = mApproved.get(userId);
            if (allowedByType == null) {
                allowedByType = new ArrayMap<>();
                mApproved.put(userId, allowedByType);
            }
            ArraySet<String> approved = allowedByType.get(isPrimary);
            if (approved == null) {
                approved = new ArraySet<>();
                allowedByType.put(isPrimary, approved);
            }
            String approvedItem = getApprovedValue(pkgOrComponent);

            if (approvedItem != null) {
                if (enabled) {
                    approved.add(approvedItem);
                } else {
                    approved.remove(approvedItem);
                }
            }
            ArraySet<String> userSetServices = mUserSetServices.get(userId);
            if (userSetServices == null) {
                userSetServices = new ArraySet<>();
                mUserSetServices.put(userId, userSetServices);
            }
            if (userSet) {
                userSetServices.add(pkgOrComponent);
            } else {
                userSetServices.remove(pkgOrComponent);
            }
        }
        //见5.2
        rebindServices(false, userId);
    }

>1.getApprovedValue

    private String getApprovedValue(String pkgOrComponent) {
        if (mApprovalLevel == APPROVAL_BY_COMPONENT) {
        //走这里,验证下是否是 a.b.c/.d 或者a.b.c/a.b.c.d,也就是可以解析出包名和类名的
            if(ComponentName.unflattenFromString(pkgOrComponent) != null) {
                return pkgOrComponent;
            }
            return null;
        } else {
            return getPackageName(pkgOrComponent);
        }
    }

6.PackageManagerService.java

6.1.IPackageManagerBase.java

public abstract class IPackageManagerBase extends IPackageManager.Stub {
//..
    public final void resetApplicationPreferences(int userId) {
        mPreferredActivityHelper.resetApplicationPreferences(userId);
    }

6.2.PreferredActivityHelper.java

>1.resetApplicationPreferences

    public void resetApplicationPreferences(int userId) {
        mPm.mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
        // writer
        try {
            final SparseBooleanArray changedUsers = new SparseBooleanArray();
            synchronized (mPm.mLock) {//见6.3
                mPm.clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
            }
            if (changedUsers.size() > 0) {//见6.4
                mPm.postPreferredActivityChangedBroadcast(userId);
            }
            synchronized (mPm.mLock) {
            //见7.2
                mPm.mSettings.applyDefaultPreferredAppsLPw(userId);
                //
                mPm.mDomainVerificationManager.clearUser(userId);
                final int numPackages = mPm.mPackages.size();
                for (int i = 0; i < numPackages; i++) {
                    final AndroidPackage pkg = mPm.mPackages.valueAt(i);
                    //重置运行权限
                    mPm.mPermissionManager.resetRuntimePermissions(pkg, userId);
                }
            }
            //见补充2,更新默认的桌面
            updateDefaultHomeNotLocked(mPm.snapshotComputer(), userId);
            //补充3
            resetNetworkPolicies(userId);
            //小节6.5
            mPm.scheduleWritePackageRestrictions(userId);
        }
    }

>2.updateDefaultHomeNotLocked

    public boolean updateDefaultHomeNotLocked(@NonNull Computer snapshot, @UserIdInt int userId) {

        if (!mPm.isSystemReady()) {
            return false;
        }
        //桌面intent
        final Intent intent = snapshot.getHomeIntent();
        //根据intent查找所有的resolveInfo
        final List<ResolveInfo> resolveInfos = snapshot.queryIntentActivitiesInternal(
                intent, null, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
        //旋转最合适的一个
        final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(snapshot,
                intent, null, 0, resolveInfos, true, false, false, userId);
        //获取对应的包名        
        final String packageName = preferredResolveInfo != null
                && preferredResolveInfo.activityInfo != null
                ? preferredResolveInfo.activityInfo.packageName : null;
       //获取当前活动的launcher包名         
        final String currentPackageName = mPm.getActiveLauncherPackageName(userId);
        if (TextUtils.equals(currentPackageName, packageName)) {
        //默认的launcher和当前的一样,不做处理
            return false;
        }
        final String[] callingPackages = snapshot.getPackagesForUid(Binder.getCallingUid());
        if (callingPackages != null && ArrayUtils.contains(callingPackages,
                mPm.mRequiredPermissionControllerPackage)) {
            // PermissionController manages default home directly.
            return false;
        }

        if (packageName == null) {
            return false;
        }
        //修改为新的launcher
        return mPm.setActiveLauncherPackage(packageName, userId,
                successful -> {
                    if (successful) {
                        mPm.postPreferredActivityChangedBroadcast(userId);
                    }
                });
    }

>3.resetNetworkPolicies

    private void resetNetworkPolicies(int userId) {
    //见8.1
        mPm.mInjector.getLocalService(NetworkPolicyManagerInternal.class).resetUserState(userId);
    }

6.3.clearPackagePreferredActivitiesLPw

比如我们的包,跳转一个intent,有3个选项,我们可以选择一个作为默认打开的程序,这里就是清除这种数据

    void clearPackagePreferredActivitiesLPw(String packageName,
            @NonNull SparseBooleanArray outUserChanged, int userId) {
        //清除的包的首选活动数据
        mSettings.clearPackagePreferredActivities(packageName, outUserChanged, userId);
    }

6.4.postPreferredActivityChangedBroadcast

首选意图改变广播

    void postPreferredActivityChangedBroadcast(int userId) {
        mHandler.post(() -> mBroadcastHelper.sendPreferredActivityChangedBroadcast(userId));
    }

>1.BroadcastHelper.java

    public void sendPreferredActivityChangedBroadcast(int userId) {
        final IActivityManager am = ActivityManager.getService();
        if (am == null) {
            return;
        }

        final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
        try {
            am.broadcastIntentWithFeature(null, null, intent, null, null,
                    0, null, null, null, null, null, android.app.AppOpsManager.OP_NONE,
                    null, false, false, userId);
        } catch (RemoteException e) {
        }
    }

6.5.scheduleWritePackageRestrictions

    void scheduleWritePackageRestrictions(int userId) {
        invalidatePackageInfoCache();
        if (userId == UserHandle.USER_ALL) {
            synchronized (mDirtyUsers) {
                for (int aUserId : mUserManager.getUserIds()) {
                    mDirtyUsers.add(aUserId);
                }
            }
        } else {
            if (!mUserManager.exists(userId)) {
                return;
            }
            synchronized (mDirtyUsers) {
                mDirtyUsers.add(userId);
            }
        }
        if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
            mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
        }
    }

交给PackageHandler.java处理,最终又回到这里

    void writePendingRestrictions() {
        synchronized (mLock) {
            mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
            synchronized (mDirtyUsers) {
                for (int userId : mDirtyUsers) {
                //
                    mSettings.writePackageRestrictionsLPr(userId);
                }
                mDirtyUsers.clear();
            }
        }
    }

7.Settings.java

7.1.clearPackagePreferredActivities

    void clearPackagePreferredActivities(String packageName,
            @NonNull SparseBooleanArray outUserChanged, int userId) {
        boolean changed = false;
        ArrayList<PreferredActivity> removed = null;
        for (int i = 0; i < mPreferredActivities.size(); i++) {
            final int thisUserId = mPreferredActivities.keyAt(i);
            PreferredIntentResolver pir = mPreferredActivities.valueAt(i);
            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
                continue;
            }
            Iterator<PreferredActivity> it = pir.filterIterator();
            while (it.hasNext()) {
                PreferredActivity pa = it.next();
                if (packageName == null
                        || (pa.mPref.mComponent.getPackageName().equals(packageName)
                                && pa.mPref.mAlways)) {
                    if (removed == null) {
                        removed = new ArrayList<>();
                    }
                    //没有提供具体的包名,或者提供的包名和我们的首选意图解析的包名一样,加入remove集合
                    removed.add(pa);
                }
            }
            if (removed != null) {
                for (int j = 0; j < removed.size(); j++) {
                    PreferredActivity pa = removed.get(j);
                    pir.removeFilter(pa);
                }
                //有要移除的数据,标记
                outUserChanged.put(thisUserId, true);
                changed = true;
            }
        }
        if (changed) {
            onChanged();
        }
    }

7.2.applyDefaultPreferredAppsLPw

应用默认的首选应用

    void applyDefaultPreferredAppsLPw(int userId) {
        // First pull data from any pre-installed apps.
        final PackageManagerInternal pmInternal =
                LocalServices.getService(PackageManagerInternal.class);
        for (PackageSetting ps : mPackages.values()) {
        //系统包,首选活动过滤不为空
            if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0 && ps.getPkg() != null
                    && !ps.getPkg().getPreferredActivityFilters().isEmpty()) {
                List<Pair<String, ParsedIntentInfo>> intents
                        = ps.getPkg().getPreferredActivityFilters();
                for (int i=0; i<intents.size(); i++) {
                //首选activity的类名以及解析的intent信息
                    Pair<String, ParsedIntentInfo> pair = intents.get(i);
                    //应用
                    applyDefaultPreferredActivityLPw(pmInternal,
                            pair.second.getIntentFilter(),
                            new ComponentName(ps.getPackageName(), pair.first), userId);
                }
            }
        }

        // Read preferred apps from .../etc/preferred-apps directories.
        //循环所有的系统分区,读取特定位置的配置文件,获取首选app信息
        int size = PackageManagerService.SYSTEM_PARTITIONS.size();
        for (int index = 0; index < size; index++) {
            ScanPartition partition = PackageManagerService.SYSTEM_PARTITIONS.get(index);

            File preferredDir = new File(partition.getFolder(), "etc/preferred-apps");
            if (!preferredDir.exists() || !preferredDir.isDirectory()) {
                continue;
            }

            if (!preferredDir.canRead()) {
                continue;
            }

            File[] files = preferredDir.listFiles();
            if (ArrayUtils.isEmpty(files)) {
                continue;
            }
            //必须有.xml结尾的可读文件
            for (File f : files) {
                if (!f.getPath().endsWith(".xml")) {
                    continue;
                }
                if (!f.canRead()) {
                    continue;
                }

                try (InputStream str = new FileInputStream(f)) {
                    final TypedXmlPullParser parser = Xml.resolvePullParser(str);

                    int type;
                    while ((type = parser.next()) != XmlPullParser.START_TAG
                            && type != XmlPullParser.END_DOCUMENT) {
                        ;
                    }

                    if (type != XmlPullParser.START_TAG) {
                        continue;
                    }
                    if (!"preferred-activities".equals(parser.getName())) {
                        continue;
                    }
                    //读取并应用数据
                    readDefaultPreferredActivitiesLPw(parser, userId);
                } 
            }
        }
    }

7.3.writePackageRestrictionsLPr

    void writePackageRestrictionsLPr(int userId) {
        invalidatePackageCache();

        if (DEBUG_MU) {
            Log.i(TAG, "Writing package restrictions for user=" + userId);
        }
        final long startTime = SystemClock.uptimeMillis();

        // Keep the old stopped packages around until we know the new ones have
        // been successfully written.
        File userPackagesStateFile = getUserPackagesStateFile(userId);
        File backupFile = getUserPackagesStateBackupFile(userId);
        new File(userPackagesStateFile.getParent()).mkdirs();

>1.getUserPackagesStateFile

    private File getUserPackagesStateFile(int userId) {
        File userDir = new File(new File(mSystemDir, "users"), Integer.toString(userId));
        return new File(userDir, "package-restrictions.xml");
    }

8.NetworkPolicyManagerService.java

8.1.NetworkPolicyManagerInternalImpl

    private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {

        @Override
        public void resetUserState(int userId) {
            synchronized (mUidRulesFirstLock) {
                boolean changed = removeUserStateUL(userId, false, true);
                changed = addDefaultRestrictBackgroundAllowlistUidsUL(userId) || changed;
                if (changed) {
                    synchronized (mNetworkPoliciesSecondLock) {
                        writePolicyAL();
                    }
                }
            }
        }

8.2.getUidsWithPolicy

根据提供的网络策略返回所有支持的uid

    public int[] getUidsWithPolicy(int policy) {
        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);

        int[] uids = new int[0];
        synchronized (mUidRulesFirstLock) {
            for (int i = 0; i < mUidPolicy.size(); i++) {
                final int uid = mUidPolicy.keyAt(i);
                final int uidPolicy = mUidPolicy.valueAt(i);
                //要查找的和循环的策略都是空,或者循环的策略里包含要查找的策略
                if ((policy == POLICY_NONE && uidPolicy == POLICY_NONE) ||
                        (uidPolicy & policy) != 0) {
                    uids = appendInt(uids, uid);
                }
            }
        }
        return uids;
    }

8.3.setUidPolicy

设置新的网络策略

    public void setUidPolicy(int uid, int policy) {
        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);

        if (!UserHandle.isApp(uid)) {
            throw new IllegalArgumentException("cannot apply policy to UID " + uid);
        }
        synchronized (mUidRulesFirstLock) {
            try {
                final int oldPolicy = mUidPolicy.get(uid, POLICY_NONE);
                if (oldPolicy != policy) {
                //见8.4.
                    setUidPolicyUncheckedUL(uid, oldPolicy, policy, true);
                }
            } 
        }
    }

8.4.setUidPolicyUncheckedUL

    private void setUidPolicyUncheckedUL(int uid, int oldPolicy, int policy, boolean persist) {
        setUidPolicyUncheckedUL(uid, policy, false);//补充1

        final boolean notifyApp;
        if (!isUidValidForAllowlistRulesUL(uid)) {//补充2
            notifyApp = false;
        } else {
            final boolean wasDenied = oldPolicy == POLICY_REJECT_METERED_BACKGROUND;
            final boolean isDenied = policy == POLICY_REJECT_METERED_BACKGROUND;
            final boolean wasAllowed = oldPolicy == POLICY_ALLOW_METERED_BACKGROUND;
            final boolean isAllowed = policy == POLICY_ALLOW_METERED_BACKGROUND;
            final boolean wasBlocked = wasDenied || (mRestrictBackground && !wasAllowed);
            final boolean isBlocked = isDenied || (mRestrictBackground && !isAllowed);
            if ((wasAllowed && (!isAllowed || isDenied))
                    && mDefaultRestrictBackgroundAllowlistUids.get(uid)
                    && !mRestrictBackgroundAllowlistRevokedUids.get(uid)) {
                mRestrictBackgroundAllowlistRevokedUids.append(uid, true);
            }
            notifyApp = wasBlocked != isBlocked;
        }
        //补充3,策略变化,通知相关的回调,以及发送广播
        mHandler.obtainMessage(MSG_POLICIES_CHANGED, uid, policy, Boolean.valueOf(notifyApp))
                .sendToTarget();
        if (persist) {
            synchronized (mNetworkPoliciesSecondLock) {
                writePolicyAL();
            }
        }
    }

>1.setUidPolicyUncheckedUL

给uid设置对应的策略

    private void setUidPolicyUncheckedUL(int uid, int policy, boolean persist) {
        if (policy == POLICY_NONE) {
        //NONE的话,删除
            mUidPolicy.delete(uid);
        } else {
        //其他的添加
            mUidPolicy.put(uid, policy);
        }

        // uid policy changed, recompute rules and persist policy.
        //策略变化了,更新数据使用限制的规则
        updateRulesForDataUsageRestrictionsUL(uid);
        if (persist) {
            synchronized (mNetworkPoliciesSecondLock) {
            //需要持久化的,保存数据
                writePolicyAL();
            }
        }
    }

>2.isUidValidForAllowlistRulesUL

是普通应用,并且清单文件里有网络权限

    private boolean isUidValidForAllowlistRulesUL(int uid) {
        return UserHandle.isApp(uid) && hasInternetPermissionUL(uid);
    }
    public static boolean isApp(int uid) {
        if (uid > 0) {
            final int appId = getAppId(uid); //10000-19999
            return appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID;
        } else {
            return false;
        }
    }

>3.MSG_POLICIES_CHANGED

                case MSG_POLICIES_CHANGED: {
                    final int uid = msg.arg1;
                    final int policy = msg.arg2;
                    final Boolean notifyApp = (Boolean) msg.obj;
                    // First notify internal listeners...
                    final int length = mListeners.beginBroadcast();
                    for (int i = 0; i < length; i++) {
                    //循环所有的监听,
                        final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
                        dispatchUidPoliciesChanged(listener, uid, policy);
                    }
                    mListeners.finishBroadcast();
                    //通知app的话,发送广播
                    if (notifyApp.booleanValue()) {
                        broadcastRestrictBackgroundChanged(uid, notifyApp);
                    }
                    return true;
                }
    private void broadcastRestrictBackgroundChanged(int uid, Boolean changed) {
        final PackageManager pm = mContext.getPackageManager();
        final String[] packages = pm.getPackagesForUid(uid);
        if (packages != null) {
            final int userId = UserHandle.getUserId(uid);
            for (String packageName : packages) {
                final Intent intent =
                        new Intent(ConnectivityManager.ACTION_RESTRICT_BACKGROUND_CHANGED);
                intent.setPackage(packageName);
                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
            }
        }
    }

9.AppOpsService.java

应用操作服务,

public class AppOpsService extends IAppOpsService.Stub {

9.1.AppProtoEnums

code是通过proto文件生成的,路径frameworks/base/core/proto/android/app/enums.proto

syntax = "proto2";

package android.app;

option java_outer_classname = "AppProtoEnums";
option java_multiple_files = true;

//...

// AppOpsManager.java - operation ids for logging
enum AppOpEnum {
    APP_OP_NONE = -1;
    APP_OP_COARSE_LOCATION = 0;
    APP_OP_FINE_LOCATION = 1;
    APP_OP_GPS = 2;
    APP_OP_VIBRATE = 3;
    APP_OP_READ_CONTACTS = 4;

    APP_OP_REQUEST_INSTALL_PACKAGES = 66;
//...

9.2.resetAllModes

这里是从上篇的reset apps 那边调用的,第二个参数为空。

  1. 循环所有的uidState,先获取opModes(SparseIntArray),key就是操作,value是状态
  2. 先判断对应的key是否允许重置,允许的话
    public void resetAllModes(int reqUserId, String reqPackageName) {
        final int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        reqUserId = ActivityManager.handleIncomingUser(callingPid, callingUid, reqUserId,
                true, true, "resetAllModes", null);

        int reqUid = -1;
    //权限检查
        enforceManageAppOpsModes(callingPid, callingUid, reqUid);

        HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks = null;
        ArrayList<ChangeRec> allChanges = new ArrayList<>();
        synchronized (this) {
            boolean changed = false;
            for (int i = mUidStates.size() - 1; i >= 0; i--) {
                UidState uidState = mUidStates.valueAt(i);
                //key就是9.1里定义的操作,value就是操作的状态,支持的状态见10.1
                SparseIntArray opModes = uidState.opModes;
                if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
                    final int uidOpCount = opModes.size();
                    for (int j = uidOpCount - 1; j >= 0; j--) {
                        final int code = opModes.keyAt(j);
                        //我们这里是重置操作,所以需要先查看下对应的操作是否支持重置,见10.2
                        if (AppOpsManager.opAllowsReset(code)) {
                            int previousMode = opModes.valueAt(j);
                            opModes.removeAt(j);
                            if (opModes.size() <= 0) {
                                uidState.opModes = null;
                            }
                            //循环进程里包含的所有包
                            for (String packageName : getPackagesForUid(uidState.uid)) {
                            //添加回调,见补充2
                                callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
                                        previousMode, mOpModeWatchers.get(code));
                                callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
                                        previousMode, mPackageModeWatchers.get(packageName));
                    //见补充3,添加数据到集合
                                allChanges = addChange(allChanges, code, uidState.uid,
                                        packageName, previousMode);
                            }
                        }
                    }
                }

                if (uidState.pkgOps == null) {
                //没有额外的包
                    continue;
                }

                if (reqUserId != UserHandle.USER_ALL
                        && reqUserId != UserHandle.getUserId(uidState.uid)) {
                    // 不同的用户
                    continue;
                }
            //一个进程下可能有多个包
                Map<String, Ops> packages = uidState.pkgOps;
                //key就是包名
                Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator();
                boolean uidChanged = false;
                while (it.hasNext()) {
                    Map.Entry<String, Ops> ent = it.next();
                    String packageName = ent.getKey();
                    if (reqPackageName != null && !reqPackageName.equals(packageName)) {
                        // Skip any ops for a different package
                        continue;
                    }
                    Ops pkgOps = ent.getValue();
                    for (int j=pkgOps.size()-1; j>=0; j--) {
                        //一个存储ops数据的对象
                        Op curOp = pkgOps.valueAt(j);
                        if (shouldDeferResetOpToDpm(curOp.op)) {
                        //见补充5
                            deferResetOpToDpm(curOp.op, reqPackageName, reqUserId);
                            continue;
                        }
                        //对应的op允许reset并且当前的状态和默认状态不一样
                        if (AppOpsManager.opAllowsReset(curOp.op)
                                && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) {
                            int previousMode = curOp.mode;
                            curOp.mode = AppOpsManager.opToDefaultMode(curOp.op);
                            changed = true;
                            uidChanged = true;
                            final int uid = curOp.uidState.uid;
                            //见补充2
                            callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
                                    previousMode, mOpModeWatchers.get(curOp.op));
                            callbacks = addCallbacks(callbacks, curOp.op, uid, packageName,
                                    previousMode, mPackageModeWatchers.get(packageName));
                            //见补充3
                            allChanges = addChange(allChanges, curOp.op, uid, packageName,
                                    previousMode);
                            curOp.removeAttributionsWithNoTime();
                            if (curOp.mAttributions.isEmpty()) {
                                pkgOps.removeAt(j);
                            }
                        }
                    }
                    if (pkgOps.size() == 0) {
                        it.remove();
                    }
                }
                //见9.4.1 成了默认状态的话,从集合里移除
                if (uidState.isDefault()) {
                    mUidStates.remove(uidState.uid);
                }
                if (uidChanged) {
                //状态有改变的话,
                    uidState.evalForegroundOps(mOpModeWatchers);
                }
            }

            if (changed) {
            //这个是数据本地保存,文件路径 /data/system/appops.xml
                scheduleFastWriteLocked();
            }
        }
        if (callbacks != null) {
            for (Map.Entry<ModeCallback, ArrayList<ChangeRec>> ent : callbacks.entrySet()) {
                ModeCallback cb = ent.getKey();
                ArrayList<ChangeRec> reports = ent.getValue();
                for (int i=0; i<reports.size(); i++) {
                    ChangeRec rep = reports.get(i);
                    mHandler.sendMessage(PooledLambda.obtainMessage(
                            AppOpsService::notifyOpChanged,
                            this, cb, rep.op, rep.uid, rep.pkg));
                }
            }
        }

        int numChanges = allChanges.size();
        for (int i = 0; i < numChanges; i++) {
            ChangeRec change = allChanges.get(i);
            //op发生改变的,进行相应的操作,见补充4
            notifyOpChangedSync(change.op, change.uid, change.pkg,
                    AppOpsManager.opToDefaultMode(change.op), change.previous_mode);
        }
    }

>1.watchers集合

用户注册的监听ops的状态改变的回调集合

    //数据来源见9.3
    final SparseArray<ArraySet<ModeCallback>> mOpModeWatchers = new SparseArray<>();
    final ArrayMap<String, ArraySet<ModeCallback>> mPackageModeWatchers = new ArrayMap<>();

>2.addCallbacks

  • 最后一个参数cbs就是用户注册的回调观察
  • 第一个参数callbacks是布局变量集合,存储对应callback发生的变化内容集合
    private static HashMap<ModeCallback, ArrayList<ChangeRec>> addCallbacks(
            HashMap<ModeCallback, ArrayList<ChangeRec>> callbacks,
            int op, int uid, String packageName, int previousMode, ArraySet<ModeCallback> cbs) {
        if (cbs == null) {
        //没有要观察的回调集合,那就返回
            return callbacks;
        }
        if (callbacks == null) {
            callbacks = new HashMap<>();
        }
        final int N = cbs.size();
        for (int i=0; i<N; i++) {
            //循环用户添加的回调
            ModeCallback cb = cbs.valueAt(i);
            //根据回调获取对应的数据改变的集合
            ArrayList<ChangeRec> reports = callbacks.get(cb);
            //集合里添加数据
            ArrayList<ChangeRec> changed = addChange(reports, op, uid, packageName, previousMode);
            if (changed != reports) {
                callbacks.put(cb, changed);
            }
        }
        return callbacks;
    }

>3.addChange

创建一个数据对象放入集合

    private static ArrayList<ChangeRec> addChange(ArrayList<ChangeRec> reports,
            int op, int uid, String packageName, int previousMode) {
        boolean duplicate = false;
        if (reports == null) {
            reports = new ArrayList<>();
        } else {
            final int reportCount = reports.size();
            //循环旧数据
            for (int j = 0; j < reportCount; j++) {
                ChangeRec report = reports.get(j);
                //判断op和包名是否一样,一样就认为是重复的
                if (report.op == op && report.pkg.equals(packageName)) {
                //标记为重复的数据
                    duplicate = true;
                    break;
                }
            }
        }
        if (!duplicate) {
        //没有重复的表明是新的,
            reports.add(new ChangeRec(op, uid, packageName, previousMode));
        }

        return reports;
    }

>4.notifyOpChangedSync

    private void notifyOpChangedSync(int code, int uid, @NonNull String packageName, int mode,
            int previousMode) {
        final StorageManagerInternal storageManagerInternal =
                LocalServices.getService(StorageManagerInternal.class);
        if (storageManagerInternal != null) {
        //见9.5
            storageManagerInternal.onAppOpsChanged(code, uid, packageName, mode, previousMode);
        }
    }

>5.shouldDeferResetOpToDpm

是否应该延迟重置op,可以看到交给dpmi处理了,见9.8

    @Nullable private final DevicePolicyManagerInternal dpmi =
            LocalServices.getService(DevicePolicyManagerInternal.class);
            
    private boolean shouldDeferResetOpToDpm(int op) {
        // TODO(b/174582385): avoid special-casing app-op resets by migrating app-op permission
        //  pre-grants to a role-based mechanism or another general-purpose mechanism.
        return dpmi != null && dpmi.supportsResetOp(op);
    }

    private void deferResetOpToDpm(int op, String packageName, @UserIdInt int userId) {
        // TODO(b/174582385): avoid special-casing app-op resets by migrating app-op permission
        //  pre-grants to a role-based mechanism or another general-purpose mechanism.
        dpmi.resetOp(op, packageName, userId);
    }

9.3.startWatchingModeWithFlags

监听给定的包的指定的op的flags的改变

    public void startWatchingModeWithFlags(int op, String packageName, int flags,
            IAppOpsCallback callback) {
    //..
        if (callback == null) {
            return;
        }
        final boolean mayWatchPackageName =
                packageName != null && !filterAppAccessUnlocked(packageName);
        synchronized (this) {
            int switchOp = (op != AppOpsManager.OP_NONE) ? AppOpsManager.opToSwitch(op) : op;

            int notifiedOps;
            if ((flags & CALL_BACK_ON_SWITCHED_OP) == 0) {
                if (op == OP_NONE) {
                    notifiedOps = ALL_OPS;
                } else {
                    notifiedOps = op;
                }
            } else {
                notifiedOps = switchOp;
            }
            //先看有没有旧数据
            ModeCallback cb = mModeWatchers.get(callback.asBinder());
            if (cb == null) {
            //没有就创建新的
                cb = new ModeCallback(callback, watchedUid, flags, notifiedOps, callingUid,
                        callingPid);
                //这里添加数据
                mModeWatchers.put(callback.asBinder(), cb);
            }
            if (switchOp != AppOpsManager.OP_NONE) {
                ArraySet<ModeCallback> cbs = mOpModeWatchers.get(switchOp);
                if (cbs == null) {
                    cbs = new ArraySet<>();
                    mOpModeWatchers.put(switchOp, cbs);
                }
                cbs.add(cb);
            }
            //需要观察包名的
            if (mayWatchPackageName) {
                ArraySet<ModeCallback> cbs = mPackageModeWatchers.get(packageName);
                if (cbs == null) {
                    //没有旧数据
                    cbs = new ArraySet<>();
                    //集合添加数据
                    mPackageModeWatchers.put(packageName, cbs);
                }
                cbs.add(cb);
            }
            evalAllForegroundOpsLocked();
        }
    }

>1.filterAppAccessUnlocked

  • 确定所提供的包是否应该对Binder.getCallingUid()可见。
  • 注意:为了避免死锁,在This上同步时不能调用这个函数
    private boolean filterAppAccessUnlocked(String packageName) {
        final int callingUid = Binder.getCallingUid();
        return LocalServices.getService(PackageManagerInternal.class)
                .filterAppAccess(packageName, callingUid, UserHandle.getUserId(callingUid));
    }

9.4.UidState

>1.isDefault

        public boolean isDefault() {
            return (pkgOps == null || pkgOps.isEmpty())
                    && (opModes == null || opModes.size() <= 0)
                    && (state == UID_STATE_CACHED
                    && (pendingState == UID_STATE_CACHED));
        }

9.5.StorageManagerService.java

>1.onAppOpsChanged

//内部类里的方法
        public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode,
                int previousMode) {
            final long token = Binder.clearCallingIdentity();
            try {
                // When using FUSE, we may need to kill the app if the op changes
                switch(code) {
                    case OP_REQUEST_INSTALL_PACKAGES:
                        // In R, we used to kill the app here if it transitioned to/from
                        // MODE_ALLOWED, to make sure the app had the correct (writable) OBB
                        // view. But the majority of apps don't handle OBBs anyway, and for those
                        // that do, they can restart themselves. Therefore, starting from S,
                        // only kill the app when it transitions away from MODE_ALLOWED (eg,
                        // when the permission is taken away).
                        //旧状态是allow,新状态不是
                        if (previousMode == MODE_ALLOWED && mode != MODE_ALLOWED) {
                        //见补充2,杀死进程
                            killAppForOpChange(code, uid);
                        }
                        return;
                    case OP_MANAGE_EXTERNAL_STORAGE:
                        if (mode != MODE_ALLOWED) {
                            // Only kill if op is denied, to lose external_storage gid
                            // Killing when op is granted to pickup the gid automatically,
                            // results in a bad UX, especially since the gid only gives access
                            // to unreliable volumes, USB OTGs that are rarely mounted. The app
                            // will get the external_storage gid on next organic restart.
                            killAppForOpChange(code, uid);
                        }
                        return;
                    case OP_LEGACY_STORAGE:
                        updateLegacyStorageApps(packageName, uid, mode == MODE_ALLOWED);
                        return;
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

>2.killAppForOpChange

        private void killAppForOpChange(int code, int uid) {
            final IActivityManager am = ActivityManager.getService();
            try {//见9.6
                am.killUid(UserHandle.getAppId(uid), UserHandle.USER_ALL,
                        AppOpsManager.opToName(code) + " changed.");
            } catch (RemoteException e) {
            }
        }

9.6.ActivityManagerService.java

>1.killUid

    public void killUid(int appId, int userId, String reason) {
        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
        synchronized (this) {
            final long identity = Binder.clearCallingIdentity();
            try {
                synchronized (mProcLock) {
                    mProcessList.killPackageProcessesLSP(null /* packageName */, appId, userId,
                            ProcessList.PERSISTENT_PROC_ADJ, false /* callerWillRestart */,
                            true /* callerWillRestart */, true /* doit */,
                            true /* evenPersistent */, false /* setRemoved */,
                            false /* uninstalling */,
                            ApplicationExitInfo.REASON_OTHER,
                            ApplicationExitInfo.SUBREASON_KILL_UID,
                            reason != null ? reason : "kill uid");
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
            }
        }
    }

9.7.ProcessList.java

    boolean killPackageProcessesLSP(String packageName, int appId,
    //...
            final ArrayList<Pair<ProcessRecord, Boolean>> procs = new ArrayList<>();

        //循环所有的进程,找到appId相关的进程信息
        final int NP = mProcessNames.getMap().size();
        for (int ip = 0; ip < NP; ip++) {
            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
            //..
            //中间就是各种判断,走到最后
                procs.add(new Pair<>(app, shouldAllowRestart));
            }
        }            
            
        int N = procs.size();
        for (int i=0; i<N; i++) {
            final Pair<ProcessRecord, Boolean> proc = procs.get(i);
            //杀死进程,补充2
            removeProcessLocked(proc.first, callerWillRestart, allowRestart || proc.second,
                    reasonCode, subReason, reason);
        }
        
        killAppZygotesLocked(packageName, appId, userId, false /* force */);
        mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
        return N > 0;
    }

>2.removeProcessLocked

后边就是调用ProcessRecord的kill方法,如下

    boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
    //...
            app.killLocked(reason, reasonCode, subReason, true);

9.8.DevicePolicyManagerService.java

>1.supportsResetOp

  • 可以看到op必须是OP_INTERACT_ACROSS_PROFILES
  • 对应的服务不为空,服务注册见补充3
        public boolean supportsResetOp(int op) {
            return op == AppOpsManager.OP_INTERACT_ACROSS_PROFILES
                    && LocalServices.getService(CrossProfileAppsInternal.class) != null;
        }

>2.resetOp

  • 目前只支持为一个op,不是的话抛出异常
        @Override
        public void resetOp(int op, String packageName, @UserIdInt int userId) {
            if (op != AppOpsManager.OP_INTERACT_ACROSS_PROFILES) {
                throw new IllegalArgumentException("Unsupported op for DPM reset: " + op);
            }
            LocalServices.getService(CrossProfileAppsInternal.class)
                    .setInteractAcrossProfilesAppOp(//见补充4
                            packageName, findInteractAcrossProfilesResetMode(packageName), userId);
        }

>3.CrossProfileAppsService

public class CrossProfileAppsService extends SystemService {
    private CrossProfileAppsServiceImpl mServiceImpl;

    public CrossProfileAppsService(Context context) {
        super(context);
        mServiceImpl = new CrossProfileAppsServiceImpl(context);
    }

    @Override
    public void onStart() {
        publishBinderService(Context.CROSS_PROFILE_APPS_SERVICE, mServiceImpl);
        //这里注册的
        publishLocalService(CrossProfileAppsInternal.class, mServiceImpl.getLocalService());
    }
}

>4.setInteractAcrossProfilesAppOp

不看了,这个profile看着晕

    private void setInteractAcrossProfilesAppOpUnchecked(
            String packageName, @Mode int newMode, @UserIdInt int userId) {
        if (newMode == AppOpsManager.MODE_ALLOWED
                && !canConfigureInteractAcrossProfiles(packageName, userId)) {
            // The user should not be prompted for apps that cannot request to interact across
            // profiles. However, we return early here if required to avoid race conditions.
            Slog.e(TAG, "Tried to turn on the appop for interacting across profiles for invalid"
                    + " app " + packageName);
            return;
        }
        final int[] profileIds =
                mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
        for (int profileId : profileIds) {
            if (!isPackageInstalled(packageName, profileId)) {
                continue;
            }
            // Only log once per profile group by checking against the user ID.
            setInteractAcrossProfilesAppOpForProfile(
                    packageName, newMode, profileId, /* logMetrics= */ profileId == userId);
        }
    }


    class LocalService extends CrossProfileAppsInternal {
    //..
         public void setInteractAcrossProfilesAppOp(
                String packageName, int newMode, @UserIdInt int userId) {
            CrossProfileAppsServiceImpl.this.setInteractAcrossProfilesAppOpUnchecked(
                    packageName, newMode, userId);
        }   

10.AppOpsManager.java

10.1.MODE_XXX

执行操作的结果

    //给定的调用者允许执行给定的操作
    public static final int MODE_ALLOWED = 0;

     //给定的调用者不允许执行给定的操作,并且操作失败是静默的,不影响app
    public static final int MODE_IGNORED = 1;

     //给定的调用者不允许执行给定的操作,并且返回安全异常,致命的错误
    public static final int MODE_ERRORED = 2;

    /**
     * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
     * use its default security check.  This mode is not normally used; it should only be used
     * with appop permissions, and callers must explicitly check for it and deal with it.
     */
     //给定的调用者使用默认的安全检查,这个mode不常用,只应该用来权限检查
    public static final int MODE_DEFAULT = 3;

    /**
     * Special mode that means "allow only when app is in foreground."  This is <b>not</b>
     * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}.  Rather,
     * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
     * possible for it to be ultimately allowed, depending on the app's background state),
     * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
     * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
     *
     * <p>The only place you will this normally see this value is through
     * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op.  Note that because
     * you can't know the current state of the app being checked (and it can change at any
     * point), you can only treat the result here as an indication that it will vary between
     * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
     * state of the app.  You thus must always use {@link #noteOp} or {@link #startOp} to do
     * the actual check for access to the op.</p>
     */
     //只允许前台应用,
    public static final int MODE_FOREGROUND = 4;

10.2.opAllowsReset

对应的op是否允许重置,默认状态都在数组里存着了

    public static boolean opAllowsReset(int op) {
        return !sOpDisableReset[op];
    }

10.3.opToDefaultMode

对应的op的默认状态,默认状态都在数组里存着了

    public static @Mode int opToDefaultMode(int op) {
        return sOpDefaultMode[op];
    }

11.BatteryOptimizeUtils.java

11.1.resetAppOptimizationMode

    public static void resetAppOptimizationMode(
            Context context, IPackageManager ipm, AppOpsManager aom) {
        resetAppOptimizationMode(context, ipm, aom,
                PowerAllowlistBackend.getInstance(context), BatteryUtils.getInstance(context));
    }

    static void resetAppOptimizationMode(
            Context context, IPackageManager ipm, AppOpsManager aom,
            PowerAllowlistBackend allowlistBackend, BatteryUtils batteryUtils) {
        //获取安装的应用,不包括用户disable的
        final ArraySet<ApplicationInfo> applications = getInstalledApplications(context, ipm);
        if (applications == null || applications.isEmpty()) {
            return;
        }
        //见12.1
        allowlistBackend.refreshList();
        //
        for (ApplicationInfo info : applications) {
            final int mode = aom.checkOpNoThrow(
                    AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, info.uid, info.packageName);
            @OptimizationMode //见补充1
            final int optimizationMode = getAppOptimizationMode(
                    mode, allowlistBackend.isAllowlisted(info.packageName));//见12.2
            // Ignores default optimized/unknown state or system/default apps.
            if (optimizationMode == MODE_OPTIMIZED
                    || optimizationMode == MODE_UNKNOWN //见补充2
                    || isSystemOrDefaultApp(allowlistBackend, info.packageName)) {
                continue;
            }

            // Resets to the default mode: MODE_OPTIMIZED.
            setAppUsageStateInternal(MODE_OPTIMIZED, info.uid, info.packageName, batteryUtils,
                    allowlistBackend);
        }
    }

>1.getAppOptimizationMode

根据app的操作结果mode,以及app是否在白名单里,返回优化模式

    public static int getAppOptimizationMode(int mode, boolean isAllowListed) {
        if (!isAllowListed && mode == AppOpsManager.MODE_IGNORED) {
        //不在白名单,受限
            return MODE_RESTRICTED;
        } else if (isAllowListed && mode == AppOpsManager.MODE_ALLOWED) {
        //在白名单的,不受限
            return MODE_UNRESTRICTED;
        } else if (!isAllowListed && mode == AppOpsManager.MODE_ALLOWED) {
        //不在白名单的,优化
            return MODE_OPTIMIZED;
        } else {
            return MODE_UNKNOWN;
        }
    }

>2.isSystemOrDefaultApp

在系统白名单里,或者是默认的激活应用

    private static boolean isSystemOrDefaultApp(
            PowerAllowlistBackend powerAllowlistBackend, String packageName) {
        return powerAllowlistBackend.isSysAllowlisted(packageName)
                || powerAllowlistBackend.isDefaultActiveApp(packageName);
    }

>3.setAppUsageStateInternal

    private static void setAppUsageStateInternal(
            @OptimizationMode int mode, int uid, String packageName, BatteryUtils batteryUtils,
            PowerAllowlistBackend powerAllowlistBackend) {
        if (mode == MODE_UNKNOWN) {
            return;
        }

        // MODE_RESTRICTED = AppOpsManager.MODE_IGNORED + !allowListed
        // MODE_UNRESTRICTED = AppOpsManager.MODE_ALLOWED + allowListed
        // MODE_OPTIMIZED = AppOpsManager.MODE_ALLOWED + !allowListed
        final int appOpsManagerMode =
                mode == MODE_RESTRICTED ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED;
        final boolean allowListed = mode == MODE_UNRESTRICTED;

        setAppOptimizationModeInternal(appOpsManagerMode, allowListed, uid, packageName,
                    batteryUtils, powerAllowlistBackend);
    }
//
    private static void setAppOptimizationModeInternal(
            int appStandbyMode, boolean allowListed, int uid, String packageName,
            BatteryUtils batteryUtils, PowerAllowlistBackend powerAllowlistBackend) {
        try {//见11.2
            batteryUtils.setForceAppStandby(uid, packageName, appStandbyMode);
            //更新白名单
            if (allowListed) {
                powerAllowlistBackend.addApp(packageName);
            } else {
                powerAllowlistBackend.removeApp(packageName);
            }
        }
    }

11.2.BatteryUtils

>1.setForceAppStandby

    public void setForceAppStandby(int uid, String packageName,
            int mode) {
        // Control whether app could run jobs in the background
        //设置app是否可以在后台运行job的mode
        mAppOpsManager.setMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName, mode);

        ThreadUtils.postOnBackgroundThread(() -> {
            final BatteryDatabaseManager batteryDatabaseManager = BatteryDatabaseManager
                    .getInstance(mContext);
            //更新数据库
            if (mode == AppOpsManager.MODE_IGNORED) {
                batteryDatabaseManager.insertAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
                        uid, packageName, System.currentTimeMillis());
            } else if (mode == AppOpsManager.MODE_ALLOWED) {
                batteryDatabaseManager.deleteAction(AnomalyDatabaseHelper.ActionType.RESTRICTION,
                        uid, packageName);
            }
        });
    }

12.PowerAllowlistBackend

12.1.refreshList

    public void refreshList() {
        mSysAllowlistedApps.clear();
        mAllowlistedApps.clear();
        mDefaultActiveApps.clear();
        if (mDeviceIdleService == null) {
            return;
        }
        try {
            //所有的白名单,包括系统设置的,用户设置的,
            final String[] allowlistedApps = mDeviceIdleService.getFullPowerWhitelist();
            for (String app : allowlistedApps) {
                mAllowlistedApps.add(app);
            }
            //系统设置的白名单,所有模式下退出省电模式
            final String[] sysAllowlistedApps = mDeviceIdleService.getSystemPowerWhitelist();
            for (String app : sysAllowlistedApps) {
                mSysAllowlistedApps.add(app);
            }
            final boolean hasTelephony = mAppContext.getPackageManager().hasSystemFeature(
                    PackageManager.FEATURE_TELEPHONY);
            final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
                    true /* updateIfNeeded */);
            final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(
                    mAppContext);

            if (hasTelephony) {
            //有语音通话功能,添加默认的短信以及拨号应用
                if (defaultSms != null) {
                    mDefaultActiveApps.add(defaultSms.getPackageName());
                }
                if (!TextUtils.isEmpty(defaultDialer)) {
                    mDefaultActiveApps.add(defaultDialer);
                }
            }
        }
    }

>1.DeviceIdleController.java

    /**
     * Package names the system has white-listed to opt out of power save restrictions for
     * all modes.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistApps = new ArrayMap<>();


    /**
     * Package names the user has white-listed to opt out of power save restrictions.
     */
    private final ArrayMap<String, Integer> mPowerSaveWhitelistUserApps = new ArrayMap<>();

12.2.isAllowlisted

在白名单里,或者是默认的活动应用

    public boolean isAllowlisted(String pkg) {
        if (mAllowlistedApps.contains(pkg)) {
            return true;
        }

        if (isDefaultActiveApp(pkg)) {
            return true;
        }

        return false;
    }