Add CTS test for DISALLOW_MODIFY_ACCOUNTS

This test was previously in XTS and is ported across to CTS.

Bug: 22030831
Change-Id: Idd886b85305fb4f160deffe002ff9e87f999ed58
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java
index 2d30ee3..d93c8f2 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java
@@ -24,6 +24,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.UserManager;
 
 import java.io.IOException;
 
@@ -51,13 +52,19 @@
         super.setUp();
         mAccountManager = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
         clearAllAccountManagementDisabled();
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
         AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_1);
+        AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_2);
     }
 
     @Override
     protected void tearDown() throws Exception {
         clearAllAccountManagementDisabled();
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
         AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_1);
+        AccountUtilsTest.removeAllAccountsForType(mAccountManager, ACCOUNT_TYPE_2);
         super.tearDown();
     }
 
@@ -157,6 +164,66 @@
         assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
     }
 
+    public void testUserRestriction_addAccount() throws AuthenticatorException, IOException,
+            OperationCanceledException {
+        // Test for restriction on addAccount()
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+
+        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+        // Management is disabled, adding account should fail.
+        try {
+            mAccountManager.addAccount(ACCOUNT_TYPE_1, null, null, null, null, null, null)
+                    .getResult();
+            fail("Expected OperationCanceledException is not thrown.");
+        } catch (OperationCanceledException e) {
+            // Expected
+        }
+        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+
+        // Management is re-enabled, adding account should succeed.
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        assertEquals(0, mDevicePolicyManager.getAccountTypesWithManagementDisabled().length);
+        Bundle result = mAccountManager.addAccount(ACCOUNT_TYPE_1,
+                null, null, null, null, null, null).getResult();
+
+        // Normally the expected result of addAccount() is AccountManager returning
+        // an intent to start the authenticator activity for adding new accounts.
+        // But MockAccountAuthenticator returns a new account straightway.
+        assertEquals(ACCOUNT_TYPE_1, result.getString(AccountManager.KEY_ACCOUNT_TYPE));
+    }
+
+    public void testUserRestriction_removeAccount() throws AuthenticatorException,
+            IOException, OperationCanceledException {
+        // Test for restriction on removeAccount()
+        mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+
+        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+        // First prepare some accounts by manually adding them,
+        // setAccountManagementDisabled(true) should not stop addAccountExplicitly().
+        assertTrue(mAccountManager.addAccountExplicitly(ACCOUNT_0, "password", null));
+        assertEquals(1, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+
+        // Removing account should fail, as we just disabled it.
+        try {
+            mAccountManager.removeAccount(ACCOUNT_0, null, null).getResult();
+            fail("Expected OperationCanceledException is not thrown.");
+        } catch (OperationCanceledException e) {
+            // Expected
+        }
+        assertEquals(1, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+
+        // Re-enable management, so we can successfully remove account this time.
+        mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        assertTrue(mAccountManager.removeAccount(ACCOUNT_0, null, null).getResult());
+
+        // Make sure the removal actually succeeds.
+        assertEquals(0, mAccountManager.getAccountsByType(ACCOUNT_TYPE_1).length);
+    }
+
     private void clearAllAccountManagementDisabled() {
         for (String accountType : mDevicePolicyManager.getAccountTypesWithManagementDisabled()) {
             mDevicePolicyManager.setAccountManagementDisabled(ADMIN_RECEIVER_COMPONENT, accountType,