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

Commit 78f16950 authored by Makoto Onuki's avatar Makoto Onuki Committed by android-build-merger
Browse files

Merge \"Push DO/PO package names from DPMS to PM\" into nyc-dev

am: f419bd9e

Change-Id: Ic3071f3a712da72fd141ef37ac6aabe6dbd09355
parents 05157de8 f419bd9e
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.app.admin;

import android.content.Intent;
import android.os.UserHandle;

import java.util.List;

@@ -73,17 +72,6 @@ public abstract class DevicePolicyManagerInternal {
     */
    public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy);

    /**
     * Checks if a given package has a device or a profile owner for the given user.
     * <p>
     * <em>Note: does <b>not</b> support negative userIds like {@link UserHandle#USER_ALL}</em>
     *
     * @param packageName The package to check
     * @param userId the userId to check for.
     * @return true if package has a device or profile owner, false otherwise.
     */
    public abstract boolean hasDeviceOwnerOrProfileOwner(String packageName, int userId);

    /**
     * Creates an intent to show the admin support dialog to let the user know that the package is
     * suspended by the admin. This assumes that {@param packageName} is suspended by the
+13 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.content.pm;

import android.content.ComponentName;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.SparseArray;

import java.util.List;

@@ -147,4 +148,16 @@ public abstract class PackageManagerInternal {
     */
    public abstract ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
            int userId);

    /**
     * Called by DeviceOwnerManagerService to set the package names of device owner and profile
     * owners.
     */
    public abstract void setDeviceAndProfileOwnerPackages(
            int deviceOwnerUserId, String deviceOwner, SparseArray<String> profileOwners);

    /**
     * Whether a package's data be cleared.
     */
    public abstract boolean canPackageBeWiped(int userId, String packageName);
}
+6 −5
Original line number Diff line number Diff line
@@ -5375,17 +5375,18 @@ public final class ActivityManagerService extends ActivityManagerNative
        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
        final DevicePolicyManagerInternal dpmi = LocalServices
                .getService(DevicePolicyManagerInternal.class);
        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
        }
        long callingId = Binder.clearCallingIdentity();
        try {
            IPackageManager pm = AppGlobals.getPackageManager();
            int pkgUid = -1;
            synchronized(this) {
                if (getPackageManagerInternalLocked().canPackageBeWiped(
                        userId, packageName)) {
                    throw new SecurityException(
                            "Cannot clear data for a device owner or a profile owner");
                }
                try {
                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
                } catch (RemoteException e) {
+20 −8
Original line number Diff line number Diff line
@@ -102,11 +102,11 @@ import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCES
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.ResourcesManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
import android.app.admin.SecurityLog;
import android.app.backup.IBackupManager;
@@ -622,6 +622,8 @@ public class PackageManagerService extends IPackageManager.Stub {
    @GuardedBy("mPackages")
    final ArraySet<String> mFrozenPackages = new ArraySet<>();
    final ProtectedPackages mProtectedPackages = new ProtectedPackages();
    boolean mRestoredSettings;
    // System configuration read by SystemConfig.
@@ -16400,9 +16402,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */, "clear application data");
        final DevicePolicyManagerInternal dpmi = LocalServices
                .getService(DevicePolicyManagerInternal.class);
        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
        if (mProtectedPackages.canPackageBeWiped(userId, packageName)) {
            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
        }
        // Queue up an async operation since the package deletion may take a little while.
@@ -17729,10 +17729,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                        + Binder.getCallingPid()
                        + ", uid=" + uid + ", package uid=" + pkgSetting.appId);
            }
            // Don't allow changing profile and device owners. Calling into DPMS, so no locking.
            final DevicePolicyManagerInternal dpmi = LocalServices
                    .getService(DevicePolicyManagerInternal.class);
            if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
            // Don't allow changing profile and device owners.
            if (mProtectedPackages.canPackageStateBeChanged(userId, packageName)) {
                throw new SecurityException("Cannot disable a device owner or a profile owner");
            }
        }
@@ -20829,6 +20827,20 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                int userId) {
            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
        }
        @Override
        public void setDeviceAndProfileOwnerPackages(
                int deviceOwnerUserId, String deviceOwnerPackage,
                SparseArray<String> profileOwnerPackages) {
            mProtectedPackages.setDeviceAndProfileOwnerPackages(
                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
        }
        @Override
        public boolean canPackageBeWiped(int userId, String packageName) {
            return mProtectedPackages.canPackageBeWiped(userId,
                    packageName);
        }
    }
    @Override
+89 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm;

import android.annotation.UserIdInt;
import android.os.UserHandle;
import android.util.SparseArray;

/**
 * Manages package names that need special protection.
 *
 * TODO: This class should persist the information by itself, and also keeps track of device admin
 * packages for all users.  Then PMS.isPackageDeviceAdmin() should use it instead of talking
 * to DPMS.
 */
public class ProtectedPackages {
    @UserIdInt
    private int mDeviceOwnerUserId;

    private String mDeviceOwnerPackage;

    private SparseArray<String> mProfileOwnerPackages;

    private final Object mLock = new Object();

    /**
     * Sets the device/profile owner information.
     */
    public void setDeviceAndProfileOwnerPackages(
            int deviceOwnerUserId, String deviceOwnerPackage,
            SparseArray<String> profileOwnerPackages) {
        synchronized (mLock) {
            mDeviceOwnerUserId = deviceOwnerUserId;
            mDeviceOwnerPackage =
                    (deviceOwnerUserId == UserHandle.USER_NULL) ? null : deviceOwnerPackage;
            mProfileOwnerPackages = (profileOwnerPackages == null) ? null
                    : profileOwnerPackages.clone();
        }
    }

    private boolean hasDeviceOwnerOrProfileOwner(int userId, String packageName) {
        if (packageName == null) {
            return false;
        }
        synchronized (mLock) {
            if (mDeviceOwnerPackage != null) {
                if ((mDeviceOwnerUserId == userId)
                        && (packageName.equals(mDeviceOwnerPackage))) {
                    return true;
                }
            }
            if (mProfileOwnerPackages != null) {
                if (packageName.equals(mProfileOwnerPackages.get(userId))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Whether a package or the components in a package's enabled state can be changed
     * by other callers than itself.
     */
    public boolean canPackageStateBeChanged(@UserIdInt int userId, String packageName) {
        return hasDeviceOwnerOrProfileOwner(userId, packageName);
    }

    /**
     * Whether a package's data be cleared.
     */
    public boolean canPackageBeWiped(@UserIdInt int userId, String packageName) {
        return hasDeviceOwnerOrProfileOwner(userId, packageName);
    }
}
Loading