• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.content.pm;
2 
3 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
4 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
5 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
6 import static android.content.pm.PackageManager.DONT_KILL_APP;
7 import static android.content.pm.PackageManager.GET_ACTIVITIES;
8 import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
9 import static android.content.pm.PackageManager.GET_SERVICES;
10 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
11 import static android.os.Build.VERSION_CODES.O;
12 import static com.google.common.truth.Truth.assertThat;
13 import static org.junit.Assert.fail;
14 
15 import android.content.ComponentName;
16 import android.content.Context;
17 import android.content.Intent;
18 import android.content.pm.PackageManager.NameNotFoundException;
19 import androidx.test.core.app.ApplicationProvider;
20 import androidx.test.ext.junit.runners.AndroidJUnit4;
21 import androidx.test.filters.SdkSuppress;
22 import java.util.ArrayList;
23 import java.util.List;
24 import org.junit.After;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.robolectric.annotation.Config;
29 import org.robolectric.annotation.internal.DoNotInstrument;
30 import org.robolectric.testapp.TestService;
31 
32 /** Compatibility test for {@link PackageManager} */
33 @DoNotInstrument
34 @RunWith(AndroidJUnit4.class)
35 public final class PackageManagerTest {
36   private Context context;
37   private PackageManager pm;
38 
39   @Before
setup()40   public void setup() throws Exception {
41     context = ApplicationProvider.getApplicationContext();
42     pm = context.getPackageManager();
43   }
44 
45   @After
tearDown()46   public void tearDown() {
47     pm.setApplicationEnabledSetting(
48         context.getPackageName(), COMPONENT_ENABLED_STATE_DEFAULT, DONT_KILL_APP);
49     pm.setComponentEnabledSetting(
50         new ComponentName(context, "org.robolectric.testapp.TestActivity"),
51         COMPONENT_ENABLED_STATE_DEFAULT,
52         DONT_KILL_APP);
53     pm.setComponentEnabledSetting(
54         new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity"),
55         COMPONENT_ENABLED_STATE_DEFAULT,
56         DONT_KILL_APP);
57   }
58 
59   @Test
60   @Config(minSdk = O)
61   @SdkSuppress(minSdkVersion = O)
isInstantApp_shouldNotBlowup()62   public void isInstantApp_shouldNotBlowup() {
63     assertThat(context.getPackageManager().isInstantApp()).isFalse();
64   }
65 
66   @Test
getPackageInfo()67   public void getPackageInfo() throws Exception {
68     PackageInfo info =
69         pm.getPackageInfo(
70             context.getPackageName(), MATCH_DISABLED_COMPONENTS | GET_ACTIVITIES | GET_SERVICES);
71     ActivityInfo[] activities = filterExtraneous(info.activities);
72 
73     assertThat(activities).hasLength(4);
74     assertThat(info.services).hasLength(1);
75 
76     assertThat(activities[0].name).isEqualTo("org.robolectric.testapp.TestActivity");
77     assertThat(activities[0].enabled).isTrue();
78     assertThat(activities[1].name).isEqualTo("org.robolectric.testapp.DisabledTestActivity");
79     assertThat(activities[1].enabled).isFalse();
80 
81     assertThat(info.services[0].name).isEqualTo("org.robolectric.testapp.TestService");
82     assertThat(info.services[0].enabled).isTrue();
83   }
84 
85   @Test
getPackageInfo_noFlagsGetNoComponents()86   public void getPackageInfo_noFlagsGetNoComponents() throws Exception {
87     PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0);
88     assertThat(info.activities).isNull();
89     assertThat(info.services).isNull();
90   }
91 
92   @Test
getPackageInfo_skipsDisabledComponents()93   public void getPackageInfo_skipsDisabledComponents() throws Exception {
94     PackageInfo info = pm.getPackageInfo(context.getPackageName(), GET_ACTIVITIES);
95     ActivityInfo[] activities = filterExtraneous(info.activities);
96 
97     assertThat(activities).hasLength(3);
98     assertThat(activities[0].name).isEqualTo("org.robolectric.testapp.TestActivity");
99   }
100 
101   @Test
getComponent_partialName()102   public void getComponent_partialName() {
103     ComponentName serviceName = new ComponentName(context, ".TestService");
104 
105     try {
106       pm.getServiceInfo(serviceName, 0);
107       fail("Expected NameNotFoundException");
108     } catch (NameNotFoundException expected) {
109     }
110   }
111 
112   @Test
getComponent_wrongNameActivity()113   public void getComponent_wrongNameActivity() {
114     ComponentName activityName = new ComponentName(context, "WrongNameActivity");
115 
116     try {
117       pm.getActivityInfo(activityName, 0);
118       fail("Expected NameNotFoundException");
119     } catch (NameNotFoundException expected) {
120     }
121   }
122 
123   @Test
getComponent_validName()124   public void getComponent_validName() throws Exception {
125     ComponentName componentName = new ComponentName(context, "org.robolectric.testapp.TestService");
126     ServiceInfo info = pm.getServiceInfo(componentName, 0);
127 
128     assertThat(info).isNotNull();
129   }
130 
131   @Test
getComponent_validName_queryWithMoreFlags()132   public void getComponent_validName_queryWithMoreFlags() throws Exception {
133     ComponentName componentName = new ComponentName(context, "org.robolectric.testapp.TestService");
134     ServiceInfo info = pm.getServiceInfo(componentName, MATCH_DISABLED_COMPONENTS);
135 
136     assertThat(info).isNotNull();
137   }
138 
139   @Test
queryIntentServices_noFlags()140   public void queryIntentServices_noFlags() {
141     List<ResolveInfo> result = pm.queryIntentServices(new Intent(context, TestService.class), 0);
142 
143     assertThat(result).hasSize(1);
144   }
145 
146   @Test
getComponent_disabledComponent_doesntInclude()147   public void getComponent_disabledComponent_doesntInclude() {
148     ComponentName disabledActivityName =
149         new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity");
150 
151     try {
152       pm.getActivityInfo(disabledActivityName, 0);
153       fail("NameNotFoundException expected");
154     } catch (NameNotFoundException expected) {
155     }
156   }
157 
158   @Test
getComponent_disabledComponent_include()159   public void getComponent_disabledComponent_include() throws Exception {
160     ComponentName disabledActivityName =
161         new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity");
162 
163     ActivityInfo info = pm.getActivityInfo(disabledActivityName, MATCH_DISABLED_COMPONENTS);
164     assertThat(info).isNotNull();
165     assertThat(info.enabled).isFalse();
166   }
167 
168   @Test
getPackageInfo_programmaticallyDisabledComponent_noFlags_notReturned()169   public void getPackageInfo_programmaticallyDisabledComponent_noFlags_notReturned() {
170     ComponentName activityName = new ComponentName(context, "org.robolectric.testapp.TestActivity");
171     pm.setComponentEnabledSetting(activityName, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
172 
173     try {
174       pm.getActivityInfo(activityName, 0);
175       fail("NameNotFoundException expected");
176     } catch (NameNotFoundException expected) {
177     }
178   }
179 
180   @Test
getPackageInfo_programmaticallyDisabledComponent_withFlags_returned()181   public void getPackageInfo_programmaticallyDisabledComponent_withFlags_returned()
182       throws Exception {
183     ComponentName activityName = new ComponentName(context, "org.robolectric.testapp.TestActivity");
184     pm.setComponentEnabledSetting(activityName, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
185 
186     ActivityInfo info = pm.getActivityInfo(activityName, MATCH_DISABLED_COMPONENTS);
187     assertThat(info).isNotNull();
188     // WHAT?? Seems like we always get the manifest value for ComponentInfo.enabled
189     assertThat(info.enabled).isTrue();
190     assertThat(info.isEnabled()).isTrue();
191   }
192 
193   @Test
getPackageInfo_programmaticallyEnabledComponent_returned()194   public void getPackageInfo_programmaticallyEnabledComponent_returned() throws Exception {
195     ComponentName activityName =
196         new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity");
197     pm.setComponentEnabledSetting(activityName, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
198 
199     ActivityInfo info = pm.getActivityInfo(activityName, 0);
200     assertThat(info).isNotNull();
201     // WHAT?? Seems like we always get the manifest value for ComponentInfo.enabled
202     assertThat(info.enabled).isFalse();
203     assertThat(info.isEnabled()).isFalse();
204   }
205 
206   @Test
207   @Config(maxSdk = 23)
208   @SdkSuppress(maxSdkVersion = 23)
getPackageInfo_disabledApplication_stillReturned_below24()209   public void getPackageInfo_disabledApplication_stillReturned_below24() throws Exception {
210     pm.setApplicationEnabledSetting(
211         context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
212 
213     PackageInfo packageInfo =
214         pm.getPackageInfo(context.getPackageName(), GET_SERVICES | GET_ACTIVITIES);
215     ActivityInfo[] activities = filterExtraneous(packageInfo.activities);
216 
217     assertThat(packageInfo.packageName).isEqualTo(context.getPackageName());
218     assertThat(packageInfo.applicationInfo.enabled).isFalse();
219 
220     // Seems that although disabled app makes everything disabled it is still returned with its
221     // manifest state below API 23
222     assertThat(activities).hasLength(3);
223     assertThat(packageInfo.services).hasLength(1);
224 
225     assertThat(activities[0].enabled).isTrue();
226     assertThat(packageInfo.services[0].enabled).isTrue();
227     assertThat(activities[0].isEnabled()).isFalse();
228     assertThat(packageInfo.services[0].isEnabled()).isFalse();
229   }
230 
231   @Test
232   @Config(minSdk = 24)
233   @SdkSuppress(minSdkVersion = 24)
getPackageInfo_disabledApplication_stillReturned_after24()234   public void getPackageInfo_disabledApplication_stillReturned_after24() throws Exception {
235     pm.setApplicationEnabledSetting(
236         context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
237 
238     PackageInfo packageInfo =
239         pm.getPackageInfo(context.getPackageName(), GET_SERVICES | GET_ACTIVITIES);
240 
241     assertThat(packageInfo.packageName).isEqualTo(context.getPackageName());
242     assertThat(packageInfo.applicationInfo.enabled).isFalse();
243 
244     // seems that since API 24 it is isEnabled() and not enabled that gets something into default
245     // result
246     assertThat(packageInfo.activities).isNull();
247     assertThat(packageInfo.services).isNull();
248   }
249 
250   @Test
getPackageInfo_disabledApplication_withFlags_returnedEverything()251   public void getPackageInfo_disabledApplication_withFlags_returnedEverything() throws Exception {
252     pm.setApplicationEnabledSetting(
253         context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
254 
255     PackageInfo packageInfo =
256         pm.getPackageInfo(
257             context.getPackageName(),
258             GET_SERVICES | GET_ACTIVITIES | MATCH_DISABLED_COMPONENTS);
259     ActivityInfo[] activities = filterExtraneous(packageInfo.activities);
260 
261     assertThat(packageInfo.applicationInfo.enabled).isFalse();
262     assertThat(packageInfo.packageName).isEqualTo(context.getPackageName());
263     assertThat(activities).hasLength(4);
264     assertThat(packageInfo.services).hasLength(1);
265     assertThat(activities[0].enabled).isTrue(); // default enabled flag
266   }
267 
268   @Test
getApplicationInfo_disabledApplication_stillReturnedWithNoFlags()269   public void getApplicationInfo_disabledApplication_stillReturnedWithNoFlags() throws Exception {
270     pm.setApplicationEnabledSetting(
271         context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
272 
273     ApplicationInfo applicationInfo = pm.getApplicationInfo(context.getPackageName(), 0);
274 
275     assertThat(applicationInfo.enabled).isFalse();
276     assertThat(applicationInfo.packageName).isEqualTo(context.getPackageName());
277   }
278 
279   @Test
queryIntentActivities_packageOnly()280   public void queryIntentActivities_packageOnly() {
281     List<ResolveInfo> resolveInfos =
282         pm.queryIntentActivities(
283             new Intent().setPackage(context.getPackageName()),
284             MATCH_DISABLED_COMPONENTS | GET_RESOLVED_FILTER);
285 
286     for (ResolveInfo resolveInfo : resolveInfos) {
287       assertThat(resolveInfo.filter).isNotNull();
288     }
289   }
290 
filterExtraneous(ActivityInfo[] activities)291   private ActivityInfo[] filterExtraneous(ActivityInfo[] activities) {
292     List<ActivityInfo> filtered = new ArrayList<>();
293     for (ActivityInfo activity : activities) {
294       if (activity.name.startsWith("org.robolectric")) {
295         filtered.add(activity);
296       }
297     }
298     return filtered.toArray(new ActivityInfo[0]);
299   }
300 }
301