1 /* 2 * Copyright (C) 2019 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.pm; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.util.Pair; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 import com.android.server.pm.parsing.pkg.AndroidPackage; 25 import com.android.server.pm.parsing.pkg.AndroidPackageUtils; 26 import com.android.server.pm.parsing.pkg.ParsedPackage; 27 28 import java.io.File; 29 import java.util.Set; 30 31 32 33 // TODO: Move to .parsing sub-package 34 @VisibleForTesting 35 public interface PackageAbiHelper { 36 /** 37 * Derive and get the location of native libraries for the given package, 38 * which varies depending on where and how the package was installed. 39 */ 40 @NonNull deriveNativeLibraryPaths(AndroidPackage pkg, boolean isUpdatedSystemApp, File appLib32InstallDir)41 NativeLibraryPaths deriveNativeLibraryPaths(AndroidPackage pkg, boolean isUpdatedSystemApp, 42 File appLib32InstallDir); 43 44 /** 45 * Calculate the abis for a bundled app. These can uniquely be determined from the contents of 46 * the system partition, i.e whether it contains 64 or 32 bit shared libraries etc. We do not 47 * validate any of this information, and instead assume that the system was built sensibly. 48 */ getBundledAppAbis(AndroidPackage pkg)49 Abis getBundledAppAbis(AndroidPackage pkg); 50 51 /** 52 * Derive the ABI of a non-system package located at {@code pkg}. This information 53 * is derived purely on the basis of the contents of {@code pkg} and {@code cpuAbiOverride}. 54 * 55 * If {@code extractLibs} is true, native libraries are extracted from the app if required. 56 */ derivePackageAbi(AndroidPackage pkg, boolean isUpdatedSystemApp, String cpuAbiOverride, File appLib32InstallDir)57 Pair<Abis, NativeLibraryPaths> derivePackageAbi(AndroidPackage pkg, boolean isUpdatedSystemApp, 58 String cpuAbiOverride, File appLib32InstallDir) throws PackageManagerException; 59 60 /** 61 * Calculates adjusted ABIs for a set of packages belonging to a shared user so that they all 62 * match. i.e, so that all packages can be run inside a single process if required. 63 * 64 * Optionally, callers can pass in a parsed package via {@code scannedPackage} in which case 65 * this function will either try and make the ABI for all packages in 66 * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of 67 * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This 68 * variant is used when installing or updating a package that belongs to a shared user. 69 * 70 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 71 * adds unnecessary complexity. 72 * 73 * @return the calculated primary abi that should be set for all non-specified packages 74 * belonging to the shared user. 75 */ 76 @Nullable getAdjustedAbiForSharedUser( Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage)77 String getAdjustedAbiForSharedUser( 78 Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage); 79 80 /** 81 * The native library paths and related properties that should be set on a 82 * {@link ParsedPackage}. 83 */ 84 final class NativeLibraryPaths { 85 public final String nativeLibraryRootDir; 86 public final boolean nativeLibraryRootRequiresIsa; 87 public final String nativeLibraryDir; 88 public final String secondaryNativeLibraryDir; 89 90 @VisibleForTesting NativeLibraryPaths(String nativeLibraryRootDir, boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir, String secondaryNativeLibraryDir)91 NativeLibraryPaths(String nativeLibraryRootDir, 92 boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir, 93 String secondaryNativeLibraryDir) { 94 this.nativeLibraryRootDir = nativeLibraryRootDir; 95 this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; 96 this.nativeLibraryDir = nativeLibraryDir; 97 this.secondaryNativeLibraryDir = secondaryNativeLibraryDir; 98 } 99 applyTo(ParsedPackage pkg)100 public void applyTo(ParsedPackage pkg) { 101 pkg.setNativeLibraryRootDir(nativeLibraryRootDir) 102 .setNativeLibraryRootRequiresIsa(nativeLibraryRootRequiresIsa) 103 .setNativeLibraryDir(nativeLibraryDir) 104 .setSecondaryNativeLibraryDir(secondaryNativeLibraryDir); 105 } 106 } 107 108 /** 109 * The primary and secondary ABIs that should be set on a package and its package setting. 110 */ 111 final class Abis { 112 public final String primary; 113 public final String secondary; 114 115 @VisibleForTesting Abis(String primary, String secondary)116 Abis(String primary, String secondary) { 117 this.primary = primary; 118 this.secondary = secondary; 119 } 120 Abis(AndroidPackage pkg, PackageSetting pkgSetting)121 Abis(AndroidPackage pkg, PackageSetting pkgSetting) { 122 this(AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting), 123 AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting)); 124 } 125 applyTo(ParsedPackage pkg)126 public void applyTo(ParsedPackage pkg) { 127 pkg.setPrimaryCpuAbi(primary) 128 .setSecondaryCpuAbi(secondary); 129 } applyTo(PackageSetting pkgSetting)130 public void applyTo(PackageSetting pkgSetting) { 131 // pkgSetting might be null during rescan following uninstall of updates 132 // to a bundled app, so accommodate that possibility. The settings in 133 // that case will be established later from the parsed package. 134 // 135 // If the settings aren't null, sync them up with what we've derived. 136 if (pkgSetting != null) { 137 pkgSetting.primaryCpuAbiString = primary; 138 pkgSetting.secondaryCpuAbiString = secondary; 139 } 140 } 141 } 142 } 143