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