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.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 static com.google.common.truth.Truth.assertThat;
25 
26 import android.os.Build;
27 import android.platform.test.annotations.Presubmit;
28 
29 import androidx.test.filters.SmallTest;
30 
31 import com.android.internal.pm.parsing.pkg.PackageImpl;
32 import com.android.internal.pm.parsing.pkg.ParsedPackage;
33 import com.android.internal.pm.pkg.parsing.ParsingPackage;
34 import com.android.server.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary;
35 import com.android.server.pm.pkg.AndroidPackage;
36 
37 import org.junit.Assume;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.junit.runners.JUnit4;
41 
42 @Presubmit
43 @SmallTest
44 @RunWith(JUnit4.class)
45 public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdaterTest {
46 
47     @Test
null_usesLibraries_and_usesOptionalLibraries()48     public void null_usesLibraries_and_usesOptionalLibraries() {
49         ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
50                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
51                 .hideAsParsed());
52 
53         AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
54                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
55                 .hideAsParsed())
56                 .hideAsFinal();
57 
58         checkBackwardsCompatibility(before, after, false);
59     }
60 
61     /**
62      * Detect when the android.test.base is not on the bootclasspath.
63      *
64      * <p>This test will be ignored when org.apache.http.legacy is not on the bootclasspath and
65      * succeed otherwise. This allows a developer to ensure that the tests are being run in the
66      * correct environment.
67      */
68     @Test
detectWhenATBisOnBCP()69     public void detectWhenATBisOnBCP() {
70         Assume.assumeTrue(PackageBackwardCompatibility.bootClassPathContainsATB());
71     }
72 
73     /**
74      * Ensures that the {@link PackageBackwardCompatibility} uses {@link OrgApacheHttpLegacyUpdater}
75      * and {@link AndroidTestBaseUpdater} when necessary.
76      *
77      * <p>More comprehensive tests for that class can be found in
78      * {@link OrgApacheHttpLegacyUpdaterTest}.
79      */
80     @Test
targeted_at_O()81     public void targeted_at_O() {
82         ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
83                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
84                 .setTargetSdkVersion(Build.VERSION_CODES.O)
85                 .hideAsParsed());
86 
87         ParsingPackage after = PackageImpl.forTesting(PACKAGE_NAME)
88                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
89                 .setTargetSdkVersion(Build.VERSION_CODES.O);
90 
91         if (!PackageBackwardCompatibility.bootClassPathContainsATB()) {
92             after.addUsesLibrary(ANDROID_TEST_BASE);
93         }
94         after.addUsesLibrary(ORG_APACHE_HTTP_LEGACY);
95 
96         checkBackwardsCompatibility(before, ((ParsedPackage) after.hideAsParsed()).hideAsFinal(),
97                 false);
98     }
99 
100     /**
101      * Ensures that the {@link PackageBackwardCompatibility} uses
102      * {@link RemoveUnnecessaryAndroidTestBaseLibrary}
103      * when necessary.
104      *
105      * <p>More comprehensive tests for that class can be found in
106      * {@link RemoveUnnecessaryAndroidTestBaseLibraryTest}.
107      */
108     @Test
android_test_base_in_usesLibraries()109     public void android_test_base_in_usesLibraries() {
110         Assume.assumeTrue("Test requires that "
111                         + ANDROID_TEST_BASE + " is on the bootclasspath",
112                 PackageBackwardCompatibility.bootClassPathContainsATB());
113 
114         ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
115                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
116                 .addUsesLibrary(ANDROID_TEST_BASE)
117                 .hideAsParsed());
118 
119         // android.test.base should be removed from the libraries because it is provided
120         // on the bootclasspath and providing both increases start up cost unnecessarily.
121         AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
122                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
123                 .hideAsParsed())
124                 .hideAsFinal();
125 
126         checkBackwardsCompatibility(before, after, false);
127     }
128 
129     /**
130      * Ensures that the {@link PackageBackwardCompatibility} uses a
131      * {@link PackageBackwardCompatibility.AndroidTestRunnerSplitUpdater}.
132      *
133      * <p>More comprehensive tests for that class can be found in
134      * {@link AndroidTestRunnerSplitUpdaterTest}.
135      */
136     @Test
android_test_runner_in_usesLibraries()137     public void android_test_runner_in_usesLibraries() {
138         ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
139                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
140                 .addUsesLibrary(ANDROID_TEST_RUNNER)
141                 .hideAsParsed());
142 
143         ParsingPackage after = PackageImpl.forTesting(PACKAGE_NAME)
144                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
145         if (!PackageBackwardCompatibility.bootClassPathContainsATB()) {
146             after.addUsesLibrary(ANDROID_TEST_BASE);
147         }
148         after.addUsesLibrary(ANDROID_TEST_MOCK);
149         after.addUsesLibrary(ANDROID_TEST_RUNNER);
150 
151         checkBackwardsCompatibility(before, ((ParsedPackage) after.hideAsParsed()).hideAsFinal(),
152                 false);
153     }
154 
155     /**
156      * Ensures that the {@link PackageBackwardCompatibility} uses a
157      * {@link ComGoogleAndroidMapsUpdater}.
158      */
159     @Test
com_google_android_maps_in_usesLibraries()160     public void com_google_android_maps_in_usesLibraries() {
161         ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
162                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
163                 .addUsesLibrary("com.google.android.maps")
164                 .hideAsParsed());
165 
166         ParsingPackage after = PackageImpl.forTesting(PACKAGE_NAME)
167                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
168 
169         checkBackwardsCompatibility(before, ((ParsedPackage) after.hideAsParsed()).hideAsFinal(),
170                 false);
171     }
172 
173     /**
174      * Ensures that the {@link PackageBackwardCompatibility} uses a
175      * {@link AndroidNetIpSecIkeUpdater}.
176      */
177     @Test
android_net_ipsec_ike_in_usesLibraries()178     public void android_net_ipsec_ike_in_usesLibraries() {
179         ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
180                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
181                 .addUsesLibrary("android.net.ipsec.ike")
182                 .hideAsParsed());
183 
184         ParsingPackage after = PackageImpl.forTesting(PACKAGE_NAME)
185                 .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
186 
187         checkBackwardsCompatibility(before, ((ParsedPackage) after.hideAsParsed()).hideAsFinal(),
188                 false);
189     }
190 
191     /**
192      * Ensures that ApexSharedLibraryUpdater is the last updater in the list of package updaters
193      * used by PackageBackwardCompatibility.
194      *
195      * This is required so mainline can add and remove libraries installed by the platform updaters.
196      */
197     @Test
testApexPackageUpdaterOrdering()198     public void testApexPackageUpdaterOrdering() {
199         PackageBackwardCompatibility instance =
200                 (PackageBackwardCompatibility) PackageBackwardCompatibility.getInstance();
201         PackageSharedLibraryUpdater[] updaterArray = instance.getPackageUpdaters();
202 
203         PackageSharedLibraryUpdater lastUpdater = updaterArray[updaterArray.length - 1];
204         assertThat(lastUpdater).isInstanceOf(ApexSharedLibraryUpdater.class);
205     }
206 
checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after, boolean isSystemApp)207     private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after,
208             boolean isSystemApp) {
209         checkBackwardsCompatibility(before, after, isSystemApp,
210                 PackageBackwardCompatibility::getInstance);
211     }
212 }
213