Migrate LauncherAppsTests.
Test: btest android.devicepolicy.cts.LauncherAppsTest
Fixes: 231910384
Fixes: 231910553
Fixes: 231910717
Fixes: 231910528
Change-Id: I28a655a28e15dfb31340c74434df44a54cfae327
diff --git a/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/parameterized/IncludeRunOnPrimaryUserWithNoDpc.java b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/parameterized/IncludeRunOnPrimaryUserWithNoDpc.java
new file mode 100644
index 0000000..8d89a62
--- /dev/null
+++ b/common/device-side/bedstead/harrier/common/src/main/java/com/android/bedstead/harrier/annotations/parameterized/IncludeRunOnPrimaryUserWithNoDpc.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.bedstead.harrier.annotations.parameterized;
+
+import static com.android.bedstead.harrier.annotations.AnnotationRunPrecedence.EARLY;
+
+import com.android.bedstead.harrier.annotations.AnnotationRunPrecedence;
+import com.android.bedstead.harrier.annotations.RequireRunOnPrimaryUser;
+import com.android.bedstead.harrier.annotations.enterprise.EnsureHasNoDpc;
+import com.android.bedstead.harrier.annotations.meta.ParameterizedAnnotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Parameterize a test so that it runs on the primary user and has no device owner or profile
+ * owners.
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@ParameterizedAnnotation
+@RequireRunOnPrimaryUser
+@EnsureHasNoDpc
+public @interface IncludeRunOnPrimaryUserWithNoDpc {
+ /**
+ * Weight sets the order that annotations will be resolved.
+ *
+ * <p>Annotations with a lower weight will be resolved before annotations with a higher weight.
+ *
+ * <p>If there is an order requirement between annotations, ensure that the weight of the
+ * annotation which must be resolved first is lower than the one which must be resolved later.
+ *
+ * <p>Weight can be set to a {@link AnnotationRunPrecedence} constant, or to any {@link int}.
+ */
+ int weight() default EARLY;
+}
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityReference.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityReference.java
index 4915f67..97f77a8 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityReference.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/activities/ActivityReference.java
@@ -17,9 +17,13 @@
package com.android.bedstead.nene.activities;
import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import com.android.bedstead.nene.TestApis;
+import com.android.bedstead.nene.exceptions.NeneException;
import com.android.bedstead.nene.packages.ComponentReference;
import com.android.bedstead.nene.packages.Package;
+import com.android.bedstead.nene.users.UserReference;
/**
* A representation of an activity on device which may or may not exist.
@@ -37,6 +41,52 @@
super(component.componentName());
}
+ /**
+ * Is this activity enabled.
+ */
+ public boolean isEnabled(UserReference user) {
+ // This currently uses activity-specific methods - it'd be great to have this at the top
+ // level and work for any component
+ try {
+ return TestApis.context().androidContextAsUser(user)
+ .getPackageManager()
+ .getActivityInfo(componentName(), 0)
+ .enabled;
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new NeneException("Activity does not exist or is not activity " + this, e);
+ }
+ }
+
+ /**
+ * Is this activity enabled.
+ */
+ public boolean isEnabled() {
+ return isEnabled(TestApis.users().instrumented());
+ }
+
+ /**
+ * Is this activity exported.
+ */
+ public boolean isExported(UserReference user) {
+ // This currently uses activity-specific methods - it'd be great to have this at the top
+ // level and work for any component
+ try {
+ return TestApis.context().androidContextAsUser(user)
+ .getPackageManager()
+ .getActivityInfo(componentName(), 0)
+ .exported;
+ } catch (PackageManager.NameNotFoundException e) {
+ throw new NeneException("Activity does not exist or is not activity " + this, e);
+ }
+ }
+
+ /**
+ * Is this activity exported.
+ */
+ public boolean isExported() {
+ return isExported(TestApis.users().instrumented());
+ }
+
@Override
public String toString() {
return "ActivityReference{component=" + super.toString() + "}";
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java
index 5698da2..59166c5 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Package.java
@@ -30,6 +30,8 @@
import static android.os.Build.VERSION_CODES.S;
import static android.os.Process.myUid;
+import static com.android.bedstead.nene.permissions.CommonPermissions.CHANGE_COMPONENT_ENABLED_STATE;
+
import static com.google.common.truth.Truth.assertWithMessage;
import android.annotation.TargetApi;
@@ -849,6 +851,43 @@
return packageInfo.sharedUserId;
}
+ /**
+ * See {@link PackageManager#setSyntheticAppDetailsActivityEnabled(String, boolean)}.
+ */
+ @Experimental
+ public void setSyntheticAppDetailsActivityEnabled(UserReference user, boolean enabled) {
+ try (PermissionContext p = TestApis.permissions()
+ .withPermission(CHANGE_COMPONENT_ENABLED_STATE)) {
+ TestApis.context().androidContextAsUser(user).getPackageManager()
+ .setSyntheticAppDetailsActivityEnabled(packageName(), enabled);
+ }
+ }
+
+ /**
+ * See {@link PackageManager#setSyntheticAppDetailsActivityEnabled(String, boolean)}.
+ */
+ @Experimental
+ public void setSyntheticAppDetailsActivityEnabled(boolean enabled) {
+ setSyntheticAppDetailsActivityEnabled(TestApis.users().instrumented(), enabled);
+ }
+
+ /**
+ * See {@link PackageManager#getSyntheticAppDetailsActivityEnabled(String)}.
+ */
+ @Experimental
+ public boolean syntheticAppDetailsActivityEnabled(UserReference user) {
+ return TestApis.context().androidContextAsUser(user).getPackageManager()
+ .getSyntheticAppDetailsActivityEnabled(packageName());
+ }
+
+ /**
+ * See {@link PackageManager#getSyntheticAppDetailsActivityEnabled(String)}.
+ */
+ @Experimental
+ public boolean syntheticAppDetailsActivityEnabled() {
+ return syntheticAppDetailsActivityEnabled(TestApis.users().instrumented());
+ }
+
private static final class ProcessInfo {
final String mPackageName;
final int mPid;
diff --git a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java
index f6ce364..3d1188a 100644
--- a/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java
+++ b/common/device-side/bedstead/nene/src/main/java/com/android/bedstead/nene/packages/Packages.java
@@ -44,6 +44,7 @@
import androidx.annotation.RequiresApi;
import com.android.bedstead.nene.TestApis;
+import com.android.bedstead.nene.activities.ActivityReference;
import com.android.bedstead.nene.annotations.Experimental;
import com.android.bedstead.nene.exceptions.AdbException;
import com.android.bedstead.nene.exceptions.AdbParseException;
@@ -536,6 +537,21 @@
}
/**
+ * Get a reference to a given {@code componentName} activity.
+ *
+ * <p>This does not guarantee that the component exists - nor that it is actually an activity.
+ */
+ @Experimental
+ public ActivityReference activity(ComponentName componentName) {
+ if (componentName == null) {
+ throw new NullPointerException();
+ }
+
+ return new ActivityReference(
+ find(componentName.getPackageName()), componentName.getClassName());
+ }
+
+ /**
* Get a reference to a given {@code componentName}.
*
* <p>This does not guarantee that the component exists.
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
index d994d21..b7be8d9 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
+++ b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
@@ -254,56 +254,6 @@
}
@Test
- public void testHasLauncherActivityAppHasAppDetailsActivityInjected() throws Exception {
- assumeNotHeadlessSystemUserMode();
-
- // HasLauncherActivityApp is installed for duration of this test - make sure
- // it's present on the activity list, has the synthetic activity generated, and it's
- // enabled and exported
- disableLauncherActivity();
- assertActivityInjected(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE);
- }
-
- @Test
- public void testGetSetSyntheticAppDetailsActivityEnabled() throws Exception {
- assumeNotHeadlessSystemUserMode();
-
- disableLauncherActivity();
- assertActivityInjected(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE);
- PackageManager pm = mContext.getPackageManager();
- try {
- pm.setSyntheticAppDetailsActivityEnabled(mContext.getPackageName(), false);
- fail("Should not able to change current app's app details activity state");
- } catch (SecurityException e) {
- // Expected: No permission
- }
- try {
- pm.setSyntheticAppDetailsActivityEnabled(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE, false);
- fail("Should not able to change other app's app details activity state");
- } catch (SecurityException e) {
- // Expected: No permission
- }
- mInstrumentation.getUiAutomation().adoptShellPermissionIdentity();
- try {
- assertThat(pm.getSyntheticAppDetailsActivityEnabled(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE))
- .isTrue();
- // Disable app details activity and assert if the change is applied
- pm.setSyntheticAppDetailsActivityEnabled(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE, false);
- assertThat(pm.getSyntheticAppDetailsActivityEnabled(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE))
- .isFalse();
- assertInjectedActivityNotFound(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE);
- // Enable app details activity and assert if the change is applied
- pm.setSyntheticAppDetailsActivityEnabled(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE, true);
- assertThat(pm.getSyntheticAppDetailsActivityEnabled(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE))
- .isTrue();
- assertActivityInjected(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE);
- } finally {
- mInstrumentation.getUiAutomation().dropShellPermissionIdentity();
- }
- }
-
-
- @Test
public void testProfileOwnerLauncherActivityInjected() throws Exception {
assertActivityInjected(MANAGED_PROFILE_PKG);
}
@@ -322,14 +272,7 @@
assertInjectedActivityNotFound(NO_PERMISSION_APP_PACKAGE);
}
- @Test
- public void testDoPoNoTestAppInjectedActivityFound() throws Exception {
- // HasLauncherActivityApp is installed for duration of this test - make sure
- // it's NOT present on the activity list For example, DO / PO mode won't show icons.
- // This test is being called by DeviceOwnerTest.
- disableLauncherActivity();
- assertInjectedActivityNotFound(HAS_LAUNCHER_ACTIVITY_APP_PACKAGE);
- }
+
@Test
public void testProfileOwnerInjectedActivityNotFound() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index c3ac137..48038c1 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -816,28 +816,6 @@
}
@Test
- public void testNoHiddenActivityFoundTest() throws Exception {
- try {
- // Install app to primary user
- installAppAsUser(BaseLauncherAppsTest.LAUNCHER_TESTS_APK, mPrimaryUserId);
- installAppAsUser(BaseLauncherAppsTest.LAUNCHER_TESTS_SUPPORT_APK, mPrimaryUserId);
- installAppAsUser(LAUNCHER_TESTS_HAS_LAUNCHER_ACTIVITY_APK, mPrimaryUserId);
-
- // Run test to check if launcher api shows hidden app
- String mSerialNumber = Integer.toString(getUserSerialNumber(mPrimaryUserId));
- runDeviceTestsAsUser(BaseLauncherAppsTest.LAUNCHER_TESTS_PKG,
- BaseLauncherAppsTest.LAUNCHER_TESTS_CLASS,
- "testDoPoNoTestAppInjectedActivityFound",
- mPrimaryUserId, Collections.singletonMap(BaseLauncherAppsTest.PARAM_TEST_USER,
- mSerialNumber));
- } finally {
- getDevice().uninstallPackage(LAUNCHER_TESTS_HAS_LAUNCHER_ACTIVITY_APK);
- getDevice().uninstallPackage(BaseLauncherAppsTest.LAUNCHER_TESTS_SUPPORT_APK);
- getDevice().uninstallPackage(BaseLauncherAppsTest.LAUNCHER_TESTS_APK);
- }
- }
-
- @Test
public void testSetGlobalSettingLogged() throws Exception {
assertMetricsLogged(getDevice(), () -> {
executeDeviceTestMethod(".DevicePolicyLoggingTest", "testSetGlobalSettingLogged");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
index fd267c0..cac30db 100755
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
@@ -116,21 +116,6 @@
mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mMainUserSerialNumber));
}
- @Test
- public void testNoHiddenActivityInProfile() throws Exception {
- // Install app for all users.
- installAppAsUser(LAUNCHER_TESTS_HAS_LAUNCHER_ACTIVITY_APK, mParentUserId);
- installAppAsUser(LAUNCHER_TESTS_HAS_LAUNCHER_ACTIVITY_APK, mProfileUserId);
-
- // Run tests to check SimpleApp exists in both profile and main user.
- runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
- LAUNCHER_TESTS_CLASS, "testDoPoNoTestAppInjectedActivityFound",
- mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mProfileSerialNumber));
- runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
- LAUNCHER_TESTS_CLASS, "testHasLauncherActivityAppHasAppDetailsActivityInjected",
- mParentUserId, Collections.singletonMap(PARAM_TEST_USER, mMainUserSerialNumber));
- }
-
@FlakyTest
@Test
public void testLauncherCallbackPackageAddedProfile() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LimitAppIconHidingTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LimitAppIconHidingTest.java
index 29f3d04..b823a94 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LimitAppIconHidingTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LimitAppIconHidingTest.java
@@ -74,13 +74,6 @@
}
@Test
- public void testHasLauncherActivityAppHasAppDetailsActivityInjected() throws Exception {
- runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
- LAUNCHER_TESTS_CLASS, "testHasLauncherActivityAppHasAppDetailsActivityInjected",
- mCurrentUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber));
- }
-
- @Test
public void testNoSystemAppHasSyntheticAppDetailsActivityInjected() throws Exception {
runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
LAUNCHER_TESTS_CLASS, "testNoSystemAppHasSyntheticAppDetailsActivityInjected",
@@ -100,11 +93,4 @@
LAUNCHER_TESTS_CLASS, "testNoPermissionAppNotInjected",
mCurrentUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber));
}
-
- @Test
- public void testGetSetSyntheticAppDetailsActivityEnabled() throws Exception {
- runDeviceTestsAsUser(LAUNCHER_TESTS_PKG,
- LAUNCHER_TESTS_CLASS, "testGetSetSyntheticAppDetailsActivityEnabled",
- mCurrentUserId, Collections.singletonMap(PARAM_TEST_USER, mSerialNumber));
- }
}
diff --git a/tests/devicepolicy/src/android/devicepolicy/cts/LauncherAppsTest.java b/tests/devicepolicy/src/android/devicepolicy/cts/LauncherAppsTest.java
index d6793ba..48e6767 100644
--- a/tests/devicepolicy/src/android/devicepolicy/cts/LauncherAppsTest.java
+++ b/tests/devicepolicy/src/android/devicepolicy/cts/LauncherAppsTest.java
@@ -16,31 +16,206 @@
package android.devicepolicy.cts;
-import static org.junit.Assert.assertNull;
+import static com.android.bedstead.nene.permissions.CommonPermissions.CHANGE_COMPONENT_ENABLED_STATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.os.Process;
import com.android.bedstead.harrier.BedsteadJUnit4;
+import com.android.bedstead.harrier.DeviceState;
+import com.android.bedstead.harrier.annotations.EnsureDoesNotHavePermission;
+import com.android.bedstead.harrier.annotations.EnsureHasPermission;
+import com.android.bedstead.harrier.annotations.RequireNotHeadlessSystemUserMode;
+import com.android.bedstead.harrier.annotations.parameterized.IncludeRunOnDeviceOwnerUser;
+import com.android.bedstead.harrier.annotations.parameterized.IncludeRunOnParentOfProfileOwnerWithNoDeviceOwner;
+import com.android.bedstead.harrier.annotations.parameterized.IncludeRunOnPrimaryUserWithNoDpc;
+import com.android.bedstead.harrier.annotations.parameterized.IncludeRunOnProfileOwnerProfileWithNoDeviceOwner;
import com.android.bedstead.nene.TestApis;
+import com.android.bedstead.testapp.TestApp;
+import com.android.bedstead.testapp.TestAppActivityReference;
+import com.android.bedstead.testapp.TestAppInstance;
+import com.android.queryable.queries.ActivityQuery;
+import com.android.queryable.queries.IntentFilterQuery;
+import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.List;
+
@RunWith(BedsteadJUnit4.class)
public final class LauncherAppsTest {
- private final Context sContext = TestApis.context().instrumentedContext();
- private final LauncherApps sLauncherApps = sContext.getSystemService(LauncherApps.class);
+ private static final Context sContext = TestApis.context().instrumentedContext();
+ private static final LauncherApps sLauncherApps = sContext.getSystemService(LauncherApps.class);
+ private static final String SYNTHETIC_APP_DETAILS_ACTIVITY = "android.app.AppDetailsActivity";
+ private static final PackageManager sPackageManager = sContext.getPackageManager();
+
+ @ClassRule @Rule
+ public static DeviceState sDeviceState = new DeviceState();
+
+
+ private static final ActivityQuery<?> MAIN_ACTIVITY_QUERY = ActivityQuery.activity()
+ .exported().isTrue()
+ .intentFilters().contains(
+ IntentFilterQuery.intentFilter()
+ .actions().contains(Intent.ACTION_MAIN)
+ .categories().contains(Intent.CATEGORY_LAUNCHER)
+ );
+
+ private static final TestApp sTestApp = sDeviceState.testApps().query()
+ .whereActivities().contains(MAIN_ACTIVITY_QUERY).get();
+
+ // TODO(257215214): Unrelated to device policy - move to PackageManager module
@Test
public void resolveActivity_invalid_doesNotCrash() {
- final Intent intent = new Intent();
+ Intent intent = new Intent();
intent.setComponent(new ComponentName("invalidPackage", "invalidClass"));
// Test that resolving invalid intent does not crash launcher
- assertNull(sLauncherApps.resolveActivity(intent, Process.myUserHandle()));
+ assertThat(sLauncherApps.resolveActivity(intent, Process.myUserHandle())).isNull();
+ }
+
+ @Test
+ @IncludeRunOnDeviceOwnerUser // Device Owner devices should not show hidden apps
+ @IncludeRunOnProfileOwnerProfileWithNoDeviceOwner // Work profiles should not show hidden apps
+ public void getActivityList_activityIsDisabled_isNotIncludedInList() {
+ // We install on the DPC user so that this installs in the work profile when there is one
+ try (TestAppInstance app = sTestApp.install(sDeviceState.dpc().user())) {
+ disableMainActivity(app);
+
+ List<LauncherActivityInfo> launcherActivities = sLauncherApps.getActivityList(
+ app.packageName(), app.user().userHandle());
+
+ assertThat(launcherActivities).isEmpty();
+ }
+ }
+
+
+ @Test
+ @IncludeRunOnPrimaryUserWithNoDpc // Synthetic activities should be injected in general
+ @IncludeRunOnParentOfProfileOwnerWithNoDeviceOwner // Should be injected for personal users with a work profile
+ @RequireNotHeadlessSystemUserMode(reason = "b/257217938 functionality is broken on headless")
+ public void getActivityList_launcherActivityIsDisabled_syntheticActivityIsIncluded() {
+ try (TestAppInstance app = sTestApp.install()) {
+ disableMainActivity(app);
+
+ List<LauncherActivityInfo> activities = sLauncherApps.getActivityList(
+ app.packageName(), app.user().userHandle());
+
+ assertSyntheticActivityIsIncluded(activities);
+ }
+ }
+
+ // TODO(257215214): Unrelated to device policy - move to PackageManager module
+ @Test
+ @EnsureDoesNotHavePermission(CHANGE_COMPONENT_ENABLED_STATE)
+ public void setSyntheticAppDetailsActivityEnabled_noPermission_throwsException() {
+ try (TestAppInstance app = sTestApp.install()) {
+ assertThrows(SecurityException.class, () ->
+ sPackageManager.setSyntheticAppDetailsActivityEnabled(
+ app.packageName(), /* enabled= */ false));
+ }
+ }
+
+ // TODO(257215214): Unrelated to device policy - move to PackageManager module
+ @Test
+ @EnsureHasPermission(CHANGE_COMPONENT_ENABLED_STATE)
+ public void setSyntheticAppDetailsActivityEnabled_true_isEnabled() {
+ try (TestAppInstance app = sTestApp.install()) {
+ disableMainActivity(app);
+
+ sPackageManager.setSyntheticAppDetailsActivityEnabled(
+ app.packageName(), /* enabled= */ true);
+
+ assertThat(app.testApp().pkg().syntheticAppDetailsActivityEnabled()).isTrue();
+ }
+ }
+
+ // TODO(257215214): Unrelated to device policy - move to PackageManager module
+ @Test
+ @EnsureHasPermission(CHANGE_COMPONENT_ENABLED_STATE)
+ @RequireNotHeadlessSystemUserMode(reason = "b/257217938 functionality is broken on headless")
+ public void setSyntheticAppDetailsActivityEnabled_true_activityListIncludesSyntheticActivity() {
+ try (TestAppInstance app = sTestApp.install()) {
+ disableMainActivity(app);
+
+ sPackageManager.setSyntheticAppDetailsActivityEnabled(
+ app.packageName(), /* enabled= */ true);
+
+ List<LauncherActivityInfo> activities = sLauncherApps.getActivityList(
+ app.packageName(), app.user().userHandle());
+ assertSyntheticActivityIsIncluded(activities);
+ }
+ }
+
+ // TODO(257215214): Unrelated to device policy - move to PackageManager module
+ @Test
+ @EnsureHasPermission(CHANGE_COMPONENT_ENABLED_STATE)
+ public void setSyntheticAppDetailsActivityEnabled_false_isNotEnabled() {
+ try (TestAppInstance app = sTestApp.install()) {
+ try {
+ disableMainActivity(app);
+
+ sPackageManager.setSyntheticAppDetailsActivityEnabled(
+ app.packageName(), /* enabled= */ false);
+
+ assertThat(app.testApp().pkg().syntheticAppDetailsActivityEnabled()).isFalse();
+ } finally {
+ app.testApp().pkg().setSyntheticAppDetailsActivityEnabled(true);
+ }
+ }
+ }
+
+ // TODO(257215214): Unrelated to device policy - move to PackageManager module
+ @Test
+ @EnsureHasPermission(CHANGE_COMPONENT_ENABLED_STATE)
+ public void setSyntheticAppDetailsActivityEnabled_false_activityListDoesNotIncludeSyntheticActivity() {
+ try (TestAppInstance app = sTestApp.install()) {
+ try {
+ disableMainActivity(app);
+
+ sPackageManager.setSyntheticAppDetailsActivityEnabled(
+ app.packageName(), /* enabled= */ false);
+
+ List<LauncherActivityInfo> activities = sLauncherApps.getActivityList(
+ app.packageName(), app.user().userHandle());
+ assertThat(activities).isEmpty();
+ } finally {
+ app.testApp().pkg().setSyntheticAppDetailsActivityEnabled(true);
+ }
+ }
+ }
+
+ private void disableMainActivity(TestAppInstance testApp) {
+ TestAppActivityReference activity = testApp.activities().query()
+ .whereActivity().exported().isTrue()
+ .whereActivity().intentFilters().contains(
+ IntentFilterQuery.intentFilter()
+ .actions().contains(Intent.ACTION_MAIN)
+ .categories().contains(Intent.CATEGORY_LAUNCHER)
+ ).get();
+ activity.component().disable();
+ }
+
+ private void assertSyntheticActivityIsIncluded(List<LauncherActivityInfo> activities) {
+ assertThat(activities).isNotEmpty();
+ for (LauncherActivityInfo info : activities) {
+ assertThat(info.getName()).isEqualTo(SYNTHETIC_APP_DETAILS_ACTIVITY);
+ assertThat(TestApis.packages().activity(info.getComponentName()).isEnabled())
+ .isTrue();
+ assertThat(TestApis.packages().activity(info.getComponentName()).isExported())
+ .isTrue();
+ }
}
}