1 /* 2 * Copyright (C) 2016 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.content; 18 19 import static junit.framework.Assert.assertTrue; 20 21 import android.accounts.Account; 22 import android.accounts.AccountManager; 23 import android.app.Activity; 24 import android.content.ContentProviderClient; 25 import android.content.ContentResolver; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.SyncRequest; 29 import android.content.SyncResult; 30 import android.content.cts.FlakyTestRule; 31 import android.content.pm.PackageManager; 32 import android.net.ConnectivityManager; 33 import android.net.NetworkInfo; 34 import android.os.Bundle; 35 import android.os.Process; 36 import android.os.SystemClock; 37 import android.support.test.InstrumentationRegistry; 38 import android.support.test.runner.AndroidJUnit4; 39 import org.junit.After; 40 import org.junit.Before; 41 import org.junit.Rule; 42 import org.junit.Test; 43 import org.junit.rules.TestRule; 44 import org.junit.runner.RunWith; 45 46 import java.io.IOException; 47 import java.util.concurrent.CountDownLatch; 48 import java.util.concurrent.TimeUnit; 49 50 import com.android.compatibility.common.util.SystemUtil; 51 52 /** 53 * Tests whether a sync adapter can access accounts. 54 */ 55 @RunWith(AndroidJUnit4.class) 56 public class CtsSyncAccountAccessSameCertTestCases { 57 private static final long SYNC_TIMEOUT_MILLIS = 20000; // 20 sec 58 59 @Rule 60 public final TestRule mFlakyTestTRule = new FlakyTestRule(3); 61 62 @Before setUp()63 public void setUp() throws Exception { 64 allowSyncAdapterRunInBackgroundAndDataInBackground(); 65 } 66 67 @After tearDown()68 public void tearDown() throws Exception { 69 disallowSyncAdapterRunInBackgroundAndDataInBackground(); 70 } 71 72 @Test testAccountAccess_sameCertAsAuthenticatorCanSeeAccount()73 public void testAccountAccess_sameCertAsAuthenticatorCanSeeAccount() throws Exception { 74 if (!hasDataConnection() || !hasNotificationSupport()) { 75 return; 76 } 77 78 Intent intent = new Intent(getContext(), StubActivity.class); 79 Activity activity = InstrumentationRegistry.getInstrumentation().startActivitySync(intent); 80 81 AccountManager accountManager = getContext().getSystemService(AccountManager.class); 82 Bundle result = accountManager.addAccount("com.stub", null, null, null, activity, 83 null, null).getResult(); 84 85 Account addedAccount = new Account( 86 result.getString(AccountManager.KEY_ACCOUNT_NAME), 87 result.getString(AccountManager.KEY_ACCOUNT_TYPE)); 88 89 waitForSyncManagerAccountChangeUpdate(); 90 91 try { 92 CountDownLatch latch = new CountDownLatch(1); 93 94 SyncAdapter.setOnPerformSyncDelegate((Account account, Bundle extras, 95 String authority, ContentProviderClient provider, SyncResult syncResult) 96 -> latch.countDown()); 97 98 Bundle extras = new Bundle(); 99 extras.putBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, true); 100 extras.putBoolean(ContentResolver.SYNC_EXTRAS_PRIORITY, true); 101 extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true); 102 SyncRequest request = new SyncRequest.Builder() 103 .setSyncAdapter(null, "com.android.cts.stub.provider") 104 .syncOnce() 105 .setExtras(extras) 106 .setExpedited(true) 107 .setManual(true) 108 .build(); 109 ContentResolver.requestSync(request); 110 111 assertTrue(latch.await(SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)); 112 } finally { 113 accountManager.removeAccount(addedAccount, activity, null, null); 114 } 115 } 116 getContext()117 private Context getContext() { 118 return InstrumentationRegistry.getInstrumentation().getContext(); 119 } 120 waitForSyncManagerAccountChangeUpdate()121 private void waitForSyncManagerAccountChangeUpdate() { 122 // Wait for the sync manager to be notified for the new account. 123 // Unfortunately, there is no way to detect this event, sigh... 124 SystemClock.sleep(SYNC_TIMEOUT_MILLIS); 125 } 126 hasDataConnection()127 private boolean hasDataConnection() { 128 ConnectivityManager connectivityManager = getContext().getSystemService( 129 ConnectivityManager.class); 130 NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); 131 return activeNetwork != null && activeNetwork.isConnectedOrConnecting(); 132 } 133 hasNotificationSupport()134 private boolean hasNotificationSupport() { 135 return !getContext().getPackageManager() 136 .hasSystemFeature(PackageManager.FEATURE_LEANBACK); 137 } 138 allowSyncAdapterRunInBackgroundAndDataInBackground()139 private void allowSyncAdapterRunInBackgroundAndDataInBackground() throws IOException { 140 // Allow us to run in the background 141 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 142 "cmd deviceidle whitelist +" + getContext().getPackageName()); 143 // Allow us to use data in the background 144 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 145 "cmd netpolicy add restrict-background-whitelist " + Process.myUid()); 146 } 147 disallowSyncAdapterRunInBackgroundAndDataInBackground()148 private void disallowSyncAdapterRunInBackgroundAndDataInBackground() throws IOException { 149 // Allow us to run in the background 150 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 151 "cmd deviceidle whitelist -" + getContext().getPackageName()); 152 // Allow us to use data in the background 153 SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), 154 "cmd netpolicy remove restrict-background-whitelist " + Process.myUid()); 155 } 156 } 157