1 /* 2 * Copyright (C) 2015 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 package android.car.content.pm; 17 18 import android.annotation.IntDef; 19 import android.annotation.Nullable; 20 import android.annotation.SystemApi; 21 import android.content.pm.Signature; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import java.lang.annotation.Retention; 26 import java.lang.annotation.RetentionPolicy; 27 import java.util.Arrays; 28 29 /** 30 * Parcelable to hold information on app blocking allowlist or denylist for a package. 31 * @hide 32 */ 33 @SystemApi 34 public final class AppBlockingPackageInfo implements Parcelable { 35 36 /** Package name for the package to block or allow. */ 37 public final String packageName; 38 39 /** Represents system app which does not need {@link #signature}. */ 40 public static final int FLAG_SYSTEM_APP = 0x1; 41 /** Denylist or allowlist every Activities in the package. When this is set, 42 * {@link #activities} may be null. */ 43 public static final int FLAG_WHOLE_ACTIVITY = 0x2; 44 /** @hide */ 45 @IntDef(flag = true, 46 value = {FLAG_SYSTEM_APP, FLAG_WHOLE_ACTIVITY}) 47 @Retention(RetentionPolicy.SOURCE) 48 public @interface ConstructorFlags {} 49 50 /** 51 * flags to give additional information on the package. 52 * @see #FLAG_SYSTEM_APP 53 * @see #FLAG_WHOLE_ACTIVITY 54 */ 55 public final int flags; 56 57 /** 58 * Package version should be bigger than this to block or allow. 59 * (package version > minRevisionCode) 60 * 0 means do not care min version. 61 */ 62 public final int minRevisionCode; 63 64 /** 65 * Package version should be smaller than this to block or allow. 66 * (package version < minRevisionCode) 67 * 0 means do not care max version. 68 */ 69 public final int maxRevisionCode; 70 71 /** 72 * Signature of package. This can be null if target package is from system so that package 73 * name is enough to uniquely identify it (= {@link #flags} having {@link #FLAG_SYSTEM_APP}. 74 * Matching any member of array is considered as matching package. 75 */ 76 public final Signature[] signatures; 77 78 /** List of activities (full class name). This can be null if Activity is not blocked or 79 * allowed. Additionally, {@link #FLAG_WHOLE_ACTIVITY} set in {@link #flags} shall have 80 * null for this. */ 81 public final String[] activities; 82 83 AppBlockingPackageInfo(String packageName, int minRevisionCode, int maxRevisionCode, @ConstructorFlags int flags, @Nullable Signature[] signatures, @Nullable String[] activities)84 public AppBlockingPackageInfo(String packageName, int minRevisionCode, int maxRevisionCode, 85 @ConstructorFlags int flags, @Nullable Signature[] signatures, 86 @Nullable String[] activities) { 87 if (packageName == null) { 88 throw new IllegalArgumentException("packageName cannot be null"); 89 } 90 this.packageName = packageName; 91 this.flags = flags; 92 this.minRevisionCode = minRevisionCode; 93 this.maxRevisionCode = maxRevisionCode; 94 this.signatures = signatures; 95 this.activities = activities; 96 verify(); 97 } 98 AppBlockingPackageInfo(Parcel in)99 public AppBlockingPackageInfo(Parcel in) { 100 packageName = in.readString(); 101 flags = in.readInt(); 102 minRevisionCode= in.readInt(); 103 maxRevisionCode = in.readInt(); 104 signatures = in.createTypedArray(Signature.CREATOR); 105 activities = in.createStringArray(); 106 verify(); 107 } 108 109 @Override describeContents()110 public int describeContents() { 111 return 0; 112 } 113 114 @Override writeToParcel(Parcel dest, int flags)115 public void writeToParcel(Parcel dest, int flags) { 116 dest.writeString(packageName); 117 dest.writeInt(this.flags); 118 dest.writeInt(minRevisionCode); 119 dest.writeInt(maxRevisionCode); 120 dest.writeTypedArray(signatures, 0); 121 dest.writeStringArray(activities); 122 } 123 124 public static final Parcelable.Creator<AppBlockingPackageInfo> CREATOR 125 = new Parcelable.Creator<AppBlockingPackageInfo>() { 126 public AppBlockingPackageInfo createFromParcel(Parcel in) { 127 return new AppBlockingPackageInfo(in); 128 } 129 130 public AppBlockingPackageInfo[] newArray(int size) { 131 return new AppBlockingPackageInfo[size]; 132 } 133 }; 134 135 /** @hide */ verify()136 public void verify() throws IllegalArgumentException { 137 if (signatures == null && (flags & FLAG_SYSTEM_APP) == 0) { 138 throw new IllegalArgumentException( 139 "Only system package with FLAG_SYSTEM_APP can have null signatures"); 140 } 141 } 142 143 /** @hide */ isActivityCovered(String className)144 public boolean isActivityCovered(String className) { 145 if ((flags & FLAG_WHOLE_ACTIVITY) != 0) { 146 return true; 147 } 148 if (activities == null) { 149 return false; 150 } 151 for (String activityName : activities) { 152 if (activityName.equals(className)) { 153 return true; 154 } 155 } 156 return false; 157 } 158 159 @Override hashCode()160 public int hashCode() { 161 final int prime = 31; 162 int result = 1; 163 result = prime * result + Arrays.hashCode(activities); 164 result = prime * result + flags; 165 result = prime * result + maxRevisionCode; 166 result = prime * result + minRevisionCode; 167 result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); 168 result = prime * result + Arrays.hashCode(signatures); 169 return result; 170 } 171 172 @Override equals(Object obj)173 public boolean equals(Object obj) { 174 if (this == obj) { 175 return true; 176 } 177 if (obj == null) { 178 return false; 179 } 180 if (getClass() != obj.getClass()) { 181 return false; 182 } 183 AppBlockingPackageInfo other = (AppBlockingPackageInfo) obj; 184 if (!Arrays.equals(activities, other.activities)) { 185 return false; 186 } 187 if (flags != other.flags) { 188 return false; 189 } 190 if (maxRevisionCode != other.maxRevisionCode) { 191 return false; 192 } 193 if (minRevisionCode != other.minRevisionCode) { 194 return false; 195 } 196 if (packageName == null) { 197 if (other.packageName != null) 198 return false; 199 } else if (!packageName.equals(other.packageName)) 200 return false; 201 if (!Arrays.equals(signatures, other.signatures)) { 202 return false; 203 } 204 return true; 205 } 206 207 @Override toString()208 public String toString() { 209 return "AppBlockingPackageInfo [packageName=" + packageName + ", flags=" + flags 210 + ", minRevisionCode=" + minRevisionCode + ", maxRevisionCode=" + maxRevisionCode 211 + ", signatures=" + Arrays.toString(signatures) + ", activities=" 212 + Arrays.toString(activities) + "]"; 213 } 214 } 215