通过DeviceAdminSettings.java的addAc。设备管理应用"界面列表中应用的激活状态是通过DevicePolicyManager的isAdminActiveAsUser()方法获取的。" />

设备管理应用"界面列表中应用的激活状态是通过DevicePolicyManager的isAdminActiveAsUser()方法获取的

"设备管理应用"界面列表中应用的激活状态是通过DevicePolicyManager的isAdminActiveAsUser()方法获取的设置中,"设备管理应用"界面应用列表数据加载逻辑如下:> 通过DeviceAdminSettings.java的addActiveAdminsForProfile()和addDeviceAdminBroadcastReceiversForProfile()方法获取应用列表:packages/apps/Settings/src/com/android/settings/DeviceAdminSettings.javaprivate void updateAvailableAdminsForProfile(final int profileId) { // We are adding the union of two sets 'A' and 'B' of device admins to mAvailableAdmins. // Set 'A' is the set of active admins for the profile whereas set 'B' is the set of // listeners to DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED for the profile.// Add all of set 'A' to mAvailableAdmins. List activeAdminsListForProfile = mDPM.getActiveAdminsAsUser(profileId); addActiveAdminsForProfile(activeAdminsListForProfile, profileId); // Collect set 'B' and add B-A to mAvailableAdmins. addDeviceAdminBroadcastReceiversForProfile(activeAdminsListForProfile, profileId); }>获取显示的应用列表.private void addActiveAdminsForProfile(final List activeAdmins, final int profileId) { if (activeAdmins != null) { final PackageManager packageManager = getActivity().getPackageManager(); final IPackageManager iPackageManager = AppGlobals.getPackageManager(); final int n = activeAdmins.size(); for (int i = 0; i < n; ++i) { final ComponentName activeAdmin = activeAdmins.get(i); final ActivityInfo ai; try { ai = iPackageManager.getReceiverInfo(activeAdmin, PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DIRECT_BOOT_AWARE, profileId); } catch (RemoteException e) { Log.w(TAG, "Unable to load component: " + activeAdmin); continue; } final DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(ai); if (deviceAdminInfo == null) { continue; } // Don't do the applicationInfo.isInternal() check here; if an active // admin is already on SD card, just show it. final DeviceAdminListItem item = new DeviceAdminListItem(); item.info = deviceAdminInfo; item.name = deviceAdminInfo.loadLabel(packageManager).toString(); item.active = true; mAdmins.add(item); } } }private void addDeviceAdminBroadcastReceiversForProfile( Collection alreadyAddedComponents, final int profileId) { final PackageManager pm = getActivity().getPackageManager(); List enabledForProfile = pm.queryBroadcastReceiversAsUser( new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, profileId); if (enabledForProfile == null) { enabledForProfile = Collections.emptyList(); } final int n = enabledForProfile.size(); for (int i = 0; i < n; ++i) { ResolveInfo resolveInfo = enabledForProfile.get(i); ComponentName riComponentName = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name); if (alreadyAddedComponents == null || !alreadyAddedComponents.contains(riComponentName)) { DeviceAdminInfo deviceAdminInfo =createDeviceAdminInfo(resolveInfo.activityInfo); // add only visible ones (note: active admins are added regardless of visibility) if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) { if (!deviceAdminInfo.getActivityInfo().applicationInfo.isInternal()) { continue; } DeviceAdminListItem item = new DeviceAdminListItem(); item.info = deviceAdminInfo; item.name = deviceAdminInfo.loadLabel(pm).toString(); // Active ones already added. item.active = false; mAdmins.add(item); } } } }> 通过DeviceAdminSettings.java的isActiveAdmin()方法获取应用激活状态:private boolean isActiveAdmin(DeviceAdminInfo item) { return mDPM.isAdminActiveAsUser(item.getComponent(), getUserId(item)); }> 设置中调用mDPM.getActiveAdminsAsUser(profileId)来确定列表的数目,该接口是DevicePolicyManager通过Binder调用DeviceManagerService.java中的接口 进入frameworks/base/core/java/android/app/admin/DevicePolicyManager.java public @Nullable List getActiveAdminsAsUser(int userId) { 1609if (mService != null) { 1610try { 1611return mService.getActiveAdmins(userId); 1612} catch (RemoteException e) { 1613throw e.rethrowFromSystemServer(); 1614}> 跟踪mService.getActiveAdmins(userId)进入frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @SuppressWarnings("unchecked") 3280public List getActiveAdmins(int userHandle) { 3281if (!mHasFeature) { 3282return Collections.EMPTY_LIST; 3283} 3284 3285enforceFullCrossUsersPermission(userHandle); 3286synchronized (this) { 3287DevicePolicyData policy = getUserData(userHandle); 3288final int N = policy.mAdminList.size(); 3289if (N <= 0) { 3290return null; 3291} 3292ArrayList res = new ArrayList(N); 3293for (int i=0; i从本地的List里面复制了一份给返回,在这个文件里就找到了两处add:一处在 setActiveAdmin,一致在 loadSettingsLocked ,setActiveAdmin发现他是一个hide的借口存在于Manager类上,第三发的应用是不能调到的,在loadSettingsLocked。在这个函数里面在做xml的parser.代码比较长,不全列出来 private void saveSettingsLocked(int userHandle) { 2511DevicePolicyData policy = getUserData(userHandle); 2512JournaledFile journal = makeJournaledFile(userHandle); 2513FileOutputStream stream = null; 2514try { 2515stream = new FileOutputStream(journal.chooseForWrite(), false); 2516XmlSerializer out = new FastXmlSerializer(); 2517out.setOutput(stream, StandardCharsets.UTF_8.name()); 2518out.startDocument(null, true); 2519 2520out.startTag(null, "policies"); 2521if (policy.mRestrictionsProvider != null) { 2522out.attribute(null, ATTR_PERMISSION_PROVIDER, 2523policy.mRestrictionsProvider.flattenToString()); >从上面代码可以看出,JournaledFile journal = makeJournaledFile(userHandle)加载需要解析的xml文件,进入该函数发现需要解析的xml文件为device_policies.xml private static final String DEVICE_POLICIES_XML = "device_policies.xml"; private JournaledFile makeJournaledFile(int userHandle) { 2500final String base = userHandle == UserHandle.USER_SYSTEM 2501? mInjector.getDevicePolicyFilePathForSystemUser() + DEVICE_POLICIES_XML 2502: new File(mInjector.environmentGetUserSystemDirectory(userHandle), 2503DEVICE_POLICIES_XML).getAbsolutePath(); 2504if (VERBOSE_LOG) { 2505Log.v(LOG_TAG, "Opening " + base); 2506} 2507return new JournaledFile(new File(base), new File(base + ".tmp")); 2508} >综上,显示列表是DeviceManagerService.java来解析device_policies.xml文件,并非通过配置文件或者增加功能来显示的.>列表选项是否默认,Settings中通过DeviceAdminSettings.java的isActiveAdmin()方法获取应用激活状态: private boolean isActiveAdmin(DeviceAdminInfo item) { return mDPM.isAdminActiveAsUser(item.getComponent(), getUserId(item)); } > 跟踪mDPM.isAdminActiveAsUser(item.getComponent(), getUserId(item)); 进入frameworks/base/core/java/android/app/admin/DevicePolicyManager.java567public boolean isAdminActiveAsUser(@NonNull ComponentName admin, int userId) { 1568if (mService != null) { 1569try { 1570return mService.isAdminActive(admin, userId); 1571} catch (RemoteException e) { 1572throw e.rethrowFromSystemServer(); 1573} 1574} 1575return false; 1576}>同理,通过Binder机制,进入DeviceMangerService.java文件中发现调用的是getActiveAdminUncheckedLocked(adminReceiver, userHandle)接口,进一步跟踪进入. 3241public boolean isAdminActive(ComponentName adminReceiver, int userHandle) { 3242if (!mHasFeature) { 3243return false; 3244} 3245enforceFullCrossUsersPermission(userHandle); 3246synchronized (this) { 3247return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null; 3248} 3249}> 查看传入的参数在mAdminMap中是否存在. 9ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) { 2250ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who); 2251if (admin != null 2252&& who.getPackageName().equals(admin.info.getActivityInfo().packageName) 2253&& who.getClassName().equals(admin.info.getActivityInfo().name)) { 2254return admin; 2255} 2256return null; 2257}> 我们来查看谁向mAdminMap中写入参数.查看在 loadSettingsLocked接口中有mAdminMap.put操作,由如下代码来看,是通过解析device_policy.xml来决定是否默认选中的. private void loadSettingsLocked(DevicePolicyData policy, int userHandle) { 2708JournaledFile journal = makeJournaledFile(userHandle); 2709FileInputStream stream = null; 2710File file = journal.chooseForRead(); 2711boolean needsRewrite = false; 2712try { 2713stream = new FileInputStream(file); 2714XmlPullParser parser = Xml.newPullParser(); 2715parser.setInput(stream, StandardCharsets.UTF_8.name()); 2716 ... ... + userHandle); 2810} 2811if (dai != null) { 2812ActiveAdmin ap = new ActiveAdmin(dai, /* parent */ false); 2813ap.readFromXml(parser); 2814policy.mAdminMap.put(ap.info.getComponent(), ap); 2815} 2816} catch (RuntimeException e) { 2817Slog.w(LOG_TAG, "Failed loading admin " + name, e); 2818}> 综上所述,该界面显示的列表已经相应列表是否默认选中,都是通过解析device_policy.xml文件来决定的,并非是某个配置文件通过简单修改即可. 该机制为Android 原生机制,强制修改存在不可控风险

    推荐阅读