Allow disabling non-system device admins

In safe mode, PM.queryXxx() doesn't return non-system apps.
Use IPM.getReceiverInfo() instead.

Bug 27108276

Change-Id: I391a41eb07e414ba224a808a362125912b177de2
This commit is contained in:
Makoto Onuki
2016-02-24 12:56:44 -08:00
parent e50ed4ac72
commit 7cdaa52161

View File

@@ -18,6 +18,7 @@ package com.android.settings;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AppGlobals;
import android.app.ListFragment; import android.app.ListFragment;
import android.app.admin.DeviceAdminInfo; import android.app.admin.DeviceAdminInfo;
import android.app.admin.DeviceAdminReceiver; import android.app.admin.DeviceAdminReceiver;
@@ -27,11 +28,15 @@ import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.util.Log; import android.util.Log;
@@ -356,7 +361,7 @@ public class DeviceAdminSettings extends ListFragment {
resolveInfo.activityInfo.name); resolveInfo.activityInfo.name);
if (alreadyAddedComponents == null if (alreadyAddedComponents == null
|| !alreadyAddedComponents.contains(riComponentName)) { || !alreadyAddedComponents.contains(riComponentName)) {
DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolveInfo); DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolveInfo.activityInfo);
// add only visible ones (note: active admins are added regardless of visibility) // add only visible ones (note: active admins are added regardless of visibility)
if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) { if (deviceAdminInfo != null && deviceAdminInfo.isVisible()) {
if (!deviceAdminInfo.getActivityInfo().applicationInfo.isInternal()) { if (!deviceAdminInfo.getActivityInfo().applicationInfo.isInternal()) {
@@ -383,20 +388,27 @@ public class DeviceAdminSettings extends ListFragment {
final int profileId) { final int profileId) {
if (activeAdmins != null) { if (activeAdmins != null) {
final PackageManager packageManager = getActivity().getPackageManager(); final PackageManager packageManager = getActivity().getPackageManager();
final IPackageManager iPackageManager = AppGlobals.getPackageManager();
final int n = activeAdmins.size(); final int n = activeAdmins.size();
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
ComponentName activeAdmin = activeAdmins.get(i); final ComponentName activeAdmin = activeAdmins.get(i);
List<ResolveInfo> resolved = packageManager.queryBroadcastReceiversAsUser( final ActivityInfo ai;
new Intent().setComponent(activeAdmin), PackageManager.GET_META_DATA try {
| PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS, profileId); ai = iPackageManager.getReceiverInfo(activeAdmin,
if (resolved != null) { PackageManager.GET_META_DATA |
final int resolvedMax = resolved.size(); PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
for (int j = 0; j < resolvedMax; ++j) { PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, profileId);
DeviceAdminInfo deviceAdminInfo = createDeviceAdminInfo(resolved.get(j)); } catch (RemoteException e) {
if (deviceAdminInfo != null) { 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 // Don't do the applicationInfo.isInternal() check here; if an active
// admin is already on SD card, just show it. // admin is already on SD card, just show it.
DeviceAdminListItem item = new DeviceAdminListItem(); final DeviceAdminListItem item = new DeviceAdminListItem();
item.info = deviceAdminInfo; item.info = deviceAdminInfo;
item.name = deviceAdminInfo.loadLabel(packageManager).toString(); item.name = deviceAdminInfo.loadLabel(packageManager).toString();
item.active = true; item.active = true;
@@ -404,24 +416,19 @@ public class DeviceAdminSettings extends ListFragment {
} }
} }
} }
}
}
}
/** /**
* Creates a device admin info object for the resolved intent that points to the component of * Creates a device admin info object for the resolved intent that points to the component of
* the device admin. * the device admin.
* *
* @param resolved resolved intent. * @param ai ActivityInfo for the admin component.
* @return new {@link DeviceAdminInfo} object or null if there was an error. * @return new {@link DeviceAdminInfo} object or null if there was an error.
*/ */
private DeviceAdminInfo createDeviceAdminInfo(ResolveInfo resolved) { private DeviceAdminInfo createDeviceAdminInfo(ActivityInfo ai) {
try { try {
return new DeviceAdminInfo(getActivity(), resolved); return new DeviceAdminInfo(getActivity(), ai);
} catch (XmlPullParserException e) { } catch (XmlPullParserException|IOException e) {
Log.w(TAG, "Skipping " + resolved.activityInfo, e); Log.w(TAG, "Skipping " + ai, e);
} catch (IOException e) {
Log.w(TAG, "Skipping " + resolved.activityInfo, e);
} }
return null; return null;
} }