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