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 127 @Override 128 public AppBlockingPackageInfo createFromParcel(Parcel in) { 129 return new AppBlockingPackageInfo(in); 130 } 131 132 @Override 133 public AppBlockingPackageInfo[] newArray(int size) { 134 return new AppBlockingPackageInfo[size]; 135 } 136 }; 137 138 /** @hide */ verify()139 public void verify() throws IllegalArgumentException { 140 if (signatures == null && (flags & FLAG_SYSTEM_APP) == 0) { 141 throw new IllegalArgumentException( 142 "Only system package with FLAG_SYSTEM_APP can have null signatures"); 143 } 144 } 145 146 /** @hide */ isActivityCovered(String className)147 public boolean isActivityCovered(String className) { 148 if ((flags & FLAG_WHOLE_ACTIVITY) != 0) { 149 return true; 150 } 151 if (activities == null) { 152 return false; 153 } 154 for (String activityName : activities) { 155 if (activityName.equals(className)) { 156 return true; 157 } 158 } 159 return false; 160 } 161 162 @Override hashCode()163 public int hashCode() { 164 final int prime = 31; 165 int result = 1; 166 result = prime * result + Arrays.hashCode(activities); 167 result = prime * result + flags; 168 result = prime * result + maxRevisionCode; 169 result = prime * result + minRevisionCode; 170 result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); 171 result = prime * result + Arrays.hashCode(signatures); 172 return result; 173 } 174 175 @Override equals(Object obj)176 public boolean equals(Object obj) { 177 if (this == obj) { 178 return true; 179 } 180 if (obj == null) { 181 return false; 182 } 183 if (getClass() != obj.getClass()) { 184 return false; 185 } 186 AppBlockingPackageInfo other = (AppBlockingPackageInfo) obj; 187 if (!Arrays.equals(activities, other.activities)) { 188 return false; 189 } 190 if (flags != other.flags) { 191 return false; 192 } 193 if (maxRevisionCode != other.maxRevisionCode) { 194 return false; 195 } 196 if (minRevisionCode != other.minRevisionCode) { 197 return false; 198 } 199 if (packageName == null) { 200 if (other.packageName != null) { 201 return false; 202 } 203 } else if (!packageName.equals(other.packageName)) { 204 return false; 205 } 206 if (!Arrays.equals(signatures, other.signatures)) { 207 return false; 208 } 209 return true; 210 } 211 212 @Override toString()213 public String toString() { 214 return "AppBlockingPackageInfo [packageName=" + packageName + ", flags=" + flags 215 + ", minRevisionCode=" + minRevisionCode + ", maxRevisionCode=" + maxRevisionCode 216 + ", signatures=" + Arrays.toString(signatures) + ", activities=" 217 + Arrays.toString(activities) + "]"; 218 } 219 } 220