1 /* 2 * Copyright (C) 2022 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 android.app.admin; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.util.ArraySet; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.Collections; 28 import java.util.Objects; 29 import java.util.Set; 30 31 32 /** 33 * A generic class that defines which APK packages are in scope for some device policy. 34 * <p> 35 * The packages can be defined using either an allowlist or a blocklist. 36 * In allowlist mode, it could optionally include all system packages 37 * that meet the specific criteria of the device policy in question. 38 */ 39 public final class PackagePolicy implements Parcelable { 40 41 /** 42 * PackagePolicy type indicator for {@link PackagePolicy} 43 * <p> 44 * This constant indicates that all packages are allowed except for the packages returned by 45 * {@link PackagePolicy#getPackageNames()}, which acts as a denylist. 46 * @see #PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM 47 * @see #PACKAGE_POLICY_ALLOWLIST 48 */ 49 public static final int PACKAGE_POLICY_BLOCKLIST = 1; 50 51 /** 52 * PackagePolicy type indicator for {@link PackagePolicy} 53 * <p> 54 * This constant indicates system packages are allowed in addition to the packages returned by 55 * {@link PackagePolicy#getPackageNames()}, which acts as an allowlist. 56 * 57 * <p>Functions that accept {@link PackagePolicy} will further clarify 58 * how this policy is interpreted. 59 * 60 * @see #PACKAGE_POLICY_BLOCKLIST 61 * @see #PACKAGE_POLICY_ALLOWLIST 62 */ 63 public static final int PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM = 2; 64 65 /** 66 * PackagePolicy type indicator for {@link PackagePolicy} 67 * <p> 68 * This constant indicates that all packages are denied except for the packages returned by 69 * {@link PackagePolicy#getPackageNames()}, which acts as an allowlist. 70 * 71 * @see #PACKAGE_POLICY_BLOCKLIST 72 * @see #PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM 73 */ 74 public static final int PACKAGE_POLICY_ALLOWLIST = 3; 75 76 /** 77 * 78 * @hide 79 */ 80 @Retention(RetentionPolicy.SOURCE) 81 @IntDef(prefix = {"PACKAGE_POLICY_"}, value = { 82 PACKAGE_POLICY_BLOCKLIST, 83 PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM, 84 PACKAGE_POLICY_ALLOWLIST 85 }) 86 public @interface PackagePolicyType {} 87 88 private @PackagePolicyType int mPolicyType; 89 90 private ArraySet<String> mPackageNames; 91 92 /** 93 * Create the package policy 94 * @param policyType indicates how to interpret this policy 95 96 * @see PackagePolicy#PackagePolicy(int, Set) 97 */ PackagePolicy(@ackagePolicyType int policyType)98 public PackagePolicy(@PackagePolicyType int policyType) { 99 this(policyType, Collections.emptySet()); 100 } 101 102 /** 103 * Create the package policy 104 * @param policyType indicates how to interpret this policy 105 * @param packageNames allowlist or a denylist, based on policyType 106 */ PackagePolicy(@ackagePolicyType int policyType, @NonNull Set<String> packageNames)107 public PackagePolicy(@PackagePolicyType int policyType, @NonNull Set<String> packageNames) { 108 if (policyType != PACKAGE_POLICY_BLOCKLIST 109 && policyType != PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM 110 && policyType != PACKAGE_POLICY_ALLOWLIST) { 111 throw new IllegalArgumentException("Invalid policy type"); 112 } 113 mPolicyType = policyType; 114 mPackageNames = new ArraySet<>(packageNames); 115 } 116 PackagePolicy(Parcel in)117 private PackagePolicy(Parcel in) { 118 mPolicyType = in.readInt(); 119 mPackageNames = (ArraySet<String>) in.readArraySet(null); 120 } 121 122 /** 123 * Returns the current policy type 124 */ getPolicyType()125 public @PackagePolicyType int getPolicyType() { 126 return mPolicyType; 127 } 128 129 /** 130 * Returns the list of packages to use as an allow/deny list based on policy type 131 */ 132 @NonNull getPackageNames()133 public Set<String> getPackageNames() { 134 return Collections.unmodifiableSet(mPackageNames); 135 } 136 137 /** 138 * Evaluates the packageName provided against this policy to determine if the package should be 139 * allowed. 140 * 141 * If the policy type is {@link #PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM}, 142 * the systemPackage will be used in addition to package names of this policy's 143 * {@link #getPackageNames()} 144 * 145 * @param packageName the name of the package to test 146 * @param systemPackages list of packages identified as system packages 147 * @return true if the package is allowed, false if the package is denied 148 * @hide 149 */ isPackageAllowed(@onNull String packageName, @NonNull Set<String> systemPackages)150 public boolean isPackageAllowed(@NonNull String packageName, 151 @NonNull Set<String> systemPackages) { 152 if (mPolicyType == PACKAGE_POLICY_BLOCKLIST) { 153 return !mPackageNames.contains(packageName); 154 } 155 return mPackageNames.contains(packageName) 156 || (mPolicyType == PACKAGE_POLICY_ALLOWLIST_AND_SYSTEM 157 && systemPackages.contains(packageName)); 158 } 159 160 /** 161 * @see Parcelable.Creator 162 */ 163 @NonNull 164 public static final Creator<PackagePolicy> CREATOR = new Creator<PackagePolicy>() { 165 @Override 166 public PackagePolicy createFromParcel(Parcel in) { 167 return new PackagePolicy(in); 168 } 169 170 @Override 171 public PackagePolicy[] newArray(int size) { 172 return new PackagePolicy[size]; 173 } 174 }; 175 176 @Override writeToParcel(@onNull Parcel dest, int flags)177 public void writeToParcel(@NonNull Parcel dest, int flags) { 178 dest.writeInt(mPolicyType); 179 dest.writeArraySet(mPackageNames); 180 } 181 182 @Override equals(Object thatObject)183 public boolean equals(Object thatObject) { 184 if (this == thatObject) { 185 return true; 186 } 187 if (!(thatObject instanceof PackagePolicy)) { 188 return false; 189 } 190 PackagePolicy that = (PackagePolicy) thatObject; 191 return mPolicyType == that.mPolicyType && mPackageNames.equals(that.mPackageNames); 192 } 193 194 @Override hashCode()195 public int hashCode() { 196 return Objects.hash(mPolicyType, mPackageNames); 197 } 198 199 @Override describeContents()200 public int describeContents() { 201 return 0; 202 } 203 204 } 205