Automatic sources dropoff on 2020-06-10 18:32:38.095721
The change is generated with prebuilt drop tool.
Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/com/android/server/pm/ProtectedPackages.java b/com/android/server/pm/ProtectedPackages.java
new file mode 100644
index 0000000..4da3cc3
--- /dev/null
+++ b/com/android/server/pm/ProtectedPackages.java
@@ -0,0 +1,143 @@
+/*
+ * 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.Nullable;
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.os.UserHandle;
+import android.util.SparseArray;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 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
+ @GuardedBy("this")
+ private int mDeviceOwnerUserId;
+
+ @Nullable
+ @GuardedBy("this")
+ private String mDeviceOwnerPackage;
+
+ @Nullable
+ @GuardedBy("this")
+ private SparseArray<String> mProfileOwnerPackages;
+
+ @Nullable
+ @GuardedBy("this")
+ private final String mDeviceProvisioningPackage;
+
+ @Nullable
+ @GuardedBy("this")
+ private List<String> mDeviceOwnerProtectedPackages;
+
+ private final Context mContext;
+
+ public ProtectedPackages(Context context) {
+ mContext = context;
+ mDeviceProvisioningPackage = mContext.getResources().getString(
+ R.string.config_deviceProvisioningPackage);
+ }
+
+ /**
+ * Sets the device/profile owner information.
+ */
+ public synchronized void setDeviceAndProfileOwnerPackages(
+ int deviceOwnerUserId, String deviceOwnerPackage,
+ SparseArray<String> profileOwnerPackages) {
+ mDeviceOwnerUserId = deviceOwnerUserId;
+ mDeviceOwnerPackage =
+ (deviceOwnerUserId == UserHandle.USER_NULL) ? null : deviceOwnerPackage;
+ mProfileOwnerPackages = (profileOwnerPackages == null) ? null
+ : profileOwnerPackages.clone();
+ }
+
+ public synchronized void setDeviceOwnerProtectedPackages(List<String> packageNames) {
+ mDeviceOwnerProtectedPackages = new ArrayList<String>(packageNames);
+ }
+
+ private synchronized boolean hasDeviceOwnerOrProfileOwner(int userId, String packageName) {
+ if (packageName == null) {
+ return false;
+ }
+ if (mDeviceOwnerPackage != null) {
+ if ((mDeviceOwnerUserId == userId)
+ && (packageName.equals(mDeviceOwnerPackage))) {
+ return true;
+ }
+ }
+ if (mProfileOwnerPackages != null) {
+ if (packageName.equals(mProfileOwnerPackages.get(userId))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public synchronized String getDeviceOwnerOrProfileOwnerPackage(int userId) {
+ if (mDeviceOwnerUserId == userId) {
+ return mDeviceOwnerPackage;
+ }
+ if (mProfileOwnerPackages == null) {
+ return null;
+ }
+ return mProfileOwnerPackages.get(userId);
+ }
+
+ /**
+ * Returns {@code true} if a given package is protected. Otherwise, returns {@code false}.
+ *
+ * <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) {
+ return packageName != null && (packageName.equals(mDeviceProvisioningPackage)
+ || ArrayUtils.contains(mDeviceOwnerProtectedPackages, packageName));
+ }
+
+ /**
+ * Returns {@code true} if a given package's state is protected. Otherwise, returns
+ * {@code false}.
+ *
+ * <p>This is not applicable if the caller is the package owner.
+ */
+ public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) {
+ return hasDeviceOwnerOrProfileOwner(userId, packageName)
+ || isProtectedPackage(packageName);
+ }
+
+ /**
+ * Returns {@code true} if a given package's data is protected. Otherwise, returns
+ * {@code false}.
+ */
+ public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) {
+ return hasDeviceOwnerOrProfileOwner(userId, packageName)
+ || isProtectedPackage(packageName);
+ }
+}