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