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.ArraySet; 22 import android.util.Pair; 23 24 import com.android.internal.annotations.VisibleForTesting; 25 import com.android.internal.pm.parsing.pkg.ParsedPackage; 26 import com.android.server.pm.pkg.AndroidPackage; 27 import com.android.server.pm.pkg.PackageStateInternal; 28 29 import java.io.File; 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 isSystemApp, boolean isUpdatedSystemApp, File appLib32InstallDir)41 NativeLibraryPaths deriveNativeLibraryPaths(AndroidPackage pkg, boolean isSystemApp, 42 boolean isUpdatedSystemApp, 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 isSystemApp, boolean isUpdatedSystemApp, String cpuAbiOverride, File appLib32InstallDir)57 Pair<Abis, NativeLibraryPaths> derivePackageAbi(AndroidPackage pkg, boolean isSystemApp, 58 boolean isUpdatedSystemApp, String cpuAbiOverride, File appLib32InstallDir) 59 throws PackageManagerException; 60 61 /** 62 * Calculates adjusted ABIs for a set of packages belonging to a shared user so that they all 63 * match. i.e, so that all packages can be run inside a single process if required. 64 * 65 * Optionally, callers can pass in a parsed package via {@code scannedPackage} in which case 66 * this function will either try and make the ABI for all packages in 67 * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of 68 * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This 69 * variant is used when installing or updating a package that belongs to a shared user. 70 * 71 * NOTE: We currently only match for the primary CPU abi string. Matching the secondary 72 * adds unnecessary complexity. 73 * 74 * @return the calculated primary abi that should be set for all non-specified packages 75 * belonging to the shared user. 76 */ 77 @Nullable getAdjustedAbiForSharedUser(ArraySet<? extends PackageStateInternal> packagesForUser, AndroidPackage scannedPackage)78 String getAdjustedAbiForSharedUser(ArraySet<? extends PackageStateInternal> packagesForUser, 79 AndroidPackage scannedPackage); 80 81 /** 82 * The native library paths and related properties that should be set on a 83 * {@link ParsedPackage}. 84 */ 85 final class NativeLibraryPaths { 86 public final String nativeLibraryRootDir; 87 public final boolean nativeLibraryRootRequiresIsa; 88 public final String nativeLibraryDir; 89 public final String secondaryNativeLibraryDir; 90 91 @VisibleForTesting NativeLibraryPaths(String nativeLibraryRootDir, boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir, String secondaryNativeLibraryDir)92 NativeLibraryPaths(String nativeLibraryRootDir, 93 boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir, 94 String secondaryNativeLibraryDir) { 95 this.nativeLibraryRootDir = nativeLibraryRootDir; 96 this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa; 97 this.nativeLibraryDir = nativeLibraryDir; 98 this.secondaryNativeLibraryDir = secondaryNativeLibraryDir; 99 } 100 applyTo(ParsedPackage pkg)101 public void applyTo(ParsedPackage pkg) { 102 pkg.setNativeLibraryRootDir(nativeLibraryRootDir) 103 .setNativeLibraryRootRequiresIsa(nativeLibraryRootRequiresIsa) 104 .setNativeLibraryDir(nativeLibraryDir) 105 .setSecondaryNativeLibraryDir(secondaryNativeLibraryDir); 106 } 107 } 108 109 /** 110 * The primary and secondary ABIs that should be set on a package and its package setting. 111 */ 112 final class Abis { 113 public final String primary; 114 public final String secondary; 115 116 @VisibleForTesting Abis(String primary, String secondary)117 Abis(String primary, String secondary) { 118 this.primary = primary; 119 this.secondary = secondary; 120 } 121 applyTo(ParsedPackage pkg)122 public void applyTo(ParsedPackage pkg) { 123 pkg.setPrimaryCpuAbi(primary) 124 .setSecondaryCpuAbi(secondary); 125 } applyTo(PackageSetting pkgSetting)126 public void applyTo(PackageSetting pkgSetting) { 127 // pkgSetting might be null during rescan following uninstall of updates 128 // to a bundled app, so accommodate that possibility. The settings in 129 // that case will be established later from the parsed package. 130 // 131 // If the settings aren't null, sync them up with what we've derived. 132 if (pkgSetting != null) { 133 pkgSetting.setPrimaryCpuAbi(primary); 134 pkgSetting.setSecondaryCpuAbi(secondary); 135 } 136 } 137 } 138 } 139