blob: 694760b571f93f2b1e8460db47a06fb1b5ec7f2c [file] [log] [blame]
package android.content.pm;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.DONT_KILL_APP;
import static android.content.pm.PackageManager.GET_ACTIVITIES;
import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.os.Build.VERSION_CODES.O;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SdkSuppress;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.internal.DoNotInstrument;
import org.robolectric.testapp.TestService;
/** Compatibility test for {@link PackageManager} */
@DoNotInstrument
@RunWith(AndroidJUnit4.class)
public final class PackageManagerTest {
private Context context;
private PackageManager pm;
@Before
public void setup() throws Exception {
context = ApplicationProvider.getApplicationContext();
pm = context.getPackageManager();
}
@After
public void tearDown() {
pm.setApplicationEnabledSetting(
context.getPackageName(), COMPONENT_ENABLED_STATE_DEFAULT, DONT_KILL_APP);
pm.setComponentEnabledSetting(
new ComponentName(context, "org.robolectric.testapp.TestActivity"),
COMPONENT_ENABLED_STATE_DEFAULT,
DONT_KILL_APP);
pm.setComponentEnabledSetting(
new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity"),
COMPONENT_ENABLED_STATE_DEFAULT,
DONT_KILL_APP);
}
@Test
@Config(minSdk = O)
@SdkSuppress(minSdkVersion = O)
public void isInstantApp_shouldNotBlowup() {
assertThat(context.getPackageManager().isInstantApp()).isFalse();
}
@Test
public void getPackageInfo() throws Exception {
PackageInfo info =
pm.getPackageInfo(
context.getPackageName(), MATCH_DISABLED_COMPONENTS | GET_ACTIVITIES | GET_SERVICES);
ActivityInfo[] activities = filterExtraneous(info.activities);
assertThat(activities).hasLength(4);
assertThat(info.services).hasLength(1);
assertThat(activities[0].name).isEqualTo("org.robolectric.testapp.TestActivity");
assertThat(activities[0].enabled).isTrue();
assertThat(activities[1].name).isEqualTo("org.robolectric.testapp.DisabledTestActivity");
assertThat(activities[1].enabled).isFalse();
assertThat(info.services[0].name).isEqualTo("org.robolectric.testapp.TestService");
assertThat(info.services[0].enabled).isTrue();
}
@Test
public void getPackageInfo_noFlagsGetNoComponents() throws Exception {
PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0);
assertThat(info.activities).isNull();
assertThat(info.services).isNull();
}
@Test
public void getPackageInfo_skipsDisabledComponents() throws Exception {
PackageInfo info = pm.getPackageInfo(context.getPackageName(), GET_ACTIVITIES);
ActivityInfo[] activities = filterExtraneous(info.activities);
assertThat(activities).hasLength(3);
assertThat(activities[0].name).isEqualTo("org.robolectric.testapp.TestActivity");
}
@Test
public void getComponent_partialName() {
ComponentName serviceName = new ComponentName(context, ".TestService");
try {
pm.getServiceInfo(serviceName, 0);
fail("Expected NameNotFoundException");
} catch (NameNotFoundException expected) {
}
}
@Test
public void getComponent_wrongNameActivity() {
ComponentName activityName = new ComponentName(context, "WrongNameActivity");
try {
pm.getActivityInfo(activityName, 0);
fail("Expected NameNotFoundException");
} catch (NameNotFoundException expected) {
}
}
@Test
public void getComponent_validName() throws Exception {
ComponentName componentName = new ComponentName(context, "org.robolectric.testapp.TestService");
ServiceInfo info = pm.getServiceInfo(componentName, 0);
assertThat(info).isNotNull();
}
@Test
public void getComponent_validName_queryWithMoreFlags() throws Exception {
ComponentName componentName = new ComponentName(context, "org.robolectric.testapp.TestService");
ServiceInfo info = pm.getServiceInfo(componentName, MATCH_DISABLED_COMPONENTS);
assertThat(info).isNotNull();
}
@Test
public void queryIntentServices_noFlags() {
List<ResolveInfo> result = pm.queryIntentServices(new Intent(context, TestService.class), 0);
assertThat(result).hasSize(1);
}
@Test
public void getComponent_disabledComponent_doesntInclude() {
ComponentName disabledActivityName =
new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity");
try {
pm.getActivityInfo(disabledActivityName, 0);
fail("NameNotFoundException expected");
} catch (NameNotFoundException expected) {
}
}
@Test
public void getComponent_disabledComponent_include() throws Exception {
ComponentName disabledActivityName =
new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity");
ActivityInfo info = pm.getActivityInfo(disabledActivityName, MATCH_DISABLED_COMPONENTS);
assertThat(info).isNotNull();
assertThat(info.enabled).isFalse();
}
@Test
public void getPackageInfo_programmaticallyDisabledComponent_noFlags_notReturned() {
ComponentName activityName = new ComponentName(context, "org.robolectric.testapp.TestActivity");
pm.setComponentEnabledSetting(activityName, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
try {
pm.getActivityInfo(activityName, 0);
fail("NameNotFoundException expected");
} catch (NameNotFoundException expected) {
}
}
@Test
public void getPackageInfo_programmaticallyDisabledComponent_withFlags_returned()
throws Exception {
ComponentName activityName = new ComponentName(context, "org.robolectric.testapp.TestActivity");
pm.setComponentEnabledSetting(activityName, COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
ActivityInfo info = pm.getActivityInfo(activityName, MATCH_DISABLED_COMPONENTS);
assertThat(info).isNotNull();
// WHAT?? Seems like we always get the manifest value for ComponentInfo.enabled
assertThat(info.enabled).isTrue();
assertThat(info.isEnabled()).isTrue();
}
@Test
public void getPackageInfo_programmaticallyEnabledComponent_returned() throws Exception {
ComponentName activityName =
new ComponentName(context, "org.robolectric.testapp.DisabledTestActivity");
pm.setComponentEnabledSetting(activityName, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
ActivityInfo info = pm.getActivityInfo(activityName, 0);
assertThat(info).isNotNull();
// WHAT?? Seems like we always get the manifest value for ComponentInfo.enabled
assertThat(info.enabled).isFalse();
assertThat(info.isEnabled()).isFalse();
}
@Test
@Config(maxSdk = 23)
@SdkSuppress(maxSdkVersion = 23)
public void getPackageInfo_disabledApplication_stillReturned_below24() throws Exception {
pm.setApplicationEnabledSetting(
context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
PackageInfo packageInfo =
pm.getPackageInfo(context.getPackageName(), GET_SERVICES | GET_ACTIVITIES);
ActivityInfo[] activities = filterExtraneous(packageInfo.activities);
assertThat(packageInfo.packageName).isEqualTo(context.getPackageName());
assertThat(packageInfo.applicationInfo.enabled).isFalse();
// Seems that although disabled app makes everything disabled it is still returned with its
// manifest state below API 23
assertThat(activities).hasLength(3);
assertThat(packageInfo.services).hasLength(1);
assertThat(activities[0].enabled).isTrue();
assertThat(packageInfo.services[0].enabled).isTrue();
assertThat(activities[0].isEnabled()).isFalse();
assertThat(packageInfo.services[0].isEnabled()).isFalse();
}
@Test
@Config(minSdk = 24)
@SdkSuppress(minSdkVersion = 24)
public void getPackageInfo_disabledApplication_stillReturned_after24() throws Exception {
pm.setApplicationEnabledSetting(
context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
PackageInfo packageInfo =
pm.getPackageInfo(context.getPackageName(), GET_SERVICES | GET_ACTIVITIES);
assertThat(packageInfo.packageName).isEqualTo(context.getPackageName());
assertThat(packageInfo.applicationInfo.enabled).isFalse();
// seems that since API 24 it is isEnabled() and not enabled that gets something into default
// result
assertThat(packageInfo.activities).isNull();
assertThat(packageInfo.services).isNull();
}
@Test
public void getPackageInfo_disabledApplication_withFlags_returnedEverything() throws Exception {
pm.setApplicationEnabledSetting(
context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
PackageInfo packageInfo =
pm.getPackageInfo(
context.getPackageName(),
GET_SERVICES | GET_ACTIVITIES | MATCH_DISABLED_COMPONENTS);
ActivityInfo[] activities = filterExtraneous(packageInfo.activities);
assertThat(packageInfo.applicationInfo.enabled).isFalse();
assertThat(packageInfo.packageName).isEqualTo(context.getPackageName());
assertThat(activities).hasLength(4);
assertThat(packageInfo.services).hasLength(1);
assertThat(activities[0].enabled).isTrue(); // default enabled flag
}
@Test
public void getApplicationInfo_disabledApplication_stillReturnedWithNoFlags() throws Exception {
pm.setApplicationEnabledSetting(
context.getPackageName(), COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
ApplicationInfo applicationInfo = pm.getApplicationInfo(context.getPackageName(), 0);
assertThat(applicationInfo.enabled).isFalse();
assertThat(applicationInfo.packageName).isEqualTo(context.getPackageName());
}
@Test
public void queryIntentActivities_packageOnly() {
List<ResolveInfo> resolveInfos =
pm.queryIntentActivities(
new Intent().setPackage(context.getPackageName()),
MATCH_DISABLED_COMPONENTS | GET_RESOLVED_FILTER);
for (ResolveInfo resolveInfo : resolveInfos) {
assertThat(resolveInfo.filter).isNotNull();
}
}
private ActivityInfo[] filterExtraneous(ActivityInfo[] activities) {
List<ActivityInfo> filtered = new ArrayList<>();
for (ActivityInfo activity : activities) {
if (activity.name.startsWith("org.robolectric")) {
filtered.add(activity);
}
}
return filtered.toArray(new ActivityInfo[0]);
}
}