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 com.android.server.pm.parsing.library; 18 19 import static com.android.server.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; 20 import static com.android.server.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK; 21 import static com.android.server.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER; 22 import static com.android.server.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; 23 24 import android.util.Log; 25 26 import com.android.internal.annotations.VisibleForTesting; 27 import com.android.internal.pm.parsing.pkg.ParsedPackage; 28 import com.android.internal.pm.pkg.parsing.ParsingPackage; 29 import com.android.server.SystemConfig; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * Modifies {@link ParsedPackage} in order to maintain backwards compatibility. 36 * 37 * @hide 38 */ 39 @VisibleForTesting 40 public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { 41 42 private static final String TAG = PackageBackwardCompatibility.class.getSimpleName(); 43 44 private static final PackageBackwardCompatibility INSTANCE; 45 46 static { 47 final List<PackageSharedLibraryUpdater> packageUpdaters = new ArrayList<>(); 48 49 // Remove wear-sdk, it is added to boot classpath since Android Baklava. packageUpdaters.add(new WearSdkUpdater())50 packageUpdaters.add(new WearSdkUpdater()); 51 52 // Remove android.net.ipsec.ike library, it is added to boot classpath since Android S. packageUpdaters.add(new AndroidNetIpSecIkeUpdater())53 packageUpdaters.add(new AndroidNetIpSecIkeUpdater()); 54 55 // Remove com.google.android.maps library. packageUpdaters.add(new ComGoogleAndroidMapsUpdater())56 packageUpdaters.add(new ComGoogleAndroidMapsUpdater()); 57 58 // Automatically add the org.apache.http.legacy library to the app classpath if the app 59 // targets < P. packageUpdaters.add(new OrgApacheHttpLegacyUpdater())60 packageUpdaters.add(new OrgApacheHttpLegacyUpdater()); 61 packageUpdaters.add(new AndroidHidlUpdater())62 packageUpdaters.add(new AndroidHidlUpdater()); 63 64 // Add this before adding AndroidTestBaseUpdater so that android.test.base comes before 65 // android.test.mock. packageUpdaters.add(new AndroidTestRunnerSplitUpdater())66 packageUpdaters.add(new AndroidTestRunnerSplitUpdater()); 67 68 boolean bootClassPathContainsATB = !addUpdaterForAndroidTestBase(packageUpdaters); 69 70 // ApexSharedLibraryUpdater should be the last one, to allow modifications introduced by 71 // mainline after dessert release. packageUpdaters.add(new ApexSharedLibraryUpdater( SystemConfig.getInstance().getSharedLibraries()))72 packageUpdaters.add(new ApexSharedLibraryUpdater( 73 SystemConfig.getInstance().getSharedLibraries())); 74 75 PackageSharedLibraryUpdater[] updaterArray = packageUpdaters 76 .toArray(new PackageSharedLibraryUpdater[0]); 77 INSTANCE = new PackageBackwardCompatibility( 78 bootClassPathContainsATB, updaterArray); 79 } 80 81 /** 82 * Attempt to load and add the optional updater that will only be available when 83 * REMOVE_ATB_FROM_BCP=true. If that could not be found then add the default updater that 84 * will remove any references to org.apache.http.library from the package so that 85 * it does not try and load the library when it is on the bootclasspath. 86 * 87 * TODO:(b/135203078): Find a better way to do this. 88 */ addUpdaterForAndroidTestBase( List<PackageSharedLibraryUpdater> packageUpdaters)89 private static boolean addUpdaterForAndroidTestBase( 90 List<PackageSharedLibraryUpdater> packageUpdaters) { 91 boolean hasClass = false; 92 String className = "android.content.pm.AndroidTestBaseUpdater"; 93 try { 94 Class clazz = ParsingPackage.class.getClassLoader().loadClass(className); 95 hasClass = clazz != null; 96 Log.i(TAG, "Loaded " + className); 97 } catch (ClassNotFoundException e) { 98 Log.i(TAG, "Could not find " + className + ", ignoring"); 99 } 100 101 if (hasClass) { 102 packageUpdaters.add(new AndroidTestBaseUpdater()); 103 } else { 104 packageUpdaters.add(new RemoveUnnecessaryAndroidTestBaseLibrary()); 105 } 106 return hasClass; 107 } 108 109 @VisibleForTesting getInstance()110 public static PackageSharedLibraryUpdater getInstance() { 111 return INSTANCE; 112 } 113 114 private final boolean mBootClassPathContainsATB; 115 116 private final PackageSharedLibraryUpdater[] mPackageUpdaters; 117 118 @VisibleForTesting getPackageUpdaters()119 PackageSharedLibraryUpdater[] getPackageUpdaters() { 120 return mPackageUpdaters; 121 } 122 PackageBackwardCompatibility( boolean bootClassPathContainsATB, PackageSharedLibraryUpdater[] packageUpdaters)123 private PackageBackwardCompatibility( 124 boolean bootClassPathContainsATB, PackageSharedLibraryUpdater[] packageUpdaters) { 125 this.mBootClassPathContainsATB = bootClassPathContainsATB; 126 this.mPackageUpdaters = packageUpdaters; 127 } 128 129 /** 130 * Modify the shared libraries in the supplied {@link ParsedPackage} to maintain backwards 131 * compatibility. 132 * 133 * @param parsedPackage the {@link ParsedPackage} to modify. 134 */ 135 @VisibleForTesting modifySharedLibraries(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)136 public static void modifySharedLibraries(ParsedPackage parsedPackage, boolean isSystemApp, 137 boolean isUpdatedSystemApp) { 138 INSTANCE.updatePackage(parsedPackage, isSystemApp, isUpdatedSystemApp); 139 } 140 141 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)142 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 143 boolean isUpdatedSystemApp) { 144 for (PackageSharedLibraryUpdater packageUpdater : mPackageUpdaters) { 145 packageUpdater.updatePackage(parsedPackage, isSystemApp, isUpdatedSystemApp); 146 } 147 } 148 149 /** 150 * True if the android.test.base is on the bootclasspath, false otherwise. 151 */ 152 @VisibleForTesting bootClassPathContainsATB()153 public static boolean bootClassPathContainsATB() { 154 return INSTANCE.mBootClassPathContainsATB; 155 } 156 157 /** 158 * Add android.test.mock dependency for any APK that depends on android.test.runner. 159 * 160 * <p>This is needed to maintain backwards compatibility as in previous versions of Android the 161 * android.test.runner library included the classes from android.test.mock which have since 162 * been split out into a separate library. 163 * 164 * @hide 165 */ 166 @VisibleForTesting 167 public static class AndroidTestRunnerSplitUpdater extends PackageSharedLibraryUpdater { 168 169 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)170 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 171 boolean isUpdatedSystemApp) { 172 // android.test.runner has a dependency on android.test.mock so if android.test.runner 173 // is present but android.test.mock is not then add android.test.mock. 174 prefixImplicitDependency(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); 175 } 176 } 177 178 /** 179 * Remove any usages of org.apache.http.legacy from the shared library as the library is on the 180 * bootclasspath. 181 */ 182 @VisibleForTesting 183 public static class RemoveUnnecessaryOrgApacheHttpLegacyLibrary 184 extends PackageSharedLibraryUpdater { 185 186 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)187 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 188 boolean isUpdatedSystemApp) { 189 removeLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY); 190 } 191 192 } 193 194 /** 195 * Remove any usages of android.test.base from the shared library as the library is on the 196 * bootclasspath. 197 */ 198 @VisibleForTesting 199 public static class RemoveUnnecessaryAndroidTestBaseLibrary 200 extends PackageSharedLibraryUpdater { 201 202 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)203 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 204 boolean isUpdatedSystemApp) { 205 removeLibrary(parsedPackage, ANDROID_TEST_BASE); 206 } 207 } 208 } 209