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 buildPrimaryCurProfilePath( int userId, @NonNull String packageName, @NonNull String profileName)148 public static PrimaryCurProfilePath buildPrimaryCurProfilePath( 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 primaryCurProfilePath; 155 } 156 157 @NonNull buildProfilePathForPrimaryCur( int userId, @NonNull String packageName, @NonNull String profileName)158 public static ProfilePath buildProfilePathForPrimaryCur( 159 int userId, @NonNull String packageName, @NonNull String profileName) { 160 return ProfilePath.primaryCurProfilePath( 161 buildPrimaryCurProfilePath(userId, packageName, profileName)); 162 } 163 164 @NonNull buildProfilePathForSecondaryRefAsInput(@onNull String dexPath)165 public static ProfilePath buildProfilePathForSecondaryRefAsInput(@NonNull String dexPath) { 166 // The callers expect a profile to be used as an input, so we should always pick the 167 // non-Pre-reboot one. 168 return ProfilePath.secondaryRefProfilePath( 169 buildSecondaryRefProfilePath(dexPath, false /* isPreReboot */)); 170 } 171 172 @NonNull buildProfilePathForSecondaryCur(@onNull String dexPath)173 public static ProfilePath buildProfilePathForSecondaryCur(@NonNull String dexPath) { 174 var secondaryCurProfilePath = new SecondaryCurProfilePath(); 175 secondaryCurProfilePath.dexPath = dexPath; 176 return ProfilePath.secondaryCurProfilePath(secondaryCurProfilePath); 177 } 178 179 @NonNull buildOutputProfile( @onNull WritableProfilePath finalPath, int uid, int gid, boolean isPublic)180 private static OutputProfile buildOutputProfile( 181 @NonNull WritableProfilePath finalPath, int uid, int gid, boolean isPublic) { 182 var outputProfile = new OutputProfile(); 183 outputProfile.profilePath = new TmpProfilePath(); 184 outputProfile.profilePath.finalPath = finalPath; 185 outputProfile.profilePath.id = ""; // Will be filled by artd. 186 outputProfile.profilePath.tmpPath = ""; // Will be filled by artd. 187 outputProfile.fsPermission = buildFsPermission(uid, gid, isPublic); 188 return outputProfile; 189 } 190 191 @NonNull buildOutputProfileForPrimary(@onNull String packageName, @NonNull String profileName, int uid, int gid, boolean isPublic, boolean isPreReboot)192 public static OutputProfile buildOutputProfileForPrimary(@NonNull String packageName, 193 @NonNull String profileName, int uid, int gid, boolean isPublic, boolean isPreReboot) { 194 return buildOutputProfile(WritableProfilePath.forPrimary(buildPrimaryRefProfilePath( 195 packageName, profileName, isPreReboot)), 196 uid, gid, isPublic); 197 } 198 199 @NonNull buildOutputProfileForSecondary( @onNull String dexPath, int uid, int gid, boolean isPublic, boolean isPreReboot)200 public static OutputProfile buildOutputProfileForSecondary( 201 @NonNull String dexPath, int uid, int gid, boolean isPublic, boolean isPreReboot) { 202 return buildOutputProfile(WritableProfilePath.forSecondary( 203 buildSecondaryRefProfilePath(dexPath, isPreReboot)), 204 uid, gid, isPublic); 205 } 206 207 @NonNull buildSeContext(@onNull String seInfo, int uid)208 public static SeContext buildSeContext(@NonNull String seInfo, int uid) { 209 var seContext = new SeContext(); 210 seContext.seInfo = seInfo; 211 seContext.uid = uid; 212 return seContext; 213 } 214 215 @NonNull buildRuntimeArtifactsPath( @onNull String packageName, @NonNull String dexPath, @NonNull String isa)216 public static RuntimeArtifactsPath buildRuntimeArtifactsPath( 217 @NonNull String packageName, @NonNull String dexPath, @NonNull String isa) { 218 var runtimeArtifactsPath = new RuntimeArtifactsPath(); 219 runtimeArtifactsPath.packageName = packageName; 220 runtimeArtifactsPath.dexPath = dexPath; 221 runtimeArtifactsPath.isa = isa; 222 return runtimeArtifactsPath; 223 } 224 225 @NonNull buildSecureDexMetadataWithCompanionPaths( @onNull String dexPath, @NonNull String isa, boolean isInDalvikCache)226 public static SecureDexMetadataWithCompanionPaths buildSecureDexMetadataWithCompanionPaths( 227 @NonNull String dexPath, @NonNull String isa, boolean isInDalvikCache) { 228 var paths = new SecureDexMetadataWithCompanionPaths(); 229 paths.dexPath = dexPath; 230 paths.isa = isa; 231 paths.isInDalvikCache = isInDalvikCache; 232 return paths; 233 } 234 235 @NonNull buildOutputSecureDexMetadataCompanion( @onNull String dexPath, @NonNull String isa, boolean isInDalvikCache, @NonNull PermissionSettings permissionSettings)236 public static OutputSecureDexMetadataCompanion buildOutputSecureDexMetadataCompanion( 237 @NonNull String dexPath, @NonNull String isa, boolean isInDalvikCache, 238 @NonNull PermissionSettings permissionSettings) { 239 var outputSdc = new OutputSecureDexMetadataCompanion(); 240 outputSdc.sdcPath = buildSecureDexMetadataWithCompanionPaths(dexPath, isa, isInDalvikCache); 241 outputSdc.permissionSettings = permissionSettings; 242 return outputSdc; 243 } 244 245 @NonNull toWritableProfilePath(@onNull ProfilePath profile)246 public static WritableProfilePath toWritableProfilePath(@NonNull ProfilePath profile) { 247 switch (profile.getTag()) { 248 case ProfilePath.primaryRefProfilePath: 249 return WritableProfilePath.forPrimary(profile.getPrimaryRefProfilePath()); 250 case ProfilePath.secondaryRefProfilePath: 251 return WritableProfilePath.forSecondary(profile.getSecondaryRefProfilePath()); 252 default: 253 throw new IllegalStateException("ProfilePath tag " + profile.getTag() 254 + " does not represent a writable type"); 255 } 256 } 257 258 @NonNull toString(@onNull PrimaryRefProfilePath profile)259 public static String toString(@NonNull PrimaryRefProfilePath profile) { 260 return String.format( 261 "PrimaryRefProfilePath[packageName = %s, profileName = %s, isPreReboot = %b]", 262 profile.packageName, profile.profileName, profile.isPreReboot); 263 } 264 265 @NonNull toString(@onNull SecondaryRefProfilePath profile)266 public static String toString(@NonNull SecondaryRefProfilePath profile) { 267 return String.format("SecondaryRefProfilePath[dexPath = %s, isPreReboot = %b]", 268 profile.dexPath, profile.isPreReboot); 269 } 270 271 @NonNull toString(@onNull PrebuiltProfilePath profile)272 public static String toString(@NonNull PrebuiltProfilePath profile) { 273 return String.format("PrebuiltProfilePath[dexPath = %s]", profile.dexPath); 274 } 275 276 @NonNull toString(@onNull DexMetadataPath profile)277 public static String toString(@NonNull DexMetadataPath profile) { 278 return String.format("DexMetadataPath[dexPath = %s]", profile.dexPath); 279 } 280 281 @NonNull toString(@onNull WritableProfilePath profile)282 public static String toString(@NonNull WritableProfilePath profile) { 283 switch (profile.getTag()) { 284 case WritableProfilePath.forPrimary: 285 return toString(profile.getForPrimary()); 286 case WritableProfilePath.forSecondary: 287 return toString(profile.getForSecondary()); 288 default: 289 throw new IllegalStateException( 290 "Unknown WritableProfilePath tag " + profile.getTag()); 291 } 292 } 293 294 @NonNull toString(@onNull ProfilePath profile)295 public static String toString(@NonNull ProfilePath profile) { 296 switch (profile.getTag()) { 297 case ProfilePath.primaryRefProfilePath: 298 return toString(profile.getPrimaryRefProfilePath()); 299 case ProfilePath.secondaryRefProfilePath: 300 return toString(profile.getSecondaryRefProfilePath()); 301 case ProfilePath.prebuiltProfilePath: 302 return toString(profile.getPrebuiltProfilePath()); 303 case ProfilePath.dexMetadataPath: 304 return toString(profile.getDexMetadataPath()); 305 default: 306 throw new UnsupportedOperationException( 307 "Only a subset of profile paths are supported to be converted to string, " 308 + "got " + profile.getTag()); 309 } 310 } 311 312 @NonNull toString(@onNull SecureDexMetadataWithCompanionPaths paths)313 public static String toString(@NonNull SecureDexMetadataWithCompanionPaths paths) { 314 return String.format( 315 "SecureDexMetadataWithCompanionPaths[dexPath = %s, isa = %s, isInDalvikCache = %b]", 316 paths.dexPath, paths.isa, paths.isInDalvikCache); 317 } 318 } 319