Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 889c0880 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Support safe mode properly.

In safe mode, IPM.queryXxx() doesn't work.  Use IPM.getReceiverInfo()
directly instead.

Bug 27108276

Change-Id: Ice8f882559b8f0596a19ddb3a16395a4dc538a25
parent eefb17ac
Loading
Loading
Loading
Loading
+35 −28
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ public final class DeviceAdminInfo implements Parcelable {
    /**
     * The BroadcastReceiver that implements this device admin component.
     */
    final ResolveInfo mReceiver;
    final ActivityInfo mActivityInfo;

    /**
     * Whether this should be visible to the user.
@@ -252,29 +252,42 @@ public final class DeviceAdminInfo implements Parcelable {
     */
    int mUsesPolicies;


    /**
     * Constructor.
     *
     * @param context The Context in which we are parsing the device admin.
     * @param resolveInfo The ResolveInfo returned from the package manager about
     * this device admin's component.
     */
    public DeviceAdminInfo(Context context, ResolveInfo resolveInfo)
            throws XmlPullParserException, IOException {
        this(context, resolveInfo.activityInfo);
    }
    /**
     * Constructor.
     *
     * @param context The Context in which we are parsing the device admin.
     * @param receiver The ResolveInfo returned from the package manager about
     * @param activityInfo The ActivityInfo returned from the package manager about
     * this device admin's component.
     *
     * @hide
     */
    public DeviceAdminInfo(Context context, ResolveInfo receiver)
    public DeviceAdminInfo(Context context, ActivityInfo activityInfo)
            throws XmlPullParserException, IOException {
        mReceiver = receiver;
        ActivityInfo ai = receiver.activityInfo;
        mActivityInfo = activityInfo;

        PackageManager pm = context.getPackageManager();

        XmlResourceParser parser = null;
        try {
            parser = ai.loadXmlMetaData(pm, DeviceAdminReceiver.DEVICE_ADMIN_META_DATA);
            parser = mActivityInfo.loadXmlMetaData(pm, DeviceAdminReceiver.DEVICE_ADMIN_META_DATA);
            if (parser == null) {
                throw new XmlPullParserException("No "
                        + DeviceAdminReceiver.DEVICE_ADMIN_META_DATA + " meta-data");
            }

            Resources res = pm.getResourcesForApplication(ai.applicationInfo);
            Resources res = pm.getResourcesForApplication(mActivityInfo.applicationInfo);

            AttributeSet attrs = Xml.asAttributeSet(parser);

@@ -324,14 +337,14 @@ public final class DeviceAdminInfo implements Parcelable {
            }
        } catch (NameNotFoundException e) {
            throw new XmlPullParserException(
                    "Unable to create context for: " + ai.packageName);
                    "Unable to create context for: " + mActivityInfo.packageName);
        } finally {
            if (parser != null) parser.close();
        }
    }

    DeviceAdminInfo(Parcel source) {
        mReceiver = ResolveInfo.CREATOR.createFromParcel(source);
        mActivityInfo = ActivityInfo.CREATOR.createFromParcel(source);
        mUsesPolicies = source.readInt();
    }

@@ -339,7 +352,7 @@ public final class DeviceAdminInfo implements Parcelable {
     * Return the .apk package that implements this device admin.
     */
    public String getPackageName() {
        return mReceiver.activityInfo.packageName;
        return mActivityInfo.packageName;
    }

    /**
@@ -347,7 +360,7 @@ public final class DeviceAdminInfo implements Parcelable {
     * this device admin.
     */
    public String getReceiverName() {
        return mReceiver.activityInfo.name;
        return mActivityInfo.name;
    }

    /**
@@ -355,7 +368,7 @@ public final class DeviceAdminInfo implements Parcelable {
     * device admin.  Do not modify the returned object.
     */
    public ActivityInfo getActivityInfo() {
        return mReceiver.activityInfo;
        return mActivityInfo;
    }

    /**
@@ -363,8 +376,8 @@ public final class DeviceAdminInfo implements Parcelable {
     */
    @NonNull
    public ComponentName getComponent() {
        return new ComponentName(mReceiver.activityInfo.packageName,
                mReceiver.activityInfo.name);
        return new ComponentName(mActivityInfo.packageName,
                mActivityInfo.name);
    }

    /**
@@ -374,7 +387,7 @@ public final class DeviceAdminInfo implements Parcelable {
     * resources.
     */
    public CharSequence loadLabel(PackageManager pm) {
        return mReceiver.loadLabel(pm);
        return mActivityInfo.loadLabel(pm);
    }

    /**
@@ -384,15 +397,9 @@ public final class DeviceAdminInfo implements Parcelable {
     * resources.
     */
    public CharSequence loadDescription(PackageManager pm) throws NotFoundException {
        if (mReceiver.activityInfo.descriptionRes != 0) {
            String packageName = mReceiver.resolvePackageName;
            ApplicationInfo applicationInfo = null;
            if (packageName == null) {
                packageName = mReceiver.activityInfo.packageName;
                applicationInfo = mReceiver.activityInfo.applicationInfo;
            }
            return pm.getText(packageName,
                    mReceiver.activityInfo.descriptionRes, applicationInfo);
        if (mActivityInfo.descriptionRes != 0) {
            return pm.getText(mActivityInfo.packageName,
                    mActivityInfo.descriptionRes, mActivityInfo.applicationInfo);
        }
        throw new NotFoundException();
    }
@@ -404,7 +411,7 @@ public final class DeviceAdminInfo implements Parcelable {
     * resources.
     */
    public Drawable loadIcon(PackageManager pm) {
        return mReceiver.loadIcon(pm);
        return mActivityInfo.loadIcon(pm);
    }

    /**
@@ -464,12 +471,12 @@ public final class DeviceAdminInfo implements Parcelable {

    public void dump(Printer pw, String prefix) {
        pw.println(prefix + "Receiver:");
        mReceiver.dump(pw, prefix + "  ");
        mActivityInfo.dump(pw, prefix + "  ");
    }

    @Override
    public String toString() {
        return "DeviceAdminInfo{" + mReceiver.activityInfo.name + "}";
        return "DeviceAdminInfo{" + mActivityInfo.name + "}";
    }

    /**
@@ -479,7 +486,7 @@ public final class DeviceAdminInfo implements Parcelable {
     * @param flags The flags used for parceling.
     */
    public void writeToParcel(Parcel dest, int flags) {
        mReceiver.writeToParcel(dest, flags);
        mActivityInfo.writeToParcel(dest, flags);
        dest.writeInt(mUsesPolicies);
    }

+0 −25
Original line number Diff line number Diff line
@@ -3139,31 +3139,6 @@ public class DevicePolicyManager {
        setActiveAdmin(policyReceiver, refreshing, myUserId());
    }

    /**
     * Returns the DeviceAdminInfo as defined by the administrator's package info & meta-data
     * @hide
     */
    public DeviceAdminInfo getAdminInfo(@NonNull ComponentName cn) {
        ActivityInfo ai;
        try {
            ai = mContext.getPackageManager().getReceiverInfo(cn,
                    PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Unable to retrieve device policy " + cn, e);
            return null;
        }

        ResolveInfo ri = new ResolveInfo();
        ri.activityInfo = ai;

        try {
            return new DeviceAdminInfo(mContext, ri);
        } catch (XmlPullParserException | IOException e) {
            Log.w(TAG, "Unable to parse device policy " + cn, e);
            return null;
        }
    }

    /**
     * @hide
     */
+13 −13
Original line number Diff line number Diff line
@@ -2053,31 +2053,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            return null;
        }
        enforceFullCrossUsersPermission(userHandle);
        Intent resolveIntent = new Intent();
        resolveIntent.setComponent(adminName);
        List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceiversAsUser(
                resolveIntent,
                PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
                PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE,
                userHandle);
        if (infos == null || infos.size() <= 0) {
        ActivityInfo ai = null;
        try {
            ai = mIPackageManager.getReceiverInfo(adminName,
                    PackageManager.GET_META_DATA |
                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS |
                    PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE, userHandle);
        } catch (RemoteException e) {
            // shouldn't happen.
        }
        if (ai == null) {
            throw new IllegalArgumentException("Unknown admin: " + adminName);
        }

        final ResolveInfo ri = infos.get(0);

        if (!permission.BIND_DEVICE_ADMIN.equals(ri.activityInfo.permission)) {
        if (!permission.BIND_DEVICE_ADMIN.equals(ai.permission)) {
            final String message = "DeviceAdminReceiver " + adminName + " must be protected with "
                    + permission.BIND_DEVICE_ADMIN;
            Slog.w(LOG_TAG, message);
            if (throwForMissiongPermission &&
                    ri.activityInfo.applicationInfo.targetSdkVersion > Build.VERSION_CODES.M) {
                    ai.applicationInfo.targetSdkVersion > Build.VERSION_CODES.M) {
                throw new IllegalArgumentException(message);
            }
        }

        try {
            return new DeviceAdminInfo(mContext, ri);
            return new DeviceAdminInfo(mContext, ai);
        } catch (XmlPullParserException | IOException e) {
            Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName,
                    e);
+4 −2
Original line number Diff line number Diff line
@@ -154,8 +154,10 @@ public abstract class DpmTestBase extends AndroidTestCase {
        aci.packageName = admin.getPackageName();
        aci.name = admin.getClassName();

        doReturn(realResolveInfo).when(mMockContext.packageManager).queryBroadcastReceiversAsUser(
                MockUtils.checkIntentComponent(admin),
        // Note we don't set up queryBroadcastReceivers.  We don't use it in DPMS.

        doReturn(aci).when(mMockContext.ipackageManager).getReceiverInfo(
                eq(admin),
                anyInt(),
                eq(UserHandle.getUserId(packageUid)));