Home | History | Annotate | Download | only in deviceandprofileowner
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.deviceandprofileowner;
     18 
     19 import static android.app.admin.DevicePolicyManager.EXTRA_DELEGATION_SCOPES;
     20 import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
     21 import static android.app.admin.DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL;
     22 import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
     23 import static android.app.admin.DevicePolicyManager.DELEGATION_ENABLE_SYSTEM_APP;
     24 
     25 import android.app.admin.DevicePolicyManager;
     26 import android.content.BroadcastReceiver;
     27 import android.content.ComponentName;
     28 import android.content.Context;
     29 import android.content.Intent;
     30 import android.content.IntentFilter;
     31 import android.test.MoreAsserts;
     32 
     33 import java.util.Arrays;
     34 import java.util.List;
     35 import java.util.concurrent.Semaphore;
     36 import java.util.concurrent.TimeUnit;
     37 
     38 /**
     39  * Test that an app granted delegation scopes via {@link DevicePolicyManager#setDelegatedScopes} is
     40  * notified of its new scopes by a broadcast.
     41  */
     42 public class DelegationTest extends BaseDeviceAdminTest {
     43 
     44     private static final String DELEGATE_PKG = "com.android.cts.delegate";
     45     private static final String DELEGATE_ACTIVITY_NAME =
     46             DELEGATE_PKG + ".DelegatedScopesReceiverActivity";
     47     private static final String TEST_PKG = "com.android.cts.apprestrictions.targetapp";
     48 
     49     // Broadcasts received from the delegate app.
     50     private static final String ACTION_REPORT_SCOPES = "com.android.cts.delegate.report_scopes";
     51     private static final String ACTION_RUNNING = "com.android.cts.delegate.running";
     52 
     53     // Semaphores to synchronize communication with delegate app.
     54     private volatile String[] mReceivedScopes;
     55     private Semaphore mReceivedScopeReportSemaphore;
     56     private Semaphore mReceivedRunningSemaphore;
     57 
     58     // Receiver for incoming broadcasts from the delegate app.
     59     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
     60         @Override
     61         public void onReceive(Context context, Intent intent) {
     62             if (ACTION_REPORT_SCOPES.equals(intent.getAction())) {
     63                 synchronized (DelegationTest.this) {
     64                     mReceivedScopes = intent.getStringArrayExtra(EXTRA_DELEGATION_SCOPES);
     65                     mReceivedScopeReportSemaphore.release();
     66                 }
     67             } else if (ACTION_RUNNING.equals(intent.getAction())) {
     68                 synchronized (DelegationTest.this) {
     69                     mReceivedRunningSemaphore.release();
     70                 }
     71             }
     72         }
     73     };
     74 
     75     @Override
     76     public void setUp() throws Exception {
     77         super.setUp();
     78         mReceivedScopeReportSemaphore = new Semaphore(0);
     79         mReceivedRunningSemaphore = new Semaphore(0);
     80         mReceivedScopes = null;
     81         IntentFilter filter = new IntentFilter();
     82         filter.addAction(ACTION_REPORT_SCOPES);
     83         filter.addAction(ACTION_RUNNING);
     84         mContext.registerReceiver(mReceiver, filter);
     85     }
     86 
     87     @Override
     88     public void tearDown() throws Exception {
     89         mContext.unregisterReceiver(mReceiver);
     90         super.tearDown();
     91     }
     92 
     93     public void testDelegateReceivesScopeChangedBroadcast() throws InterruptedException {
     94         // Prepare the scopes to be delegated.
     95         final List<String> scopes = Arrays.asList(
     96                 DELEGATION_CERT_INSTALL,
     97                 DELEGATION_APP_RESTRICTIONS,
     98                 DELEGATION_BLOCK_UNINSTALL,
     99                 DELEGATION_ENABLE_SYSTEM_APP);
    100 
    101         // Start delegate so it can receive the scopes changed broadcast from DevicePolicyManager.
    102         startAndWaitDelegateActivity();
    103 
    104         // Set the delegated scopes.
    105         mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT, DELEGATE_PKG, scopes);
    106 
    107         // Wait until the delegate reports its new scopes.
    108         String reportedScopes[] = waitReportedScopes();
    109 
    110         // Check that the reported scopes correspond to scopes we delegated.
    111         assertNotNull("Received null scopes from delegate", reportedScopes);
    112         MoreAsserts.assertContentsInAnyOrder("Delegated scopes do not match broadcasted scopes",
    113                 scopes, reportedScopes);
    114     }
    115 
    116     public void testCantDelegateToUninstalledPackage() {
    117         // Prepare the package name and scopes to be delegated.
    118         final String NON_EXISTENT_PKG = "com.android.nonexistent.delegate";
    119         final List<String> scopes = Arrays.asList(
    120                 DELEGATION_CERT_INSTALL,
    121                 DELEGATION_ENABLE_SYSTEM_APP);
    122         try {
    123             // Trying to delegate to non existent package should throw.
    124             mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT,
    125                     NON_EXISTENT_PKG, scopes);
    126             fail("Should throw when delegating to non existent package");
    127         } catch(IllegalArgumentException expected) {
    128         }
    129         // Assert no scopes were delegated.
    130         assertTrue("Delegation scopes granted to non existent package", mDevicePolicyManager
    131                 .getDelegatedScopes(ADMIN_RECEIVER_COMPONENT, NON_EXISTENT_PKG).isEmpty());
    132     }
    133 
    134     public void testCanRetrieveDelegates() {
    135         final List<String> someScopes = Arrays.asList(
    136                 DELEGATION_APP_RESTRICTIONS,
    137                 DELEGATION_ENABLE_SYSTEM_APP);
    138         final List<String> otherScopes = Arrays.asList(
    139                 DELEGATION_BLOCK_UNINSTALL,
    140                 DELEGATION_ENABLE_SYSTEM_APP);
    141 
    142         // In the beginning there are no delegates.
    143         assertTrue("No delegates should be found", getDelegatePackages(DELEGATION_APP_RESTRICTIONS)
    144                 .isEmpty());
    145         assertTrue("No delegates should be found", getDelegatePackages(DELEGATION_BLOCK_UNINSTALL)
    146                 .isEmpty());
    147         assertTrue("No delegates should be found", getDelegatePackages(DELEGATION_ENABLE_SYSTEM_APP)
    148                 .isEmpty());
    149 
    150         // After delegating scopes to two packages.
    151         mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT,
    152                 DELEGATE_PKG, someScopes);
    153         mDevicePolicyManager.setDelegatedScopes(ADMIN_RECEIVER_COMPONENT,
    154                 TEST_PKG, otherScopes);
    155 
    156         // The expected delegates are returned.
    157         assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_APP_RESTRICTIONS)
    158                 .contains(DELEGATE_PKG));
    159         assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_BLOCK_UNINSTALL)
    160                 .contains(TEST_PKG));
    161         assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_ENABLE_SYSTEM_APP)
    162                 .contains(DELEGATE_PKG));
    163         assertTrue("Expected delegate not found", getDelegatePackages(DELEGATION_ENABLE_SYSTEM_APP)
    164                 .contains(TEST_PKG));
    165 
    166         // Packages are only returned in their recpective scopes.
    167         assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_APP_RESTRICTIONS)
    168                 .contains(TEST_PKG));
    169         assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_BLOCK_UNINSTALL)
    170                 .contains(DELEGATE_PKG));
    171         assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_CERT_INSTALL)
    172                 .contains(DELEGATE_PKG));
    173         assertFalse("Unexpected delegate package", getDelegatePackages(DELEGATION_CERT_INSTALL)
    174                 .contains(TEST_PKG));
    175     }
    176 
    177     private List<String> getDelegatePackages(String scope) {
    178         return mDevicePolicyManager.getDelegatePackages(ADMIN_RECEIVER_COMPONENT, scope);
    179     }
    180 
    181     private void startAndWaitDelegateActivity() throws InterruptedException {
    182         mContext.startActivity(new Intent()
    183                 .setComponent(new ComponentName(DELEGATE_PKG, DELEGATE_ACTIVITY_NAME))
    184                 .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
    185         assertTrue("DelegateApp did not start in time.",
    186                 mReceivedRunningSemaphore.tryAcquire(10, TimeUnit.SECONDS));
    187     }
    188 
    189     private String[] waitReportedScopes() throws InterruptedException {
    190         assertTrue("DelegateApp did not report scope in time.",
    191                 mReceivedScopeReportSemaphore.tryAcquire(10, TimeUnit.SECONDS));
    192         return mReceivedScopes;
    193     }
    194 }
    195