• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 android.content.pm.cts;
18 
19 import static android.content.pm.ApplicationInfo.CATEGORY_ACCESSIBILITY;
20 import static android.content.pm.ApplicationInfo.CATEGORY_MAPS;
21 import static android.content.pm.ApplicationInfo.CATEGORY_PRODUCTIVITY;
22 import static android.content.pm.ApplicationInfo.CATEGORY_UNDEFINED;
23 import static android.content.pm.ApplicationInfo.FLAG_SUPPORTS_RTL;
24 
25 import static org.junit.Assert.assertArrayEquals;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertFalse;
28 import static org.junit.Assert.assertNotNull;
29 import static org.junit.Assert.assertNotSame;
30 import static org.junit.Assert.assertNull;
31 import static org.junit.Assert.assertSame;
32 import static org.junit.Assert.assertTrue;
33 import static org.junit.Assume.assumeFalse;
34 import static org.junit.Assume.assumeNotNull;
35 
36 import android.content.Context;
37 import android.content.pm.ApplicationInfo;
38 import android.content.pm.PackageInfo;
39 import android.content.pm.PackageManager;
40 import android.content.pm.PackageManager.NameNotFoundException;
41 import android.os.Build;
42 import android.os.Environment;
43 import android.os.Parcel;
44 import android.os.Process;
45 import android.os.UserHandle;
46 import android.platform.test.annotations.AppModeFull;
47 import android.platform.test.annotations.DisabledOnRavenwood;
48 import android.platform.test.ravenwood.RavenwoodRule;
49 import android.util.StringBuilderPrinter;
50 
51 import androidx.test.platform.app.InstrumentationRegistry;
52 import androidx.test.runner.AndroidJUnit4;
53 
54 import com.android.compatibility.common.util.SystemUtil;
55 
56 import org.junit.Rule;
57 import org.junit.Test;
58 import org.junit.runner.RunWith;
59 
60 /**
61  * Test {@link ApplicationInfo}.
62  */
63 @RunWith(AndroidJUnit4.class)
64 @AppModeFull // TODO(Instant) Figure out which APIs should work.
65 public class ApplicationInfoTest {
66     @Rule
67     public final RavenwoodRule mRavenwood = new RavenwoodRule();
68 
69     private static final String SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME = "com.android.cts.stub";
70     private static final String DIRECT_BOOT_UNAWARE_PACKAGE_NAME =
71             "android.content.cts.directbootunaware";
72     private static final String PARTIALLY_DIRECT_BOOT_AWARE_PACKAGE_NAME =
73             "android.content.cts.partiallydirectbootaware";
74     private static final String NO_APPLICATION_PACKAGE_NAME =
75             "android.content.cts.emptytestapp.stub";
76 
77     private static final String SAMPLE_APK_BASE = "/data/local/tmp/cts/content/";
78 
79     private static final String STUB_PACKAGE_APK = SAMPLE_APK_BASE
80             + "CtsSyncAccountAccessStubs.apk";
81 
getContext()82     private Context getContext() {
83         return InstrumentationRegistry.getInstrumentation().getTargetContext();
84     }
85 
getPackageName()86     private String getPackageName() {
87         return getContext().getPackageName();
88     }
89 
90     @Test
testConstructor()91     public void testConstructor() {
92         ApplicationInfo info = new ApplicationInfo();
93         // simple test to ensure packageName is copied by copy constructor
94         // TODO: consider expanding to check all member variables
95         info.packageName = "com.example";
96         ApplicationInfo copy = new ApplicationInfo(info);
97         assertEquals(info.packageName, copy.packageName);
98     }
99 
100     @Test
101     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testWriteToParcel()102     public void testWriteToParcel() throws NameNotFoundException {
103         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
104                 getPackageName(), PackageManager.ApplicationInfoFlags.of(0));
105 
106         Parcel p = Parcel.obtain();
107         applicationInfo.writeToParcel(p, 0);
108 
109         p.setDataPosition(0);
110         ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(p);
111         assertEquals(applicationInfo.taskAffinity, info.taskAffinity);
112         assertEquals(applicationInfo.permission, info.permission);
113         assertEquals(applicationInfo.processName, info.processName);
114         assertEquals(applicationInfo.className, info.className);
115         assertEquals(applicationInfo.theme, info.theme);
116         assertEquals(applicationInfo.flags, info.flags);
117         assertEquals(applicationInfo.sourceDir, info.sourceDir);
118         assertEquals(applicationInfo.publicSourceDir, info.publicSourceDir);
119         assertEquals(applicationInfo.sharedLibraryFiles, info.sharedLibraryFiles);
120         assertEquals(applicationInfo.dataDir, info.dataDir);
121         assertEquals(applicationInfo.uid, info.uid);
122         assertEquals(applicationInfo.enabled, info.enabled);
123         assertEquals(applicationInfo.manageSpaceActivityName, info.manageSpaceActivityName);
124         assertEquals(applicationInfo.descriptionRes, info.descriptionRes);
125     }
126 
127     @Test
testToString()128     public void testToString() {
129         ApplicationInfo applicationInfo = new ApplicationInfo();
130         assertNotNull(applicationInfo.toString());
131     }
132 
133     @Test
134     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testDescribeContents()135     public void testDescribeContents() throws NameNotFoundException {
136         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
137                 getPackageName(), PackageManager.ApplicationInfoFlags.of(0));
138 
139         assertEquals(0, applicationInfo.describeContents());
140     }
141 
142     @Test
testDump()143     public void testDump() {
144         ApplicationInfo applicationInfo = new ApplicationInfo();
145 
146         StringBuilder sb = new StringBuilder();
147         assertEquals(0, sb.length());
148         StringBuilderPrinter p = new StringBuilderPrinter(sb);
149 
150         String prefix = "";
151         applicationInfo.dump(p, prefix);
152         assertNotNull(sb.toString());
153         assertTrue(sb.length() > 0);
154     }
155 
156     @Test
157     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testLoadDescription()158     public void testLoadDescription() throws NameNotFoundException {
159         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
160                 getPackageName(), PackageManager.ApplicationInfoFlags.of(0));
161 
162         assertNull(applicationInfo.loadDescription(getContext().getPackageManager()));
163 
164         final int resHelloWorld = getContext().getResources()
165                 .getIdentifier("hello_world", "string", getContext().getPackageName());
166         applicationInfo.descriptionRes = resHelloWorld;
167         assertEquals(getContext().getResources().getString(resHelloWorld),
168                 applicationInfo.loadDescription(getContext().getPackageManager()));
169     }
170 
171     @Test
172     @DisabledOnRavenwood(blockedBy = PackageManager.class)
verifyOwnInfo()173     public void verifyOwnInfo() throws NameNotFoundException {
174         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
175                 getPackageName(), PackageManager.ApplicationInfoFlags.of(0));
176 
177         assertEquals("Android TestCase", applicationInfo.nonLocalizedLabel);
178         final int resSize4848 = getContext().getResources()
179                 .getIdentifier("size_48x48", "drawable", getContext().getPackageName());
180         assertEquals(resSize4848, applicationInfo.icon);
181         assertEquals("android.content.cts.MockApplication", applicationInfo.name);
182         int flags = FLAG_SUPPORTS_RTL;
183         assertEquals(flags, applicationInfo.flags & flags);
184         assertEquals(CATEGORY_PRODUCTIVITY, applicationInfo.category);
185     }
186 
installPackage(String apkPath)187     private void installPackage(String apkPath) {
188         assertEquals("Success\n", SystemUtil.runShellCommand(
189                 "pm install -t " + apkPath));
190     }
191 
192     @Test
193     @DisabledOnRavenwood(blockedBy = PackageManager.class)
verifyDefaultValues()194     public void verifyDefaultValues() throws NameNotFoundException {
195         // Make sure we install the original version of com.android.cts.stub.
196         installPackage(STUB_PACKAGE_APK);
197 
198         // The application "com.android.cts.stub" does not have any attributes set
199         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
200                 SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0));
201         int currentUserId = Process.myUserHandle().getIdentifier();
202 
203         assertNull(applicationInfo.className);
204         assertNull(applicationInfo.permission);
205         assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, applicationInfo.packageName);
206         assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, applicationInfo.processName);
207         assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, applicationInfo.taskAffinity);
208         assertTrue(UserHandle.isApp(applicationInfo.uid));
209         assertEquals(0, applicationInfo.theme);
210         assertEquals(0, applicationInfo.requiresSmallestWidthDp);
211         assertEquals(0, applicationInfo.compatibleWidthLimitDp);
212         assertEquals(0, applicationInfo.largestWidthLimitDp);
213         assertNotNull(applicationInfo.sourceDir);
214         assertEquals(applicationInfo.sourceDir, applicationInfo.publicSourceDir);
215         assertNull(applicationInfo.splitSourceDirs);
216         assertArrayEquals(applicationInfo.splitSourceDirs, applicationInfo.splitPublicSourceDirs);
217         assertEquals("/data/user/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
218                 applicationInfo.dataDir);
219         assertEquals("/data/user_de/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
220                 applicationInfo.deviceProtectedDataDir);
221         assertEquals("/data/user/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
222                 applicationInfo.credentialProtectedDataDir);
223         assertNull(applicationInfo.sharedLibraryFiles);
224         assertTrue(applicationInfo.enabled);
225         assertNull(applicationInfo.manageSpaceActivityName);
226         assertEquals(0, applicationInfo.descriptionRes);
227         assertEquals(0, applicationInfo.uiOptions);
228         assertEquals(CATEGORY_UNDEFINED, applicationInfo.category);
229         assertFalse(applicationInfo.hasFragileUserData());
230     }
231 
232     @Test(expected=IllegalArgumentException.class)
233     @DisabledOnRavenwood(blockedBy = PackageManager.class)
setOwnAppCategory()234     public void setOwnAppCategory() throws Exception {
235         getContext().getPackageManager().setApplicationCategoryHint(getContext().getPackageName(),
236                 CATEGORY_MAPS);
237     }
238 
239     @Test(expected=IllegalArgumentException.class)
240     @DisabledOnRavenwood(blockedBy = PackageManager.class)
setAppCategoryByNotInstaller()241     public void setAppCategoryByNotInstaller() throws Exception {
242         getContext().getPackageManager().setApplicationCategoryHint(
243                 SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, CATEGORY_MAPS);
244     }
245 
246     @Test
247     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testDirectBootUnawareAppIsNotEncryptionAware()248     public void testDirectBootUnawareAppIsNotEncryptionAware() throws Exception {
249         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
250                 DIRECT_BOOT_UNAWARE_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0));
251         assertFalse(applicationInfo.isEncryptionAware());
252     }
253 
254     @Test
255     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testDirectBootUnawareAppCategoryIsAccessibility()256     public void testDirectBootUnawareAppCategoryIsAccessibility() throws Exception {
257         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
258                 DIRECT_BOOT_UNAWARE_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0));
259         assertEquals(CATEGORY_ACCESSIBILITY, applicationInfo.category);
260     }
261 
262     @Test
263     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testDefaultAppCategoryIsUndefined()264     public void testDefaultAppCategoryIsUndefined() throws Exception {
265         final ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
266                 NO_APPLICATION_PACKAGE_NAME, PackageManager.ApplicationInfoFlags.of(0));
267         assertEquals(CATEGORY_UNDEFINED, applicationInfo.category);
268     }
269 
270     @Test
271     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testPartiallyDirectBootAwareAppIsEncryptionAware()272     public void testPartiallyDirectBootAwareAppIsEncryptionAware() throws Exception {
273         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
274                 PARTIALLY_DIRECT_BOOT_AWARE_PACKAGE_NAME,
275                 PackageManager.ApplicationInfoFlags.of(0));
276         assertTrue(applicationInfo.isEncryptionAware());
277     }
278 
279     @Test
280     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testWriteToParcelDontSquash()281     public void testWriteToParcelDontSquash() throws Exception {
282         // Make sure ApplicationInfo.writeToParcel() doesn't do the "squashing",
283         // because Parcel.allowSquashing() isn't called.
284 
285         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
286                 getPackageName(), PackageManager.ApplicationInfoFlags.of(0));
287 
288         final Parcel p = Parcel.obtain();
289         applicationInfo.writeToParcel(p, 0);
290         applicationInfo.writeToParcel(p, 0);
291 
292         // Don't call Parcel.allowSquashing()
293 
294         p.setDataPosition(0);
295         final ApplicationInfo copy1 = ApplicationInfo.CREATOR.createFromParcel(p);
296         final ApplicationInfo copy2 = ApplicationInfo.CREATOR.createFromParcel(p);
297 
298         p.recycle();
299 
300         assertNotSame(applicationInfo, copy1);
301 
302         // writeToParcel() doesn't do the squashing, so copy1 and copy2 will be different.
303         assertNotSame(copy1, copy2);
304 
305         // Check several fields to make sure they're properly copied.
306         assertEquals(applicationInfo.packageName, copy2.packageName);
307         assertEquals(copy1.packageName, copy2.packageName);
308 
309         assertEquals(applicationInfo.flags, copy2.flags);
310         assertEquals(copy1.flags, copy2.flags);
311     }
312 
313     @Test
314     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testWriteToParcelSquash()315     public void testWriteToParcelSquash() throws Exception {
316         // Make sure ApplicationInfo.writeToParcel() does the "squashing", after
317         // Parcel.allowSquashing() is called.
318 
319         ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(
320                 getPackageName(), PackageManager.ApplicationInfoFlags.of(0));
321 
322         final Parcel p = Parcel.obtain();
323 
324         final boolean prevSquashing = p.allowSquashing(); // Allow squashing.
325 
326         applicationInfo.writeToParcel(p, 0);
327         applicationInfo.writeToParcel(p, 0);
328 
329         p.setDataPosition(0);
330         final ApplicationInfo copy1 = ApplicationInfo.CREATOR.createFromParcel(p);
331         final ApplicationInfo copy2 = ApplicationInfo.CREATOR.createFromParcel(p);
332 
333         p.recycle();
334 
335         assertNotSame(applicationInfo, copy1);
336         assertSame(copy1, copy2); //
337 
338         p.restoreAllowSquashing(prevSquashing);
339     }
340 
341     @Test
342     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testIsProduct()343     public void testIsProduct() throws Exception {
344         // The product flag is supported since P. Suppose that devices lauch on Android P may not
345         // have product partition.
346         assumeFalse(Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.P);
347 
348         final String systemPath = Environment.getRootDirectory().getAbsolutePath();
349         final String productPath = Environment.getProductDirectory().getAbsolutePath();
350         final String packageName = getPartitionFirstPackageName(systemPath, productPath);
351         assertNotNull("Can not find any product packages on " + productPath + " or "
352                 + systemPath + productPath, packageName);
353 
354         final PackageInfo info = getContext().getPackageManager().getPackageInfo(
355                 packageName.trim(), 0 /* flags */);
356         assertTrue(packageName + " is not product package.", info.applicationInfo.isProduct());
357     }
358 
359     @Test
360     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testIsVendor()361     public void testIsVendor() throws Exception {
362         final String systemPath = Environment.getRootDirectory().getAbsolutePath();
363         final String vendorPath = Environment.getVendorDirectory().getAbsolutePath();
364         final String packageName = getPartitionFirstPackageName(systemPath, vendorPath);
365         // vendor package may not exist in every builds
366         assumeNotNull(packageName);
367 
368         final PackageInfo info = getContext().getPackageManager().getPackageInfo(
369                 packageName.trim(), PackageManager.PackageInfoFlags.of(0));
370         assertTrue(packageName + " is not vendor package.", info.applicationInfo.isVendor());
371     }
372 
373     @Test
374     @DisabledOnRavenwood(blockedBy = PackageManager.class)
testIsOem()375     public void testIsOem() throws Exception {
376         final String systemPath = Environment.getRootDirectory().getAbsolutePath();
377         final String oemPath = Environment.getOemDirectory().getAbsolutePath();
378         final String packageName = getPartitionFirstPackageName(systemPath, oemPath);
379         // Oem package may not exist in every builds like aosp.
380         assumeNotNull(packageName);
381 
382         final PackageInfo info = getContext().getPackageManager().getPackageInfo(
383                 packageName.trim(), PackageManager.PackageInfoFlags.of(0));
384         assertTrue(packageName + " is not oem package.", info.applicationInfo.isOem());
385     }
386 
getPartitionFirstPackageName(final String system, final String partition)387     private String getPartitionFirstPackageName(final String system, final String partition)
388             throws Exception {
389         // List package with "-f" option which contains package direction, use that to distinguish
390         // package partition and find out target package.
391         final String output = SystemUtil.runShellCommand(
392                 InstrumentationRegistry.getInstrumentation(), "pm list package -f -s");
393         final String[] packages = output.split("package:");
394         assertTrue("No system packages.", packages.length > 0);
395 
396         for (int i = 0; i < packages.length; i++) {
397             // Split package info to direction and name.
398             String[] info = packages[i].split("\\.apk=");
399             if (info.length != 2) continue; // Package info need include direction and name.
400             if (info[0] != null
401                     && (info[0].startsWith(partition + "/") || info[0].startsWith(system + partition + "/"))) {
402                 return info[1]; // Package name.
403             }
404         }
405         return null;
406     }
407 }
408