blob: c9cf6484f047e42e1226bfa052d1b8c18b4313b1 [file] [log] [blame]
/*
* Copyright (C) 2017 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.cts.deviceandprofileowner;
import static android.app.admin.DevicePolicyManager.EXTRA_DELEGATION_SCOPES;
import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
import static android.app.admin.DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL;
import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
import static android.app.admin.DevicePolicyManager.DELEGATION_ENABLE_SYSTEM_APP;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.test.MoreAsserts;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* Test that an app granted delegation scopes via {@link DevicePolicyManager#setDelegatedScopes} is
* notified of its new scopes by a broadcast.
*/
public class DelegationTest extends BaseDeviceAdminTest {
private static final String DELEGATE_PKG = "com.android.cts.delegate";
private static final String DELEGATE_ACTIVITY_NAME =
DELEGATE_PKG + ".DelegatedScopesReceiverActivity";
private static final String TEST_PKG = "com.android.cts.apprestrictions.targetapp";
// Broadcasts received from the delegate app.
private static final String ACTION_REPORT_SCOPES = "com.android.cts.delegate.report_scopes";
private static final String ACTION_RUNNING = "com.android.cts.delegate.running";
// Semaphores to synchronize communication with delegate app.
private volatile String[] mReceivedScopes;
private Semaphore mReceivedScopeReportSemaphore;
private Semaphore mReceivedRunningSemaphore;
// Receiver for incoming broadcasts from the delegate app.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (ACTION_REPORT_SCOPES.equals(intent.getAction())) {
synchronized (DelegationTest.this) {
mReceivedScopes = intent.getStringArrayExtra(EXTRA_DELEGATION_SCOPES);
mReceivedScopeReportSemaphore.release();
}
} else if (ACTION_RUNNING.equals(intent.getAction())) {
synchronized (DelegationTest.this) {
mReceivedRunningSemaphore.release();
}
}
}
};
@Override
public void setUp() throws Exception {
super.setUp();
mReceivedScopeReportSemaphore = new Semaphore(0);
mReceivedRunningSemaphore = new Semaphore(0);
mReceivedScopes = null;
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_REPORT_SCOPES);
filter.addAction(ACTION_RUNNING);
mContext.registerReceiver(mReceiver, filter);
}
@Override
public void tearDown() throws Exception {
mContext.unregisterReceiver(mReceiver);
super.tearDown();
}
public void testDelegateReceivesScopeChangedBroadcast() throws InterruptedException {
// Prepare the scopes to be delegated.
final List<String> scopes = Arrays.asList(
DELEGATION_CERT_INSTALL,
DELEGATION_APP_RESTRICTIONS,
DELEGATION_BLOCK_UNINSTALL,
DELEGATION_ENABLE_SYSTEM_APP);
// Start delegate so it can receive the scopes changed broadcast from DevicePolicyManager.
startAndWaitDelegateActivity();
// Set the delegated scopes.
mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT, DELEGATE_PKG, scopes);
// Wait until the delegate reports its new scopes.
String reportedScopes[] = waitReportedScopes();
// Check that the reported scopes correspond to scopes we delegated.
assertNotNull("Received null scopes from delegate", reportedScopes);
MoreAsserts.assertContentsInAnyOrder("Delegated scopes do not match broadcasted scopes",
scopes, reportedScopes);
}
public void testCantDelegateToUninstalledPackage() {
// Prepare the package name and scopes to be delegated.
final String NON_EXISTENT_PKG = "com.android.nonexistent.delegate";
final List<String> scopes = Arrays.asList(
DELEGATION_CERT_INSTALL,
DELEGATION_ENABLE_SYSTEM_APP);
try {
// Trying to delegate to non existent package should throw.
mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT,
NON_EXISTENT_PKG, scopes);
fail("Should throw when delegating to non existent package");
} catch(IllegalArgumentException expected) {
}
// Assert no scopes were delegated.
assertTrue("Delegation scopes granted to non existent package", mDevicePolicyManager
.getDelegatedScopes(ADMIN_RECEIVER_COMPONENT, NON_EXISTENT_PKG).isEmpty());
}
public void testCanRetrieveDelegates() {
final List<String> someScopes = Arrays.asList(
DELEGATION_APP_RESTRICTIONS,
DELEGATION_ENABLE_SYSTEM_APP);
final List<String> otherScopes = Arrays.asList(
DELEGATION_BLOCK_UNINSTALL,
DELEGATION_ENABLE_SYSTEM_APP);
// In the beginning there are no delegates.
assertTrue("No delegates should be found", getDelegatePackages(DELEGATION_APP_RESTRICTIONS)
.isEmpty());
assertTrue("No delegates should be found", getDelegatePackages(DELEGATION_BLOCK_UNINSTALL)
.isEmpty());
assertTrue("No delegates should be found", getDelegatePackages(DELEGATION_ENABLE_SYSTEM_APP)
.isEmpty());
// After delegating scopes to two packages.
mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT,
DELEGATE_PKG, someScopes);
mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT,
TEST_PKG, otherScopes);
// The expected delegates are returned.
assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_APP_RESTRICTIONS)
.contains(DELEGATE_PKG));
assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_BLOCK_UNINSTALL)
.contains(TEST_PKG));
assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_ENABLE_SYSTEM_APP)
.contains(DELEGATE_PKG));
assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_ENABLE_SYSTEM_APP)
.contains(TEST_PKG));
// Packages are only returned in their recpective scopes.
assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_APP_RESTRICTIONS)
.contains(TEST_PKG));
assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_BLOCK_UNINSTALL)
.contains(DELEGATE_PKG));
assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_CERT_INSTALL)
.contains(DELEGATE_PKG));
assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_CERT_INSTALL)
.contains(TEST_PKG));
}
private List<String> getDelegatePackages(String scope) {
return mDevicePolicyManager.getDelegatePackages(ADMIN_RECEIVER_COMPONENT, scope);
}
private void startAndWaitDelegateActivity() throws InterruptedException {
mContext.startActivity(new Intent()
.setComponent(new ComponentName(DELEGATE_PKG, DELEGATE_ACTIVITY_NAME))
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
assertTrue("DelegateApp did not start in time.",
mReceivedRunningSemaphore.tryAcquire(10, TimeUnit.SECONDS));
}
private String[] waitReportedScopes() throws InterruptedException {
assertTrue("DelegateApp did not report scope in time.",
mReceivedScopeReportSemaphore.tryAcquire(10, TimeUnit.SECONDS));
return mReceivedScopes;
}
}