1c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki/* 2c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * Copyright (C) 2016 The Android Open Source Project 3c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * 4c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 5c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * you may not use this file except in compliance with the License. 6c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * You may obtain a copy of the License at 7c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * 8c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 9c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * 10c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * Unless required by applicable law or agreed to in writing, software 11c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 12c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * See the License for the specific language governing permissions and 14c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * limitations under the License. 15c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki */ 16c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 17c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onukipackage com.android.server.pm; 18c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 199d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ngimport android.annotation.Nullable; 20c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onukiimport android.annotation.UserIdInt; 219d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ngimport android.content.Context; 22c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onukiimport android.os.UserHandle; 23c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onukiimport android.util.SparseArray; 24c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 259d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ngimport com.android.internal.R; 269d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ngimport com.android.internal.annotations.GuardedBy; 279d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng 28c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki/** 29c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * Manages package names that need special protection. 30c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * 31c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * TODO: This class should persist the information by itself, and also keeps track of device admin 32c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * packages for all users. Then PMS.isPackageDeviceAdmin() should use it instead of talking 33c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * to DPMS. 34c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki */ 35c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onukipublic class ProtectedPackages { 36c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki @UserIdInt 379d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @GuardedBy("this") 38c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki private int mDeviceOwnerUserId; 39c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 409d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @Nullable 419d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @GuardedBy("this") 42c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki private String mDeviceOwnerPackage; 43c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 449d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @Nullable 459d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @GuardedBy("this") 46c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki private SparseArray<String> mProfileOwnerPackages; 47c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 489d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @Nullable 499d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng @GuardedBy("this") 509d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng private final String mDeviceProvisioningPackage; 519d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng 529d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng private final Context mContext; 539d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng 549d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng public ProtectedPackages(Context context) { 559d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng mContext = context; 569d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng mDeviceProvisioningPackage = mContext.getResources().getString( 579d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng R.string.config_deviceProvisioningPackage); 589d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng } 59c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 60c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki /** 61c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki * Sets the device/profile owner information. 62c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki */ 639d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng public synchronized void setDeviceAndProfileOwnerPackages( 64c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki int deviceOwnerUserId, String deviceOwnerPackage, 65c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki SparseArray<String> profileOwnerPackages) { 669d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng mDeviceOwnerUserId = deviceOwnerUserId; 679d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng mDeviceOwnerPackage = 689d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng (deviceOwnerUserId == UserHandle.USER_NULL) ? null : deviceOwnerPackage; 699d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng mProfileOwnerPackages = (profileOwnerPackages == null) ? null 709d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng : profileOwnerPackages.clone(); 71c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 72c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 739d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng private synchronized boolean hasDeviceOwnerOrProfileOwner(int userId, String packageName) { 74c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki if (packageName == null) { 75c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki return false; 76c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 779d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng if (mDeviceOwnerPackage != null) { 789d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng if ((mDeviceOwnerUserId == userId) 799d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng && (packageName.equals(mDeviceOwnerPackage))) { 809d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng return true; 81c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 829d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng } 839d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng if (mProfileOwnerPackages != null) { 849d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng if (packageName.equals(mProfileOwnerPackages.get(userId))) { 859d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng return true; 86c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 87c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 88c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki return false; 89c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 90c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 91c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki /** 929d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * Returns {@code true} if a given package is protected. Otherwise, returns {@code false}. 939d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * 949d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * <p>A protected package means that, apart from the package owner, no system or privileged apps 959d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * can modify its data or package state. 969d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng */ 979d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng private synchronized boolean isProtectedPackage(String packageName) { 989d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng return packageName != null && packageName.equals(mDeviceProvisioningPackage); 999d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng } 1009d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng 1019d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng /** 1029d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * Returns {@code true} if a given package's state is protected. Otherwise, returns 1039d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * {@code false}. 1049d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * 1059d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * <p>This is not applicable if the caller is the package owner. 106c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki */ 1079d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng public boolean isPackageStateProtected(@UserIdInt int userId, String packageName) { 1089d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng return hasDeviceOwnerOrProfileOwner(userId, packageName) 1099d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng || isProtectedPackage(packageName); 110c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 111c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki 112c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki /** 1139d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * Returns {@code true} if a given package's data is protected. Otherwise, returns 1149d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng * {@code false}. 115c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki */ 1169d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng public boolean isPackageDataProtected(@UserIdInt int userId, String packageName) { 1179d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng return hasDeviceOwnerOrProfileOwner(userId, packageName) 1189d48a731d0a7c016b58bc9c1afc4acd94200650fSteven Ng || isProtectedPackage(packageName); 119c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki } 120c29f62c7388f550da2c7368c5dbc0aec7d1564feMakoto Onuki} 121