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 com.android.server.art; 18 19 import static com.android.server.art.OutputArtifacts.PermissionSettings; 20 import static com.android.server.art.OutputArtifacts.PermissionSettings.SeContext; 21 import static com.android.server.art.ProfilePath.PrebuiltProfilePath; 22 import static com.android.server.art.ProfilePath.PrimaryCurProfilePath; 23 import static com.android.server.art.ProfilePath.PrimaryRefProfilePath; 24 import static com.android.server.art.ProfilePath.SecondaryCurProfilePath; 25 import static com.android.server.art.ProfilePath.SecondaryRefProfilePath; 26 import static com.android.server.art.ProfilePath.TmpProfilePath; 27 import static com.android.server.art.ProfilePath.WritableProfilePath; 28 29 import android.annotation.NonNull; 30 import android.annotation.Nullable; 31 32 /** @hide */ 33 public final class AidlUtils { AidlUtils()34 private AidlUtils() {} 35 36 @NonNull buildArtifactsPath(@onNull String dexPath, @NonNull String isa, boolean isInDalvikCache, boolean isPreReboot)37 private static ArtifactsPath buildArtifactsPath(@NonNull String dexPath, @NonNull String isa, 38 boolean isInDalvikCache, boolean isPreReboot) { 39 var artifactsPath = new ArtifactsPath(); 40 artifactsPath.dexPath = dexPath; 41 artifactsPath.isa = isa; 42 artifactsPath.isInDalvikCache = isInDalvikCache; 43 artifactsPath.isPreReboot = isPreReboot; 44 return artifactsPath; 45 } 46 47 @NonNull buildArtifactsPathAsInput( @onNull String dexPath, @NonNull String isa, boolean isInDalvikCache)48 public static ArtifactsPath buildArtifactsPathAsInput( 49 @NonNull String dexPath, @NonNull String isa, boolean isInDalvikCache) { 50 // The callers expect artifacts to be used as inputs, so we should always pick the 51 // non-Pre-reboot ones. 52 return buildArtifactsPath(dexPath, isa, isInDalvikCache, false /* isPreReboot */); 53 } 54 55 @NonNull buildArtifactsPathAsInputPreReboot( @onNull String dexPath, @NonNull String isa, boolean isInDalvikCache)56 public static ArtifactsPath buildArtifactsPathAsInputPreReboot( 57 @NonNull String dexPath, @NonNull String isa, boolean isInDalvikCache) { 58 // Normally this should not be called, unless the caller really means to use Pre-reboot 59 // artifacts as inputs. 60 return buildArtifactsPath(dexPath, isa, isInDalvikCache, true /* isPreReboot */); 61 } 62 63 @NonNull buildFsPermission( int uid, int gid, boolean isOtherReadable, boolean isOtherExecutable)64 public static FsPermission buildFsPermission( 65 int uid, int gid, boolean isOtherReadable, boolean isOtherExecutable) { 66 var fsPermission = new FsPermission(); 67 fsPermission.uid = uid; 68 fsPermission.gid = gid; 69 fsPermission.isOtherReadable = isOtherReadable; 70 fsPermission.isOtherExecutable = isOtherExecutable; 71 return fsPermission; 72 } 73 74 @NonNull buildFsPermission(int uid, int gid, boolean isOtherReadable)75 public static FsPermission buildFsPermission(int uid, int gid, boolean isOtherReadable) { 76 return buildFsPermission(uid, gid, isOtherReadable, false /* isOtherExecutable */); 77 } 78 79 @NonNull buildDexMetadataPath(@onNull String dexPath)80 public static DexMetadataPath buildDexMetadataPath(@NonNull String dexPath) { 81 var dexMetadataPath = new DexMetadataPath(); 82 dexMetadataPath.dexPath = dexPath; 83 return dexMetadataPath; 84 } 85 86 @NonNull buildPermissionSettings(@onNull FsPermission dirFsPermission, @NonNull FsPermission fileFsPermission, @Nullable SeContext seContext)87 public static PermissionSettings buildPermissionSettings(@NonNull FsPermission dirFsPermission, 88 @NonNull FsPermission fileFsPermission, @Nullable SeContext seContext) { 89 var permissionSettings = new PermissionSettings(); 90 permissionSettings.dirFsPermission = dirFsPermission; 91 permissionSettings.fileFsPermission = fileFsPermission; 92 permissionSettings.seContext = seContext; 93 return permissionSettings; 94 } 95 96 @NonNull buildOutputArtifacts(@onNull String dexPath, @NonNull String isa, boolean isInDalvikCache, @NonNull PermissionSettings permissionSettings, boolean isPreReboot)97 public static OutputArtifacts buildOutputArtifacts(@NonNull String dexPath, @NonNull String isa, 98 boolean isInDalvikCache, @NonNull PermissionSettings permissionSettings, 99 boolean isPreReboot) { 100 var outputArtifacts = new OutputArtifacts(); 101 outputArtifacts.artifactsPath = 102 buildArtifactsPath(dexPath, isa, isInDalvikCache, isPreReboot); 103 outputArtifacts.permissionSettings = permissionSettings; 104 return outputArtifacts; 105 } 106 107 @NonNull buildPrimaryRefProfilePath( @onNull String packageName, @NonNull String profileName, boolean isPreReboot)108 private static PrimaryRefProfilePath buildPrimaryRefProfilePath( 109 @NonNull String packageName, @NonNull String profileName, boolean isPreReboot) { 110 var primaryRefProfilePath = new PrimaryRefProfilePath(); 111 primaryRefProfilePath.packageName = packageName; 112 primaryRefProfilePath.profileName = profileName; 113 primaryRefProfilePath.isPreReboot = isPreReboot; 114 return primaryRefProfilePath; 115 } 116 117 @NonNull buildSecondaryRefProfilePath( @onNull String dexPath, boolean isPreReboot)118 private static SecondaryRefProfilePath buildSecondaryRefProfilePath( 119 @NonNull String dexPath, boolean isPreReboot) { 120 var secondaryRefProfilePath = new SecondaryRefProfilePath(); 121 secondaryRefProfilePath.dexPath = dexPath; 122 secondaryRefProfilePath.isPreReboot = isPreReboot; 123 return secondaryRefProfilePath; 124 } 125 126 @NonNull buildProfilePathForPrimaryRefAsInput( @onNull String packageName, @NonNull String profileName)127 public static ProfilePath buildProfilePathForPrimaryRefAsInput( 128 @NonNull String packageName, @NonNull String profileName) { 129 // The callers expect a profile to be used as an input, so we should always pick the 130 // non-Pre-reboot one. 131 return ProfilePath.primaryRefProfilePath( 132 buildPrimaryRefProfilePath(packageName, profileName, false /* isPreReboot */)); 133 } 134 135 @NonNull buildProfilePathForPrebuilt(@onNull String dexPath)136 public static ProfilePath buildProfilePathForPrebuilt(@NonNull String dexPath) { 137 var prebuiltProfilePath = new PrebuiltProfilePath(); 138 prebuiltProfilePath.dexPath = dexPath; 139 return ProfilePath.prebuiltProfilePath(prebuiltProfilePath); 140 } 141 142 @NonNull buildProfilePathForDm(@onNull String dexPath)143 public static ProfilePath buildProfilePathForDm(@NonNull String dexPath) { 144 return ProfilePath.dexMetadataPath(buildDexMetadataPath(dexPath)); 145 } 146 147 @NonNull buildProfilePathForPrimaryCur( int userId, @NonNull String packageName, @NonNull String profileName)148 public static ProfilePath buildProfilePathForPrimaryCur( 149 int userId, @NonNull String packageName, @NonNull String profileName) { 150 var primaryCurProfilePath = new PrimaryCurProfilePath(); 151 primaryCurProfilePath.userId = userId; 152 primaryCurProfilePath.packageName = packageName; 153 primaryCurProfilePath.profileName = profileName; 154 return ProfilePath.primaryCurProfilePath(primaryCurProfilePath); 155 } 156 157 @NonNull buildProfilePathForSecondaryRefAsInput(@onNull String dexPath)158 public static ProfilePath buildProfilePathForSecondaryRefAsInput(@NonNull String dexPath) { 159 // The callers expect a profile to be used as an input, so we should always pick the 160 // non-Pre-reboot one. 161 return ProfilePath.secondaryRefProfilePath( 162 buildSecondaryRefProfilePath(dexPath, false /* isPreReboot */)); 163 } 164 165 @NonNull buildProfilePathForSecondaryCur(@onNull String dexPath)166 public static ProfilePath buildProfilePathForSecondaryCur(@NonNull String dexPath) { 167 var secondaryCurProfilePath = new SecondaryCurProfilePath(); 168 secondaryCurProfilePath.dexPath = dexPath; 169 return ProfilePath.secondaryCurProfilePath(secondaryCurProfilePath); 170 } 171 172 @NonNull buildOutputProfile( @onNull WritableProfilePath finalPath, int uid, int gid, boolean isPublic)173 private static OutputProfile buildOutputProfile( 174 @NonNull WritableProfilePath finalPath, int uid, int gid, boolean isPublic) { 175 var outputProfile = new OutputProfile(); 176 outputProfile.profilePath = new TmpProfilePath(); 177 outputProfile.profilePath.finalPath = finalPath; 178 outputProfile.profilePath.id = ""; // Will be filled by artd. 179 outputProfile.profilePath.tmpPath = ""; // Will be filled by artd. 180 outputProfile.fsPermission = buildFsPermission(uid, gid, isPublic); 181 return outputProfile; 182 } 183 184 @NonNull buildOutputProfileForPrimary(@onNull String packageName, @NonNull String profileName, int uid, int gid, boolean isPublic, boolean isPreReboot)185 public static OutputProfile buildOutputProfileForPrimary(@NonNull String packageName, 186 @NonNull String profileName, int uid, int gid, boolean isPublic, boolean isPreReboot) { 187 return buildOutputProfile(WritableProfilePath.forPrimary(buildPrimaryRefProfilePath( 188 packageName, profileName, isPreReboot)), 189 uid, gid, isPublic); 190 } 191 192 @NonNull buildOutputProfileForSecondary( @onNull String dexPath, int uid, int gid, boolean isPublic, boolean isPreReboot)193 public static OutputProfile buildOutputProfileForSecondary( 194 @NonNull String dexPath, int uid, int gid, boolean isPublic, boolean isPreReboot) { 195 return buildOutputProfile(WritableProfilePath.forSecondary( 196 buildSecondaryRefProfilePath(dexPath, isPreReboot)), 197 uid, gid, isPublic); 198 } 199 200 @NonNull buildSeContext(@onNull String seInfo, int uid)201 public static SeContext buildSeContext(@NonNull String seInfo, int uid) { 202 var seContext = new SeContext(); 203 seContext.seInfo = seInfo; 204 seContext.uid = uid; 205 return seContext; 206 } 207 208 @NonNull buildRuntimeArtifactsPath( @onNull String packageName, @NonNull String dexPath, @NonNull String isa)209 public static RuntimeArtifactsPath buildRuntimeArtifactsPath( 210 @NonNull String packageName, @NonNull String dexPath, @NonNull String isa) { 211 var runtimeArtifactsPath = new RuntimeArtifactsPath(); 212 runtimeArtifactsPath.packageName = packageName; 213 runtimeArtifactsPath.dexPath = dexPath; 214 runtimeArtifactsPath.isa = isa; 215 return runtimeArtifactsPath; 216 } 217 218 @NonNull toWritableProfilePath(@onNull ProfilePath profile)219 public static WritableProfilePath toWritableProfilePath(@NonNull ProfilePath profile) { 220 switch (profile.getTag()) { 221 case ProfilePath.primaryRefProfilePath: 222 return WritableProfilePath.forPrimary(profile.getPrimaryRefProfilePath()); 223 case ProfilePath.secondaryRefProfilePath: 224 return WritableProfilePath.forSecondary(profile.getSecondaryRefProfilePath()); 225 default: 226 throw new IllegalStateException("ProfilePath tag " + profile.getTag() 227 + " does not represent a writable type"); 228 } 229 } 230 231 @NonNull toString(@onNull PrimaryRefProfilePath profile)232 public static String toString(@NonNull PrimaryRefProfilePath profile) { 233 return String.format( 234 "PrimaryRefProfilePath[packageName = %s, profileName = %s, isPreReboot = %b]", 235 profile.packageName, profile.profileName, profile.isPreReboot); 236 } 237 238 @NonNull toString(@onNull SecondaryRefProfilePath profile)239 public static String toString(@NonNull SecondaryRefProfilePath profile) { 240 return String.format("SecondaryRefProfilePath[dexPath = %s, isPreReboot = %b]", 241 profile.dexPath, profile.isPreReboot); 242 } 243 244 @NonNull toString(@onNull PrebuiltProfilePath profile)245 public static String toString(@NonNull PrebuiltProfilePath profile) { 246 return String.format("PrebuiltProfilePath[dexPath = %s]", profile.dexPath); 247 } 248 249 @NonNull toString(@onNull DexMetadataPath profile)250 public static String toString(@NonNull DexMetadataPath profile) { 251 return String.format("DexMetadataPath[dexPath = %s]", profile.dexPath); 252 } 253 254 @NonNull toString(@onNull WritableProfilePath profile)255 public static String toString(@NonNull WritableProfilePath profile) { 256 switch (profile.getTag()) { 257 case WritableProfilePath.forPrimary: 258 return toString(profile.getForPrimary()); 259 case WritableProfilePath.forSecondary: 260 return toString(profile.getForSecondary()); 261 default: 262 throw new IllegalStateException( 263 "Unknown WritableProfilePath tag " + profile.getTag()); 264 } 265 } 266 267 @NonNull toString(@onNull ProfilePath profile)268 public static String toString(@NonNull ProfilePath profile) { 269 switch (profile.getTag()) { 270 case ProfilePath.primaryRefProfilePath: 271 return toString(profile.getPrimaryRefProfilePath()); 272 case ProfilePath.secondaryRefProfilePath: 273 return toString(profile.getSecondaryRefProfilePath()); 274 case ProfilePath.prebuiltProfilePath: 275 return toString(profile.getPrebuiltProfilePath()); 276 case ProfilePath.dexMetadataPath: 277 return toString(profile.getDexMetadataPath()); 278 default: 279 throw new UnsupportedOperationException( 280 "Only a subset of profile paths are supported to be converted to string, " 281 + "got " + profile.getTag()); 282 } 283 } 284 } 285