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