1 /* 2 * Copyright (C) 2022 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 android.appenumeration.cts; 18 19 import static android.appenumeration.cts.Constants.ACCOUNT_NAME; 20 import static android.appenumeration.cts.Constants.ACCOUNT_TYPE; 21 import static android.appenumeration.cts.Constants.ACTION_ACCOUNT_MANAGER_GET_AUTHENTICATOR_TYPES; 22 import static android.appenumeration.cts.Constants.QUERIES_NOTHING; 23 import static android.appenumeration.cts.Constants.QUERIES_PACKAGE; 24 import static android.appenumeration.cts.Constants.TARGET_STUB; 25 import static android.appenumeration.cts.Constants.TARGET_STUB_APK; 26 import static android.appenumeration.cts.Constants.TARGET_SYNCADAPTER; 27 import static android.appenumeration.cts.Constants.TARGET_WEB; 28 import static android.appenumeration.cts.Utils.ensurePackageIsInstalled; 29 import static android.content.Intent.EXTRA_RETURN_RESULT; 30 31 import static org.hamcrest.MatcherAssert.assertThat; 32 import static org.hamcrest.collection.IsMapContaining.hasEntry; 33 import static org.hamcrest.collection.IsMapWithSize.anEmptyMap; 34 import static org.hamcrest.core.Is.is; 35 import static org.junit.Assert.assertThrows; 36 37 import android.accounts.Account; 38 import android.accounts.AccountManager; 39 import android.accounts.AuthenticatorDescription; 40 import android.content.pm.PackageManager; 41 import android.os.Bundle; 42 43 import androidx.test.ext.junit.runners.AndroidJUnit4; 44 45 import org.junit.After; 46 import org.junit.Before; 47 import org.junit.BeforeClass; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 51 import java.util.Arrays; 52 import java.util.HashMap; 53 import java.util.Map; 54 55 @RunWith(AndroidJUnit4.class) 56 public class AccountManagerEnumerationTest extends AppEnumerationTestsBase { 57 private static final Account ACCOUNT = new Account(ACCOUNT_NAME, ACCOUNT_TYPE); 58 59 private static final String TARGET_VISIBLE = TARGET_STUB; 60 private static final String TARGET_NOT_VISIBLE = TARGET_WEB; 61 62 private AccountManager mAccountManager; 63 64 @BeforeClass prepareApps()65 public static void prepareApps() { 66 ensurePackageIsInstalled(TARGET_STUB, TARGET_STUB_APK); 67 } 68 69 @Before onBefore()70 public void onBefore() throws Exception { 71 mAccountManager = AccountManager.get(sContext); 72 73 assertThat(sPm.canPackageQuery(sContext.getPackageName(), TARGET_VISIBLE), 74 is(true)); 75 assertThrows(PackageManager.NameNotFoundException.class, 76 () -> sPm.canPackageQuery(sContext.getPackageName(), TARGET_NOT_VISIBLE)); 77 } 78 79 @After onAfter()80 public void onAfter() { 81 for (Account account : mAccountManager.getAccountsByType(ACCOUNT_TYPE)) { 82 mAccountManager.removeAccountExplicitly(account); 83 } 84 } 85 86 @Test addAccountExplicitlyWithVisibility_targetPackageIsVisible()87 public void addAccountExplicitlyWithVisibility_targetPackageIsVisible() { 88 final Map<String, Integer> visibility = new HashMap(); 89 visibility.put(TARGET_VISIBLE, AccountManager.VISIBILITY_VISIBLE); 90 assertThat(mAccountManager.addAccountExplicitly( 91 ACCOUNT, null /* password */, null /* userdata */, visibility), is(true)); 92 93 assertThat(mAccountManager.getAccountVisibility(ACCOUNT, TARGET_VISIBLE), 94 is(AccountManager.VISIBILITY_VISIBLE)); 95 assertThat(mAccountManager.getAccountsAndVisibilityForPackage(TARGET_VISIBLE, ACCOUNT_TYPE), 96 hasEntry(ACCOUNT, AccountManager.VISIBILITY_VISIBLE)); 97 } 98 99 @Test addAccountExplicitlyWithVisibility_targetPackageNotVisible()100 public void addAccountExplicitlyWithVisibility_targetPackageNotVisible() { 101 final Map<String, Integer> visibility = new HashMap(); 102 visibility.put(TARGET_NOT_VISIBLE, AccountManager.VISIBILITY_VISIBLE); 103 assertThat(mAccountManager.addAccountExplicitly( 104 ACCOUNT, null /* password */, null /* userdata */, visibility), is(true)); 105 106 assertThat(mAccountManager.getAccountVisibility(ACCOUNT, TARGET_NOT_VISIBLE), 107 is(AccountManager.VISIBILITY_NOT_VISIBLE)); 108 assertThat(mAccountManager.getAccountsAndVisibilityForPackage( 109 TARGET_NOT_VISIBLE, ACCOUNT_TYPE), anEmptyMap()); 110 } 111 112 @Test setAccountVisibility_targetPackageIsVisible()113 public void setAccountVisibility_targetPackageIsVisible() { 114 assertThat(mAccountManager.addAccountExplicitly( 115 ACCOUNT, null /* password */, null /* userdata */), is(true)); 116 assertThat(mAccountManager.setAccountVisibility( 117 ACCOUNT, TARGET_VISIBLE, AccountManager.VISIBILITY_VISIBLE), is(true)); 118 } 119 120 @Test setAccountVisibility_targetPackageNotVisible()121 public void setAccountVisibility_targetPackageNotVisible() { 122 assertThat(mAccountManager.addAccountExplicitly( 123 ACCOUNT, null /* password */, null /* userdata */), is(true)); 124 assertThat(mAccountManager.setAccountVisibility( 125 ACCOUNT, TARGET_NOT_VISIBLE, AccountManager.VISIBILITY_VISIBLE), is(false)); 126 } 127 128 @Test queriesPackage_getAuthenticatorTypes_canSeeSyncAdapterTarget()129 public void queriesPackage_getAuthenticatorTypes_canSeeSyncAdapterTarget() 130 throws Exception { 131 assertVisible(QUERIES_PACKAGE, TARGET_SYNCADAPTER, this::getAuthenticatorTypes); 132 } 133 134 @Test queriesNothing_getAuthenticatorTypes_cannotSeeSyncAdapterTarget()135 public void queriesNothing_getAuthenticatorTypes_cannotSeeSyncAdapterTarget() 136 throws Exception { 137 assertNotVisible(QUERIES_NOTHING, TARGET_SYNCADAPTER, this::getAuthenticatorTypes); 138 } 139 getAuthenticatorTypes(String sourcePackageName)140 private String[] getAuthenticatorTypes(String sourcePackageName) throws Exception { 141 final Bundle response = sendCommandBlocking(sourcePackageName, null /* targetPackageName */, 142 /* intentExtra */ null, ACTION_ACCOUNT_MANAGER_GET_AUTHENTICATOR_TYPES); 143 final AuthenticatorDescription[] types = 144 response.getParcelableArray(EXTRA_RETURN_RESULT, AuthenticatorDescription.class); 145 return Arrays.stream(types) 146 .map(type -> type.packageName) 147 .distinct() 148 .toArray(String[]::new); 149 } 150 } 151