Home | History | Annotate | Download | only in pm
      1 /*
      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 
     17 package com.android.server.pm;
     18 
     19 import android.annotation.Nullable;
     20 import android.annotation.UserIdInt;
     21 import android.content.Context;
     22 import android.os.UserHandle;
     23 import android.util.SparseArray;
     24 
     25 import com.android.internal.R;
     26 import com.android.internal.annotations.GuardedBy;
     27 
     28 /**
     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  */
     35 public class ProtectedPackages {
     36     @UserIdInt
     37     @GuardedBy("this")
     38     private int mDeviceOwnerUserId;
     39 
     40     @Nullable
     41     @GuardedBy("this")
     42     private String mDeviceOwnerPackage;
     43 
     44     @Nullable
     45     @GuardedBy("this")
     46     private SparseArray<String> mProfileOwnerPackages;
     47 
     48     @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     }
     59 
     60     /**
     61      * Sets the device/profile owner information.
     62      */
     63     public synchronized void setDeviceAndProfileOwnerPackages(
     64             int deviceOwnerUserId, String deviceOwnerPackage,
     65             SparseArray<String> profileOwnerPackages) {
     66         mDeviceOwnerUserId = deviceOwnerUserId;
     67         mDeviceOwnerPackage =
     68                 (deviceOwnerUserId == UserHandle.USER_NULL) ? null : deviceOwnerPackage;
     69         mProfileOwnerPackages = (profileOwnerPackages == null) ? null
     70                 : profileOwnerPackages.clone();
     71     }
     72 
     73     private synchronized boolean hasDeviceOwnerOrProfileOwner(int userId, String packageName) {
     74         if (packageName == null) {
     75             return false;
     76         }
     77         if (mDeviceOwnerPackage != null) {
     78             if ((mDeviceOwnerUserId == userId)
     79                     && (packageName.equals(mDeviceOwnerPackage))) {
     80                 return true;
     81             }
     82         }
     83         if (mProfileOwnerPackages != null) {
     84             if (packageName.equals(mProfileOwnerPackages.get(userId))) {
     85                 return true;
     86             }
     87         }
     88         return false;
     89     }
     90 
     91     public synchronized String getDeviceOwnerOrProfileOwnerPackage(int userId) {
     92         if (mDeviceOwnerUserId == userId) {
     93             return mDeviceOwnerPackage;
     94         }
     95         return mProfileOwnerPackages.get(userId);
     96     }
     97 
     98     /**
     99      * 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.
    103      */
    104     private synchronized boolean isProtectedPackage(String packageName) {
    105         return packageName != null && packageName.equals(mDeviceProvisioningPackage);
    106     }
    107 
    108     /**
    109      * 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.
    113      */
    114     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);
    126     }
    127 }
    128