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