1 /* 2 * Copyright (C) 2020 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.content.pm.parsing.component; 18 19 import android.annotation.Nullable; 20 import android.content.pm.PermissionInfo; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.text.TextUtils; 24 import android.util.ArraySet; 25 26 import com.android.internal.annotations.VisibleForTesting; 27 import com.android.internal.util.DataClass; 28 import com.android.internal.util.Parcelling; 29 import com.android.internal.util.Parcelling.BuiltIn.ForInternedString; 30 import com.android.internal.util.Parcelling.BuiltIn.ForStringSet; 31 32 import java.util.Locale; 33 import java.util.Set; 34 35 /** @hide */ 36 public class ParsedPermission extends ParsedComponent { 37 38 private static ForStringSet sForStringSet = Parcelling.Cache.getOrCreate(ForStringSet.class); 39 40 @Nullable 41 String backgroundPermission; 42 @Nullable 43 @DataClass.ParcelWith(ForInternedString.class) 44 private String group; 45 int requestRes; 46 int protectionLevel; 47 boolean tree; 48 @Nullable 49 private ParsedPermissionGroup parsedPermissionGroup; 50 @Nullable 51 Set<String> knownCerts; 52 53 @VisibleForTesting ParsedPermission()54 public ParsedPermission() { 55 } 56 ParsedPermission(ParsedPermission other)57 public ParsedPermission(ParsedPermission other) { 58 super(other); 59 this.backgroundPermission = other.backgroundPermission; 60 this.group = other.group; 61 this.requestRes = other.requestRes; 62 this.protectionLevel = other.protectionLevel; 63 this.tree = other.tree; 64 this.parsedPermissionGroup = other.parsedPermissionGroup; 65 } 66 setGroup(String group)67 public ParsedPermission setGroup(String group) { 68 this.group = TextUtils.safeIntern(group); 69 return this; 70 } 71 setFlags(int flags)72 public ParsedPermission setFlags(int flags) { 73 this.flags = flags; 74 return this; 75 } 76 isRuntime()77 public boolean isRuntime() { 78 return getProtection() == PermissionInfo.PROTECTION_DANGEROUS; 79 } 80 isAppOp()81 public boolean isAppOp() { 82 return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0; 83 } 84 85 @PermissionInfo.Protection getProtection()86 public int getProtection() { 87 return protectionLevel & PermissionInfo.PROTECTION_MASK_BASE; 88 } 89 getProtectionFlags()90 public int getProtectionFlags() { 91 return protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE; 92 } 93 getKnownCerts()94 public @Nullable Set<String> getKnownCerts() { 95 return knownCerts; 96 } 97 setKnownCert(String knownCert)98 protected void setKnownCert(String knownCert) { 99 // Convert the provided digest to upper case for consistent Set membership 100 // checks when verifying the signing certificate digests of requesting apps. 101 this.knownCerts = Set.of(knownCert.toUpperCase(Locale.US)); 102 } 103 setKnownCerts(String[] knownCerts)104 protected void setKnownCerts(String[] knownCerts) { 105 this.knownCerts = new ArraySet<>(); 106 for (String knownCert : knownCerts) { 107 this.knownCerts.add(knownCert.toUpperCase(Locale.US)); 108 } 109 } 110 calculateFootprint()111 public int calculateFootprint() { 112 int size = getName().length(); 113 if (getNonLocalizedLabel() != null) { 114 size += getNonLocalizedLabel().length(); 115 } 116 return size; 117 } 118 toString()119 public String toString() { 120 return "Permission{" 121 + Integer.toHexString(System.identityHashCode(this)) 122 + " " + getName() + "}"; 123 } 124 125 @Override describeContents()126 public int describeContents() { 127 return 0; 128 } 129 130 @Override writeToParcel(Parcel dest, int flags)131 public void writeToParcel(Parcel dest, int flags) { 132 super.writeToParcel(dest, flags); 133 dest.writeString(this.backgroundPermission); 134 dest.writeString(this.group); 135 dest.writeInt(this.requestRes); 136 dest.writeInt(this.protectionLevel); 137 dest.writeBoolean(this.tree); 138 dest.writeParcelable(this.parsedPermissionGroup, flags); 139 sForStringSet.parcel(knownCerts, dest, flags); 140 } 141 ParsedPermission(Parcel in)142 protected ParsedPermission(Parcel in) { 143 super(in); 144 // We use the boot classloader for all classes that we load. 145 final ClassLoader boot = Object.class.getClassLoader(); 146 this.backgroundPermission = in.readString(); 147 this.group = in.readString(); 148 this.requestRes = in.readInt(); 149 this.protectionLevel = in.readInt(); 150 this.tree = in.readBoolean(); 151 this.parsedPermissionGroup = in.readParcelable(boot); 152 this.knownCerts = sForStringSet.unparcel(in); 153 } 154 155 public static final Parcelable.Creator<ParsedPermission> CREATOR = 156 new Parcelable.Creator<ParsedPermission>() { 157 @Override 158 public ParsedPermission createFromParcel(Parcel source) { 159 return new ParsedPermission(source); 160 } 161 162 @Override 163 public ParsedPermission[] newArray(int size) { 164 return new ParsedPermission[size]; 165 } 166 }; 167 168 @Nullable getBackgroundPermission()169 public String getBackgroundPermission() { 170 return backgroundPermission; 171 } 172 173 @Nullable getGroup()174 public String getGroup() { 175 return group; 176 } 177 getRequestRes()178 public int getRequestRes() { 179 return requestRes; 180 } 181 getProtectionLevel()182 public int getProtectionLevel() { 183 return protectionLevel; 184 } 185 isTree()186 public boolean isTree() { 187 return tree; 188 } 189 190 @Nullable getParsedPermissionGroup()191 public ParsedPermissionGroup getParsedPermissionGroup() { 192 return parsedPermissionGroup; 193 } 194 setProtectionLevel(int value)195 public ParsedPermission setProtectionLevel(int value) { 196 protectionLevel = value; 197 return this; 198 } 199 setParsedPermissionGroup(@ullable ParsedPermissionGroup value)200 public ParsedPermission setParsedPermissionGroup(@Nullable ParsedPermissionGroup value) { 201 parsedPermissionGroup = value; 202 return this; 203 } 204 } 205