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 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 isSystemApp, boolean isUpdatedSystemApp)133 public static void modifySharedLibraries(ParsedPackage parsedPackage, boolean isSystemApp, 134 boolean isUpdatedSystemApp) { 135 INSTANCE.updatePackage(parsedPackage, isSystemApp, isUpdatedSystemApp); 136 } 137 138 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)139 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 140 boolean isUpdatedSystemApp) { 141 for (PackageSharedLibraryUpdater packageUpdater : mPackageUpdaters) { 142 packageUpdater.updatePackage(parsedPackage, isSystemApp, isUpdatedSystemApp); 143 } 144 } 145 146 /** 147 * True if the android.test.base is on the bootclasspath, false otherwise. 148 */ 149 @VisibleForTesting bootClassPathContainsATB()150 public static boolean bootClassPathContainsATB() { 151 return INSTANCE.mBootClassPathContainsATB; 152 } 153 154 /** 155 * Add android.test.mock dependency for any APK that depends on android.test.runner. 156 * 157 * <p>This is needed to maintain backwards compatibility as in previous versions of Android the 158 * android.test.runner library included the classes from android.test.mock which have since 159 * been split out into a separate library. 160 * 161 * @hide 162 */ 163 @VisibleForTesting 164 public static class AndroidTestRunnerSplitUpdater extends PackageSharedLibraryUpdater { 165 166 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)167 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 168 boolean isUpdatedSystemApp) { 169 // android.test.runner has a dependency on android.test.mock so if android.test.runner 170 // is present but android.test.mock is not then add android.test.mock. 171 prefixImplicitDependency(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); 172 } 173 } 174 175 /** 176 * Remove any usages of org.apache.http.legacy from the shared library as the library is on the 177 * bootclasspath. 178 */ 179 @VisibleForTesting 180 public static class RemoveUnnecessaryOrgApacheHttpLegacyLibrary 181 extends PackageSharedLibraryUpdater { 182 183 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)184 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 185 boolean isUpdatedSystemApp) { 186 removeLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY); 187 } 188 189 } 190 191 /** 192 * Remove any usages of android.test.base from the shared library as the library is on the 193 * bootclasspath. 194 */ 195 @VisibleForTesting 196 public static class RemoveUnnecessaryAndroidTestBaseLibrary 197 extends PackageSharedLibraryUpdater { 198 199 @Override updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, boolean isUpdatedSystemApp)200 public void updatePackage(ParsedPackage parsedPackage, boolean isSystemApp, 201 boolean isUpdatedSystemApp) { 202 removeLibrary(parsedPackage, ANDROID_TEST_BASE); 203 } 204 } 205 } 206