blob: 3d58f1de301fe355b0999c7cc3f0b52cc671c21c [file] [log] [blame]
/*
* Copyright (C) 2010 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 android.content.cts;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncAdapterType;
import android.os.Bundle;
import android.test.AndroidTestCase;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class ContentResolverSyncTestCase extends AndroidTestCase {
public static final String ACCOUNT_NAME = "android.content.cts.account.name";
public static final String ACCOUNT_TYPE = "android.content.cts.account.type";
public static final String ACCOUNT_PASSWORD = "android.content.cts.account.password";
public static final String AUTH_TOKEN = "mockAuthToken";
public static final String AUTH_TOKEN_LABEL = "mockAuthTokenLabel";
private static final String AUTHORITY = "android.content.cts.authority";
private static final Account ACCOUNT = new Account(ACCOUNT_NAME, ACCOUNT_TYPE);
private static final int LATCH_TIMEOUT_MS = 5000;
private static MockSyncAdapter sSyncAdapter;
private static AccountManager sAccountManager;
private static MockAccountAuthenticator sMockAuthenticator;
@Override
public void setUp() throws Exception {
super.setUp();
getMockSyncAdapter();
sAccountManager = AccountManager.get(getContext());
}
@Override
public void tearDown() throws Exception {
sSyncAdapter.clearData();
// Need to clean up created account
removeAccount(sAccountManager, ACCOUNT, null /* callback */);
super.tearDown();
}
public static synchronized MockSyncAdapter getMockSyncAdapter() {
if (null == sSyncAdapter) {
sSyncAdapter = new MockSyncAdapter();
}
return sSyncAdapter;
}
public static synchronized MockAccountAuthenticator getMockAuthenticator(Context context) {
if (null == sMockAuthenticator) {
sMockAuthenticator = new MockAccountAuthenticator(context);
}
return sMockAuthenticator;
}
private void addAccountExplicitly(Account account, String password, Bundle userdata) {
assertTrue(sAccountManager.addAccountExplicitly(account, password, userdata));
}
private boolean removeAccount(AccountManager am, Account account,
AccountManagerCallback<Boolean> callback) throws IOException, AuthenticatorException,
OperationCanceledException {
AccountManagerFuture<Boolean> futureBoolean = am.removeAccount(account,
callback,
null /* handler */);
Boolean resultBoolean = futureBoolean.getResult();
assertTrue(futureBoolean.isDone());
return resultBoolean;
}
private CountDownLatch setNewLatch(CountDownLatch latch) {
sSyncAdapter.setLatch(latch);
sSyncAdapter.clearData();
return latch;
}
private void addAccountAndVerifyInitSync(Account account, String password,
String authority, int latchTimeoutMs) {
CountDownLatch latch = setNewLatch(new CountDownLatch(1));
addAccountExplicitly(account, password, null /* userData */);
// Wait with timeout for the callback to do its work
try {
latch.await(latchTimeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail("should not throw an InterruptedException");
}
assertFalse(sSyncAdapter.isStartSync());
assertFalse(sSyncAdapter.isCancelSync());
assertTrue(sSyncAdapter.isInitialized());
assertEquals(account, sSyncAdapter.getAccount());
assertEquals(authority, sSyncAdapter.getAuthority());
assertEquals(true, sSyncAdapter.getExtras().get(ContentResolver.SYNC_EXTRAS_INITIALIZE));
}
private void cancelSync(Account account, String authority, int latchTimeoutMillis) {
CountDownLatch latch = setNewLatch(new CountDownLatch(1));
Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.cancelSync(account, authority);
// Wait with timeout for the callback to do its work
try {
latch.await(latchTimeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail("should not throw an InterruptedException");
}
}
private void requestSync(Account account, String authority, int latchTimeoutMillis) {
CountDownLatch latch = setNewLatch(new CountDownLatch(1));
Bundle extras = new Bundle();
extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
ContentResolver.requestSync(account, authority, extras);
// Wait with timeout for the callback to do its work
try {
latch.await(latchTimeoutMillis, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
fail("should not throw an InterruptedException");
}
}
private void setIsSyncable(Account account, String authority, boolean b) {
ContentResolver.setIsSyncable(account, authority, (b) ? 1 : 0);
}
/**
* Test a sync request
*/
public void testRequestSync() throws IOException, AuthenticatorException,
OperationCanceledException {
// Prevent auto sync
ContentResolver.setMasterSyncAutomatically(false);
assertEquals(false, ContentResolver.getMasterSyncAutomatically());
addAccountAndVerifyInitSync(ACCOUNT, ACCOUNT_PASSWORD, AUTHORITY, LATCH_TIMEOUT_MS);
sSyncAdapter.clearData();
setIsSyncable(ACCOUNT, AUTHORITY, true);
cancelSync(ACCOUNT, AUTHORITY, LATCH_TIMEOUT_MS);
sSyncAdapter.clearData();
requestSync(ACCOUNT, AUTHORITY, LATCH_TIMEOUT_MS);
assertTrue(sSyncAdapter.isStartSync());
assertFalse(sSyncAdapter.isCancelSync());
assertFalse(sSyncAdapter.isInitialized());
assertEquals(ACCOUNT, sSyncAdapter.getAccount());
assertEquals(AUTHORITY, sSyncAdapter.getAuthority());
}
/**
* Test a sync cancel
*/
public void testCancelSync() throws IOException, AuthenticatorException,
OperationCanceledException {
// Prevent auto sync
ContentResolver.setMasterSyncAutomatically(false);
assertEquals(false, ContentResolver.getMasterSyncAutomatically());
addAccountAndVerifyInitSync(ACCOUNT, ACCOUNT_PASSWORD, AUTHORITY, LATCH_TIMEOUT_MS);
sSyncAdapter.clearData();
cancelSync(ACCOUNT, AUTHORITY, LATCH_TIMEOUT_MS);
assertFalse(sSyncAdapter.isStartSync());
assertTrue(sSyncAdapter.isCancelSync());
assertFalse(sSyncAdapter.isInitialized());
assertFalse(ContentResolver.isSyncActive(ACCOUNT, AUTHORITY));
assertFalse(ContentResolver.isSyncPending(ACCOUNT, AUTHORITY));
}
/**
* Test if we can set and get the MasterSyncAutomatically switch
*/
public void testGetAndSetMasterSyncAutomatically() {
ContentResolver.setMasterSyncAutomatically(true);
assertEquals(true, ContentResolver.getMasterSyncAutomatically());
ContentResolver.setMasterSyncAutomatically(false);
assertEquals(false, ContentResolver.getMasterSyncAutomatically());
}
/**
* Test if we can set and get the SyncAutomatically switch for an account
*/
public void testGetAndSetSyncAutomatically() {
// Prevent auto sync
ContentResolver.setMasterSyncAutomatically(false);
assertEquals(false, ContentResolver.getMasterSyncAutomatically());
ContentResolver.setSyncAutomatically(ACCOUNT, AUTHORITY, false);
assertEquals(false, ContentResolver.getSyncAutomatically(ACCOUNT, AUTHORITY));
ContentResolver.setSyncAutomatically(ACCOUNT, AUTHORITY, true);
assertEquals(true, ContentResolver.getSyncAutomatically(ACCOUNT, AUTHORITY));
}
/**
* Test if we can set and get the IsSyncable switch for an account
*/
public void testGetAndSetIsSyncable() {
// Prevent auto sync
ContentResolver.setMasterSyncAutomatically(false);
assertEquals(false, ContentResolver.getMasterSyncAutomatically());
addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
ContentResolver.setIsSyncable(ACCOUNT, AUTHORITY, 2);
assertTrue(ContentResolver.getIsSyncable(ACCOUNT, AUTHORITY) > 0);
ContentResolver.setIsSyncable(ACCOUNT, AUTHORITY, 1);
assertTrue(ContentResolver.getIsSyncable(ACCOUNT, AUTHORITY) > 0);
ContentResolver.setIsSyncable(ACCOUNT, AUTHORITY, 0);
assertEquals(0, ContentResolver.getIsSyncable(ACCOUNT, AUTHORITY));
ContentResolver.setIsSyncable(ACCOUNT, AUTHORITY, -1);
assertTrue(ContentResolver.getIsSyncable(ACCOUNT, AUTHORITY) < 0);
ContentResolver.setIsSyncable(ACCOUNT, AUTHORITY, -2);
assertTrue(ContentResolver.getIsSyncable(ACCOUNT, AUTHORITY) < 0);
}
/**
* Test if we can get the sync adapter types
*/
public void testGetSyncAdapterTypes() {
SyncAdapterType[] types = ContentResolver.getSyncAdapterTypes();
assertNotNull(types);
int length = types.length;
assertTrue(length > 0);
boolean found = false;
for (int n=0; n < length; n++) {
SyncAdapterType type = types[n];
if (ACCOUNT_TYPE.equals(type.accountType) && AUTHORITY.equals(type.authority)) {
found = true;
break;
}
}
assertTrue(found);
}
/**
* Test if a badly formed sync request is throwing exceptions
*/
public void testStartSyncFailure() {
try {
ContentResolver.requestSync(null, null, null);
fail("did not throw IllegalArgumentException when extras is null.");
} catch (IllegalArgumentException e) {
//expected.
}
}
/**
* Test validate sync extra bundle
*/
public void testValidateSyncExtrasBundle() {
Bundle extras = new Bundle();
extras.putInt("Integer", 20);
extras.putLong("Long", 10l);
extras.putBoolean("Boolean", true);
extras.putFloat("Float", 5.5f);
extras.putDouble("Double", 2.5);
extras.putString("String", ACCOUNT_NAME);
extras.putCharSequence("CharSequence", null);
ContentResolver.validateSyncExtrasBundle(extras);
extras.putChar("Char", 'a'); // type Char is invalid
try {
ContentResolver.validateSyncExtrasBundle(extras);
fail("did not throw IllegalArgumentException when extras is invalide.");
} catch (IllegalArgumentException e) {
//expected.
}
}
}