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

Commit b6240695 authored by Pavel Grafov's avatar Pavel Grafov Committed by Automerger Merge Worker
Browse files

Merge "Allow profile owners to protect packages." into tm-dev am: 20bd378d

parents 62ccaabe 20bd378d
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -14569,12 +14569,13 @@ public class DevicePolicyManager {
    }
    /**
     * Called by Device owner to disable user control over apps. User will not be able to clear
     * app data or force-stop packages.
     * Called by a device owner or a profile owner to disable user control over apps. User will not
     * be able to clear app data or force-stop packages. When called by a device owner, applies to
     * all users on the device.
     *
     * @param admin which {@link DeviceAdminReceiver} this request is associated with
     * @param packages The package names for the apps.
     * @throws SecurityException if {@code admin} is not a device owner.
     * @throws SecurityException if {@code admin} is not a device owner or a profile owner.
     */
    public void setUserControlDisabledPackages(@NonNull ComponentName admin,
            @NonNull List<String> packages) {
@@ -14589,12 +14590,14 @@ public class DevicePolicyManager {
    }
    /**
     * Returns the list of packages over which user control is disabled by the device owner.
     * Returns the list of packages over which user control is disabled by a device or profile
     * owner.
     *
     * @param admin which {@link DeviceAdminReceiver} this request is associated with
     * @throws SecurityException if {@code admin} is not a device owner.
     * @throws SecurityException if {@code admin} is not a device or profile owner.
     */
    public @NonNull List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) {
    @NonNull
    public List<String> getUserControlDisabledPackages(@NonNull ComponentName admin) {
        throwIfParentInstance("getUserControlDisabledPackages");
        if (mService != null) {
            try {
+3 −3
Original line number Diff line number Diff line
@@ -371,10 +371,10 @@ public abstract class PackageManagerInternal {
            int deviceOwnerUserId, String deviceOwner, SparseArray<String> profileOwners);

    /**
     * Called by Owners to set the package names protected by the device owner.
     * Marks packages as protected for a given user or all users in case of USER_ALL.
     */
    public abstract void setDeviceOwnerProtectedPackages(
            String deviceOwnerPackageName, List<String> packageNames);
    public abstract void setOwnerProtectedPackages(
            @UserIdInt int userId, @NonNull List<String> packageNames);

    /**
     * Returns {@code true} if a given package can't be wiped. Otherwise, returns {@code false}.
+3 −4
Original line number Diff line number Diff line
@@ -352,10 +352,9 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {

    @Override
    @Deprecated
    public final void setDeviceOwnerProtectedPackages(
            String deviceOwnerPackageName, List<String> packageNames) {
        getProtectedPackages().setDeviceOwnerProtectedPackages(
                deviceOwnerPackageName, packageNames);
    public final void setOwnerProtectedPackages(
            @UserIdInt int userId, @NonNull List<String> packageNames) {
        getProtectedPackages().setOwnerProtectedPackages(userId, packageNames);
    }

    @Override
+24 −19
Original line number Diff line number Diff line
@@ -16,11 +16,11 @@

package com.android.server.pm;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Context;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;

@@ -56,7 +56,7 @@ public class ProtectedPackages {

    @Nullable
    @GuardedBy("this")
    private final ArrayMap<String, Set<String>> mDeviceOwnerProtectedPackages = new ArrayMap<>();
    private final SparseArray<Set<String>> mOwnerProtectedPackages = new SparseArray<>();

    private final Context mContext;

@@ -79,13 +79,13 @@ public class ProtectedPackages {
                : profileOwnerPackages.clone();
    }

    /** Sets the protected packages for the device owner. */
    public synchronized void setDeviceOwnerProtectedPackages(
            String deviceOwnerPackageName, List<String> packageNames) {
    /** Sets packages protected by a device or profile owner. */
    public synchronized void setOwnerProtectedPackages(
            @UserIdInt int userId, @NonNull List<String> packageNames) {
        if (packageNames.isEmpty()) {
            mDeviceOwnerProtectedPackages.remove(deviceOwnerPackageName);
            mOwnerProtectedPackages.remove(userId);
        } else {
            mDeviceOwnerProtectedPackages.put(deviceOwnerPackageName, new ArraySet<>(packageNames));
            mOwnerProtectedPackages.put(userId, new ArraySet<>(packageNames));
        }
    }

@@ -123,19 +123,24 @@ public class ProtectedPackages {
     * <p>A protected package means that, apart from the package owner, no system or privileged apps
     * can modify its data or package state.
     */
    private synchronized boolean isProtectedPackage(String packageName) {
    private synchronized boolean isProtectedPackage(@UserIdInt int userId, String packageName) {
        return packageName != null && (packageName.equals(mDeviceProvisioningPackage)
                || isDeviceOwnerProtectedPackage(packageName));
                || isOwnerProtectedPackage(userId, packageName));
    }

    /** Returns {@code true} if the given package is a protected package set by any device owner. */
    private synchronized boolean isDeviceOwnerProtectedPackage(String packageName) {
        for (Set<String> protectedPackages : mDeviceOwnerProtectedPackages.values()) {
            if (protectedPackages.contains(packageName)) {
                return true;
            }
    /**
     * Returns {@code true} if the given package is a protected package set by any device or
     * profile owner.
     */
    private synchronized boolean isOwnerProtectedPackage(
            @UserIdInt int userId, String packageName) {
        return isPackageProtectedForUser(UserHandle.USER_ALL, packageName)
                || isPackageProtectedForUser(userId, packageName);
    }
        return false;

    private synchronized boolean isPackageProtectedForUser(int userId, String packageName) {
        int userIdx = mOwnerProtectedPackages.indexOfKey(userId);
        return userIdx >= 0 && mOwnerProtectedPackages.valueAt(userIdx).contains(packageName);
    }

    /**
@@ -146,7 +151,7 @@ public class ProtectedPackages {
     */
    public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) {
        return hasDeviceOwnerOrProfileOwner(userId, packageName)
                || isProtectedPackage(packageName);
                || isProtectedPackage(userId, packageName);
    }

    /**
@@ -155,6 +160,6 @@ public class ProtectedPackages {
     */
    public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) {
        return hasDeviceOwnerOrProfileOwner(userId, packageName)
                || isProtectedPackage(packageName);
                || isProtectedPackage(userId, packageName);
    }
}
+24 −22
Original line number Diff line number Diff line
@@ -3116,6 +3116,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            deleteTransferOwnershipBundleLocked(metadata.userId);
        }
        updateSystemUpdateFreezePeriodsRecord(/* saveIfChanged */ true);
        pushUserControlDisabledPackagesLocked(metadata.userId);
    }
    private void maybeLogStart() {
@@ -3178,18 +3179,22 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        startOwnerService(userId, "start-user");
    }
    // TODO(b/218639412): Once PM stores these on a per-user basis, push even empty lists to handle
    // DO/PO removal correctly.
    void pushUserControlDisabledPackagesLocked(int userId) {
        if (userId != mOwners.getDeviceOwnerUserId()) {
            return;
        }
        ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
        if (deviceOwner == null || deviceOwner.protectedPackages == null) {
            return;
        final int targetUserId;
        final ActiveAdmin owner;
        if (getDeviceOwnerUserIdUncheckedLocked() == userId) {
            owner = getDeviceOwnerAdminLocked();
            targetUserId = UserHandle.USER_ALL;
        } else {
            owner = getProfileOwnerAdminLocked(userId);
            targetUserId = userId;
        }
        mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages(
                deviceOwner.info.getPackageName(), deviceOwner.protectedPackages);
        List<String> protectedPackages = (owner == null || owner.protectedPackages == null)
                ? Collections.emptyList() : owner.protectedPackages;
        mInjector.binderWithCleanCallingIdentity(() ->
                mInjector.getPackageManagerInternal().setOwnerProtectedPackages(
                        targetUserId, protectedPackages));
    }
    @Override
@@ -16967,23 +16972,20 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        Objects.requireNonNull(who, "ComponentName is null");
        Objects.requireNonNull(packages, "packages is null");
        final CallerIdentity caller = getCallerIdentity(who);
        Preconditions.checkCallAuthorization(
                isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller));
        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller)
                || isFinancedDeviceOwner(caller));
        checkCanExecuteOrThrowUnsafe(
                DevicePolicyManager.OPERATION_SET_USER_CONTROL_DISABLED_PACKAGES);
        synchronized (getLockObject()) {
            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
            if (!Objects.equals(deviceOwner.protectedPackages, packages)) {
                deviceOwner.protectedPackages = packages.isEmpty() ? null : packages;
            ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId());
            if (!Objects.equals(owner.protectedPackages, packages)) {
                owner.protectedPackages = packages.isEmpty() ? null : packages;
                saveSettingsLocked(caller.getUserId());
                pushUserControlDisabledPackagesLocked(caller.getUserId());
            }
        }
        mInjector.binderWithCleanCallingIdentity(
                () -> mInjector.getPackageManagerInternal().setDeviceOwnerProtectedPackages(
                        who.getPackageName(), packages));
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_USER_CONTROL_DISABLED_PACKAGES)
                .setAdmin(who)
@@ -16996,11 +16998,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        Objects.requireNonNull(who, "ComponentName is null");
        final CallerIdentity caller = getCallerIdentity(who);
        Preconditions.checkCallAuthorization(
                isDefaultDeviceOwner(caller) || isFinancedDeviceOwner(caller));
        Preconditions.checkCallAuthorization(isDefaultDeviceOwner(caller) || isProfileOwner(caller)
                || isFinancedDeviceOwner(caller));
        synchronized (getLockObject()) {
            ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
            ActiveAdmin deviceOwner = getDeviceOrProfileOwnerAdminLocked(caller.getUserId());
            return deviceOwner.protectedPackages != null
                    ? deviceOwner.protectedPackages : Collections.emptyList();
        }
Loading