blob: b3aeb80f2df050109fbf1686540837bbfc6a0f9a [file] [log] [blame]
/*
* Copyright (C) 2022 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 android.devicepolicy.cts;
import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.assertThrows;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.stats.devicepolicy.EventId;
import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
import com.android.bedstead.harrier.annotations.EnsureTestAppInstalled;
import com.android.bedstead.harrier.annotations.enterprise.CanSetPolicyTest;
import com.android.bedstead.harrier.annotations.enterprise.CannotSetPolicyTest;
import com.android.bedstead.harrier.annotations.enterprise.PolicyAppliesTest;
import com.android.bedstead.harrier.annotations.enterprise.PolicyDoesNotApplyTest;
import com.android.bedstead.harrier.annotations.enterprise.RequireHasPolicyExemptApps;
import com.android.bedstead.harrier.policies.ApplicationHidden;
import com.android.bedstead.harrier.policies.ApplicationHiddenSystemOnly;
import com.android.bedstead.metricsrecorder.EnterpriseMetricsRecorder;
import com.android.bedstead.metricsrecorder.truth.MetricQueryBuilderSubject;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.packages.Package;
import com.android.compatibility.common.util.BlockingBroadcastReceiver;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.runner.RunWith;
import java.util.Set;
import java.util.function.Function;
@RunWith(BedsteadJUnit4.class)
public class ApplicationHiddenTest {
@ClassRule @Rule
public static final DeviceState sDeviceState = new DeviceState();
private static final Package SYSTEM_PACKAGE =
TestApis.packages().find("com.android.keychain");
private static final Package NON_EXISTING_PACKAGE =
TestApis.packages().find("non.existing.package");
private static final PackageManager sLocalPackageManager =
TestApis.context().instrumentedContext().getPackageManager();
// TODO: All references to isApplicationHidden and setApplicationHidden which are not part of
// the "act" step of the test should run through a Nene API, once those APIs are permission
// accessible
private static final IntentFilter sPackageAddedIntentFilter = new IntentFilter();
private static final IntentFilter sPackageRemovedIntentFilter = new IntentFilter();
static {
sPackageAddedIntentFilter.addAction(ACTION_PACKAGE_ADDED);
sPackageRemovedIntentFilter.addAction(ACTION_PACKAGE_REMOVED);
sPackageAddedIntentFilter.addDataScheme("package");
sPackageRemovedIntentFilter.addDataScheme("package");
}
@Before
public void ensureSystemPackageInstalled() {
SYSTEM_PACKAGE.installExisting(TestApis.users().instrumented());
SYSTEM_PACKAGE.installExisting(sDeviceState.dpc().user());
}
@CanSetPolicyTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void isApplicationHidden_systemApp_isHidden_returnsTrue() {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
true);
assertThat(sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName())).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@CanSetPolicyTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void isApplicationHidden_systemApp_isNotHidden_returnsFalse() {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
false);
assertThat(sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName())).isFalse();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@CanSetPolicyTest(policy = ApplicationHiddenSystemOnly.class)
@EnsureTestAppInstalled
public void isApplicationHidden_notSystemApp_throwsException() {
assertThrows(SecurityException.class, () -> sDeviceState.dpc().devicePolicyManager()
.isApplicationHidden(sDeviceState.dpc().componentName(),
sDeviceState.testApp().packageName()));
}
@CanSetPolicyTest(policy = ApplicationHidden.class)
@EnsureTestAppInstalled
public void isApplicationHidden_notSystemApp_isHidden_returnsTrue() {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
true);
assertThat(sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(),
sDeviceState.testApp().packageName())).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
originalValue);
}
}
@CanSetPolicyTest(policy = ApplicationHidden.class)
@EnsureTestAppInstalled
public void isApplicationHidden_notSystemApp_isNotHidden_returnsFalse() {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
false);
assertThat(sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(),
sDeviceState.testApp().packageName())).isFalse();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
originalValue);
}
}
@PolicyAppliesTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void setApplicationHidden_systemApp_true_hidesApplication() throws Exception {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
false);
try (BlockingBroadcastReceiver broadcastReceiver =
sDeviceState.registerBroadcastReceiverForAllUsers(
sPackageRemovedIntentFilter,
isSchemeSpecificPart(SYSTEM_PACKAGE.packageName()))) {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
true);
assertThat(result).isTrue();
broadcastReceiver.awaitForBroadcastOrFail();
}
assertThat(SYSTEM_PACKAGE.installedOnUser()).isFalse();
assertThat(SYSTEM_PACKAGE.exists()).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@PolicyDoesNotApplyTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void setApplicationHidden_systemApp_true_applicationIsNotHidden() throws Exception {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
true);
assertThat(SYSTEM_PACKAGE.installedOnUser()).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@PolicyAppliesTest(policy = ApplicationHidden.class)
@EnsureTestAppInstalled
public void setApplicationHidden_nonSystemApp_true_hidesApplication() throws Exception {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
false);
try (BlockingBroadcastReceiver broadcastReceiver =
sDeviceState.registerBroadcastReceiverForAllUsers(
sPackageRemovedIntentFilter,
isSchemeSpecificPart(sDeviceState.testApp().packageName()))) {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
true);
assertThat(result).isTrue();
broadcastReceiver.awaitForBroadcastOrFail();
}
assertThat(sDeviceState.testApp().testApp().pkg().installedOnUser()).isFalse();
assertThat(sDeviceState.testApp().testApp().pkg().exists()).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
originalValue);
}
}
@PolicyAppliesTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void setApplicationHidden_systemApp_false_unHidesApplication() throws Exception {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
true);
try (BlockingBroadcastReceiver broadcastReceiver =
sDeviceState.registerBroadcastReceiverForAllUsers(
sPackageAddedIntentFilter,
isSchemeSpecificPart(SYSTEM_PACKAGE.packageName()))) {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
false);
assertThat(result).isTrue();
broadcastReceiver.awaitForBroadcastOrFail();
}
assertThat(SYSTEM_PACKAGE.installedOnUser()).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@PolicyAppliesTest(policy = ApplicationHidden.class)
@EnsureTestAppInstalled
public void setApplicationHidden_nonSystemApp_false_unHidesApplication() throws Exception {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName());
try {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
true);
try (BlockingBroadcastReceiver broadcastReceiver =
sDeviceState.registerBroadcastReceiverForAllUsers(
sPackageAddedIntentFilter,
isSchemeSpecificPart(sDeviceState.testApp().packageName()))) {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.testApp().packageName(),
false);
assertThat(result).isTrue();
broadcastReceiver.awaitForBroadcastOrFail();
}
assertThat(sDeviceState.testApp().testApp().pkg().installedOnUser()).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@CanSetPolicyTest(policy = ApplicationHidden.class)
@RequireHasPolicyExemptApps
public void setApplicationHidden_nonSystemApp_policyExempt_doesNotHideApplication() throws Exception {
Set<String> policyExemptApps = TestApis.devicePolicy().getPolicyExemptApps();
for (String packageName : policyExemptApps) {
try {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), packageName,
true);
assertThat(result).isFalse();
assertThat(TestApis.packages().find(packageName).installedOnUser()).isTrue();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
false);
}
}
}
@CannotSetPolicyTest(policy = ApplicationHidden.class)
public void setApplicationHidden_systemApp_notAllowed_throwsException() {
assertThrows(SecurityException.class,
() -> sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(),
SYSTEM_PACKAGE.packageName(), true));
}
@CanSetPolicyTest(policy = ApplicationHiddenSystemOnly.class)
@EnsureTestAppInstalled
public void setApplicationHidden_nonSystemApp_throwsException() {
assertThrows(SecurityException.class,
() -> sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(),
sDeviceState.testApp().packageName(), true));
}
@CanSetPolicyTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void setApplicationHidden_true_logsEvent() {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try (EnterpriseMetricsRecorder metrics = EnterpriseMetricsRecorder.create()) {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
true);
MetricQueryBuilderSubject.assertThat(metrics.query()
.whereType().isEqualTo(EventId.SET_APPLICATION_HIDDEN_VALUE)
.whereAdminPackageName().isEqualTo(sDeviceState.dpc().packageName())
.whereBoolean().isEqualTo(sDeviceState.dpc().isDelegate())
.whereStrings().contains(SYSTEM_PACKAGE.packageName())
.whereStrings().contains("hidden")
.whereStrings().contains(sDeviceState.dpc().isParentInstance() ? "calledFromParent" : "notCalledFromParent")
).wasLogged();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@CanSetPolicyTest(policy = {ApplicationHidden.class, ApplicationHiddenSystemOnly.class})
public void setApplicationHidden_false_logsEvent() {
boolean originalValue = sDeviceState.dpc().devicePolicyManager().isApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName());
try (EnterpriseMetricsRecorder metrics = EnterpriseMetricsRecorder.create()) {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
false);
MetricQueryBuilderSubject.assertThat(metrics.query()
.whereType().isEqualTo(EventId.SET_APPLICATION_HIDDEN_VALUE)
.whereAdminPackageName().isEqualTo(sDeviceState.dpc().packageName())
.whereBoolean().isEqualTo(sDeviceState.dpc().isDelegate())
.whereStrings().contains(SYSTEM_PACKAGE.packageName())
.whereStrings().contains("not_hidden")
.whereStrings().contains(sDeviceState.dpc().isParentInstance() ? "calledFromParent" : "notCalledFromParent")
).wasLogged();
} finally {
sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), SYSTEM_PACKAGE.packageName(),
originalValue);
}
}
@CanSetPolicyTest(policy = {ApplicationHidden.class})
public void setApplicationHidden_notInstalledPackage_returnsFalse() {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), NON_EXISTING_PACKAGE.packageName(),
true);
assertThat(result).isFalse();
}
@CanSetPolicyTest(policy = {ApplicationHidden.class})
public void setApplicationHidden_deviceAdmin_returnsFalse() {
boolean result = sDeviceState.dpc().devicePolicyManager().setApplicationHidden(
sDeviceState.dpc().componentName(), sDeviceState.dpcOnly().packageName(),
true);
assertThat(result).isFalse();
}
private Function<Intent, Boolean> isSchemeSpecificPart(String part) {
return (intent) -> intent.getData() != null
&& intent.getData().getSchemeSpecificPart().equals(part);
}
}