blob: a374e1484b2872591c21ff917fdd6be078c5b4f5 [file] [log] [blame]
Makoto Onukic29f62c2016-06-07 12:19:46 -07001/*
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
Steven Ng9d48a732016-06-24 19:04:14 +010019import android.annotation.Nullable;
Makoto Onukic29f62c2016-06-07 12:19:46 -070020import android.annotation.UserIdInt;
Steven Ng9d48a732016-06-24 19:04:14 +010021import android.content.Context;
Makoto Onukic29f62c2016-06-07 12:19:46 -070022import android.os.UserHandle;
23import android.util.SparseArray;
24
Steven Ng9d48a732016-06-24 19:04:14 +010025import com.android.internal.R;
26import com.android.internal.annotations.GuardedBy;
27
Makoto Onukic29f62c2016-06-07 12:19:46 -070028/**
29 * Manages package names that need special protection.
30 *
31 * TODO: This class should persist the information by itself, and also keeps track of device admin
32 * packages for all users. Then PMS.isPackageDeviceAdmin() should use it instead of talking
33 * to DPMS.
34 */
35public class ProtectedPackages {
36 @UserIdInt
Steven Ng9d48a732016-06-24 19:04:14 +010037 @GuardedBy("this")
Makoto Onukic29f62c2016-06-07 12:19:46 -070038 private int mDeviceOwnerUserId;
39
Steven Ng9d48a732016-06-24 19:04:14 +010040 @Nullable
41 @GuardedBy("this")
Makoto Onukic29f62c2016-06-07 12:19:46 -070042 private String mDeviceOwnerPackage;
43
Steven Ng9d48a732016-06-24 19:04:14 +010044 @Nullable
45 @GuardedBy("this")
Makoto Onukic29f62c2016-06-07 12:19:46 -070046 private SparseArray<String> mProfileOwnerPackages;
47
Steven Ng9d48a732016-06-24 19:04:14 +010048 @Nullable
49 @GuardedBy("this")
50 private final String mDeviceProvisioningPackage;
51
52 private final Context mContext;
53
54 public ProtectedPackages(Context context) {
55 mContext = context;
56 mDeviceProvisioningPackage = mContext.getResources().getString(
57 R.string.config_deviceProvisioningPackage);
58 }
Makoto Onukic29f62c2016-06-07 12:19:46 -070059
60 /**
61 * Sets the device/profile owner information.
62 */
Steven Ng9d48a732016-06-24 19:04:14 +010063 public synchronized void setDeviceAndProfileOwnerPackages(
Makoto Onukic29f62c2016-06-07 12:19:46 -070064 int deviceOwnerUserId, String deviceOwnerPackage,
65 SparseArray<String> profileOwnerPackages) {
Steven Ng9d48a732016-06-24 19:04:14 +010066 mDeviceOwnerUserId = deviceOwnerUserId;
67 mDeviceOwnerPackage =
68 (deviceOwnerUserId == UserHandle.USER_NULL) ? null : deviceOwnerPackage;
69 mProfileOwnerPackages = (profileOwnerPackages == null) ? null
70 : profileOwnerPackages.clone();
Makoto Onukic29f62c2016-06-07 12:19:46 -070071 }
72
Steven Ng9d48a732016-06-24 19:04:14 +010073 private synchronized boolean hasDeviceOwnerOrProfileOwner(int userId, String packageName) {
Makoto Onukic29f62c2016-06-07 12:19:46 -070074 if (packageName == null) {
75 return false;
76 }
Steven Ng9d48a732016-06-24 19:04:14 +010077 if (mDeviceOwnerPackage != null) {
78 if ((mDeviceOwnerUserId == userId)
79 && (packageName.equals(mDeviceOwnerPackage))) {
80 return true;
Makoto Onukic29f62c2016-06-07 12:19:46 -070081 }
Steven Ng9d48a732016-06-24 19:04:14 +010082 }
83 if (mProfileOwnerPackages != null) {
84 if (packageName.equals(mProfileOwnerPackages.get(userId))) {
85 return true;
Makoto Onukic29f62c2016-06-07 12:19:46 -070086 }
87 }
88 return false;
89 }
90
Suprabh Shukla7ea53782018-04-17 13:53:18 -070091 public synchronized String getDeviceOwnerOrProfileOwnerPackage(int userId) {
92 if (mDeviceOwnerUserId == userId) {
93 return mDeviceOwnerPackage;
94 }
95 return mProfileOwnerPackages.get(userId);
96 }
97
Makoto Onukic29f62c2016-06-07 12:19:46 -070098 /**
Steven Ng9d48a732016-06-24 19:04:14 +010099 * Returns {@code true} if a given package is protected. Otherwise, returns {@code false}.
100 *
101 * <p>A protected package means that, apart from the package owner, no system or privileged apps
102 * can modify its data or package state.
Makoto Onukic29f62c2016-06-07 12:19:46 -0700103 */
Steven Ng9d48a732016-06-24 19:04:14 +0100104 private synchronized boolean isProtectedPackage(String packageName) {
105 return packageName != null && packageName.equals(mDeviceProvisioningPackage);
Makoto Onukic29f62c2016-06-07 12:19:46 -0700106 }
107
108 /**
Steven Ng9d48a732016-06-24 19:04:14 +0100109 * Returns {@code true} if a given package's state is protected. Otherwise, returns
110 * {@code false}.
111 *
112 * <p>This is not applicable if the caller is the package owner.
Makoto Onukic29f62c2016-06-07 12:19:46 -0700113 */
Steven Ng9d48a732016-06-24 19:04:14 +0100114 public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) {
115 return hasDeviceOwnerOrProfileOwner(userId, packageName)
116 || isProtectedPackage(packageName);
117 }
118
119 /**
120 * Returns {@code true} if a given package's data is protected. Otherwise, returns
121 * {@code false}.
122 */
123 public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) {
124 return hasDeviceOwnerOrProfileOwner(userId, packageName)
125 || isProtectedPackage(packageName);
Makoto Onukic29f62c2016-06-07 12:19:46 -0700126 }
127}