blob: 4da3cc3be514a2bf8561b6593fed13231f7a34e8 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import android.annotation.Nullable;
20import android.annotation.UserIdInt;
21import android.content.Context;
22import android.os.UserHandle;
23import android.util.SparseArray;
24
25import com.android.internal.R;
26import com.android.internal.annotations.GuardedBy;
27import com.android.internal.util.ArrayUtils;
28
29import java.util.ArrayList;
30import java.util.List;
31
32/**
33 * Manages package names that need special protection.
34 *
35 * TODO: This class should persist the information by itself, and also keeps track of device admin
36 * packages for all users. Then PMS.isPackageDeviceAdmin() should use it instead of talking
37 * to DPMS.
38 */
39public class ProtectedPackages {
40 @UserIdInt
41 @GuardedBy("this")
42 private int mDeviceOwnerUserId;
43
44 @Nullable
45 @GuardedBy("this")
46 private String mDeviceOwnerPackage;
47
48 @Nullable
49 @GuardedBy("this")
50 private SparseArray<String> mProfileOwnerPackages;
51
52 @Nullable
53 @GuardedBy("this")
54 private final String mDeviceProvisioningPackage;
55
56 @Nullable
57 @GuardedBy("this")
58 private List<String> mDeviceOwnerProtectedPackages;
59
60 private final Context mContext;
61
62 public ProtectedPackages(Context context) {
63 mContext = context;
64 mDeviceProvisioningPackage = mContext.getResources().getString(
65 R.string.config_deviceProvisioningPackage);
66 }
67
68 /**
69 * Sets the device/profile owner information.
70 */
71 public synchronized void setDeviceAndProfileOwnerPackages(
72 int deviceOwnerUserId, String deviceOwnerPackage,
73 SparseArray<String> profileOwnerPackages) {
74 mDeviceOwnerUserId = deviceOwnerUserId;
75 mDeviceOwnerPackage =
76 (deviceOwnerUserId == UserHandle.USER_NULL) ? null : deviceOwnerPackage;
77 mProfileOwnerPackages = (profileOwnerPackages == null) ? null
78 : profileOwnerPackages.clone();
79 }
80
81 public synchronized void setDeviceOwnerProtectedPackages(List<String> packageNames) {
82 mDeviceOwnerProtectedPackages = new ArrayList<String>(packageNames);
83 }
84
85 private synchronized boolean hasDeviceOwnerOrProfileOwner(int userId, String packageName) {
86 if (packageName == null) {
87 return false;
88 }
89 if (mDeviceOwnerPackage != null) {
90 if ((mDeviceOwnerUserId == userId)
91 && (packageName.equals(mDeviceOwnerPackage))) {
92 return true;
93 }
94 }
95 if (mProfileOwnerPackages != null) {
96 if (packageName.equals(mProfileOwnerPackages.get(userId))) {
97 return true;
98 }
99 }
100 return false;
101 }
102
103 public synchronized String getDeviceOwnerOrProfileOwnerPackage(int userId) {
104 if (mDeviceOwnerUserId == userId) {
105 return mDeviceOwnerPackage;
106 }
107 if (mProfileOwnerPackages == null) {
108 return null;
109 }
110 return mProfileOwnerPackages.get(userId);
111 }
112
113 /**
114 * Returns {@code true} if a given package is protected. Otherwise, returns {@code false}.
115 *
116 * <p>A protected package means that, apart from the package owner, no system or privileged apps
117 * can modify its data or package state.
118 */
119 private synchronized boolean isProtectedPackage(String packageName) {
120 return packageName != null && (packageName.equals(mDeviceProvisioningPackage)
121 || ArrayUtils.contains(mDeviceOwnerProtectedPackages, packageName));
122 }
123
124 /**
125 * Returns {@code true} if a given package's state is protected. Otherwise, returns
126 * {@code false}.
127 *
128 * <p>This is not applicable if the caller is the package owner.
129 */
130 public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) {
131 return hasDeviceOwnerOrProfileOwner(userId, packageName)
132 || isProtectedPackage(packageName);
133 }
134
135 /**
136 * Returns {@code true} if a given package's data is protected. Otherwise, returns
137 * {@code false}.
138 */
139 public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) {
140 return hasDeviceOwnerOrProfileOwner(userId, packageName)
141 || isProtectedPackage(packageName);
142 }
143}