Add CTS for SyncManager / ContentResolver
- fix imports
- took care of Ken feedbak
- fixed variables naming
- fixed comments and copyright year and trailing whitespace
- fixed some other redundant whitespaces
- took care of Fred feedback
- code formatting
- changed MockSyncAdapter so that it does not use SyncAdapter class anymore
- suppress non needed assert on extra Bundle when init in startSync
Change-Id: I49de8e101d86e5a3ed59eb3b34a5f6aa4bd580b0
diff --git a/tests/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index a32bb78..882f080 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
* Copyright (C) 2007 The Android Open Source Project
*
@@ -16,15 +15,41 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.cts.content">
+ package="android.content.cts">
+
+ <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.USE_CREDENTIALS" />
+ <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
+ <uses-permission android:name="android.permission.READ_SYNC_STATS" />
<application>
<uses-library android:name="android.test.runner" />
+
+ <service android:name="MockSyncAdapterService" android:exported="true">
+ <intent-filter>
+ <action android:name="android.content.SyncAdapter" />
+ </intent-filter>
+
+ <meta-data android:name="android.content.SyncAdapter"
+ android:resource="@xml/syncadapter" />
+ </service>
+
+ <service android:name="MockAccountService" android:exported="true"
+ android:process="android.content.cts">
+ <intent-filter>
+ <action android:name="android.accounts.AccountAuthenticator" />
+ </intent-filter>
+
+ <meta-data android:name="android.accounts.AccountAuthenticator"
+ android:resource="@xml/authenticator" />
+ </service>
</application>
- <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
- android:targetPackage="com.android.cts.stub"
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="android.content.cts"
android:label="CTS tests of android.content"/>
-
</manifest>
diff --git a/tests/tests/content/res/drawable/ic_cts_minitab_selected.png b/tests/tests/content/res/drawable/ic_cts_minitab_selected.png
new file mode 100644
index 0000000..c730050
--- /dev/null
+++ b/tests/tests/content/res/drawable/ic_cts_minitab_selected.png
Binary files differ
diff --git a/tests/tests/content/res/drawable/ic_cts_selected.png b/tests/tests/content/res/drawable/ic_cts_selected.png
new file mode 100644
index 0000000..72a065c
--- /dev/null
+++ b/tests/tests/content/res/drawable/ic_cts_selected.png
Binary files differ
diff --git a/tests/tests/content/res/values/strings.xml b/tests/tests/content/res/values/strings.xml
new file mode 100644
index 0000000..2369648
--- /dev/null
+++ b/tests/tests/content/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Label for this package -->
+ <string name="label">Android CTS - Content</string>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/content/res/xml/authenticator.xml b/tests/tests/content/res/xml/authenticator.xml
new file mode 100644
index 0000000..46da929
--- /dev/null
+++ b/tests/tests/content/res/xml/authenticator.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the Account Manager. -->
+
+<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:accountType="android.content.cts.account.type"
+ android:icon="@drawable/ic_cts_selected"
+ android:smallIcon="@drawable/ic_cts_minitab_selected"
+ android:label="@string/label"
+/>
\ No newline at end of file
diff --git a/tests/tests/content/res/xml/syncadapter.xml b/tests/tests/content/res/xml/syncadapter.xml
new file mode 100644
index 0000000..1c0bb72
--- /dev/null
+++ b/tests/tests/content/res/xml/syncadapter.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2009, 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.
+ */
+-->
+
+<!-- The attributes in this XML file provide configuration information -->
+<!-- for the SyncAdapter. -->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ android:contentAuthority="android.content.cts.authority"
+ android:accountType="android.content.cts.account.type"
+/>
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java b/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
new file mode 100644
index 0000000..df6d5c7
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
@@ -0,0 +1,323 @@
+/*
+ * 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());
+ }
+
+ 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.
+ }
+ }
+}
diff --git a/tests/tests/content/src/android/content/cts/MockAccountAuthenticator.java b/tests/tests/content/src/android/content/cts/MockAccountAuthenticator.java
new file mode 100644
index 0000000..f1c9c38
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/MockAccountAuthenticator.java
@@ -0,0 +1,88 @@
+/*
+ * 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.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.content.Context;
+import android.os.Bundle;
+
+public class MockAccountAuthenticator extends AbstractAccountAuthenticator {
+
+ public MockAccountAuthenticator(Context context) {
+ super(context);
+ }
+
+ private Bundle createResultBundle() {
+ Bundle result = new Bundle();
+ result.putString(AccountManager.KEY_ACCOUNT_NAME, ContentResolverSyncTestCase.ACCOUNT_NAME);
+ result.putString(AccountManager.KEY_ACCOUNT_TYPE, ContentResolverSyncTestCase.ACCOUNT_TYPE);
+ result.putString(AccountManager.KEY_AUTHTOKEN, ContentResolverSyncTestCase.AUTH_TOKEN);
+
+ return result;
+ }
+
+ @Override
+ public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+ String authTokenType, String[] requiredFeatures, Bundle options)
+ throws NetworkErrorException {
+ return createResultBundle();
+ }
+
+ @Override
+ public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+ return createResultBundle();
+ }
+
+ @Override
+ public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+ String authTokenType, Bundle options) throws NetworkErrorException {
+ return createResultBundle();
+ }
+
+ @Override
+ public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
+ Bundle options) throws NetworkErrorException {
+
+ Bundle result = new Bundle();
+ result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+ return result;
+ }
+
+ @Override
+ public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+ String authTokenType, Bundle options) throws NetworkErrorException {
+ return createResultBundle();
+ }
+
+ @Override
+ public String getAuthTokenLabel(String authTokenType) {
+ return ContentResolverSyncTestCase.AUTH_TOKEN_LABEL;
+ }
+
+ @Override
+ public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+ String[] features) throws NetworkErrorException {
+
+ Bundle result = new Bundle();
+ result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+ return result;
+ }
+}
diff --git a/tests/tests/content/src/android/content/cts/MockAccountService.java b/tests/tests/content/src/android/content/cts/MockAccountService.java
new file mode 100644
index 0000000..4e41954
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/MockAccountService.java
@@ -0,0 +1,32 @@
+/*
+ * 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.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * a basic Mock Service for wrapping the MockAccountAuthenticator
+ */
+public class MockAccountService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return ContentResolverSyncTestCase.getMockAuthenticator(this).getIBinder();
+ }
+}
diff --git a/tests/tests/content/src/android/content/cts/MockSyncAdapter.java b/tests/tests/content/src/android/content/cts/MockSyncAdapter.java
new file mode 100644
index 0000000..5be9548
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/MockSyncAdapter.java
@@ -0,0 +1,126 @@
+/*
+ * 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.content.ContentResolver;
+import android.content.ISyncAdapter;
+import android.content.ISyncContext;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.util.concurrent.CountDownLatch;
+
+public class MockSyncAdapter extends ISyncAdapter.Stub {
+
+ private Account mAccount;
+ private String mAuthority;
+ private Bundle mExtras;
+ private boolean mInitialized;
+ private boolean mStartSync;
+ private boolean mCancelSync;
+ private CountDownLatch mLatch;
+
+ public Account getAccount() {
+ return mAccount;
+ }
+
+ public String getAuthority() {
+ return mAuthority;
+ }
+
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
+ public boolean isInitialized() {
+ return mInitialized;
+ }
+
+ public boolean isStartSync() {
+ return mStartSync;
+ }
+
+ public boolean isCancelSync() {
+ return mCancelSync;
+ }
+
+ public void clearData() {
+ mAccount = null;
+ mAuthority = null;
+ mExtras = null;
+ mInitialized = false;
+ mStartSync = false;
+ mCancelSync = false;
+ mLatch = null;
+ }
+
+ public void setLatch(CountDownLatch mLatch) {
+ this.mLatch = mLatch;
+ }
+
+ public void startSync(ISyncContext syncContext, String authority, Account account,
+ Bundle extras) throws RemoteException {
+
+ mAccount = account;
+ mAuthority = authority;
+ mExtras = extras;
+
+ if (null != extras && extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE)) {
+ mInitialized = true;
+ mStartSync = false;
+ mCancelSync = false;
+ } else {
+ mInitialized = false;
+ mStartSync = true;
+ mCancelSync = false;
+ }
+
+ if (null != mLatch) {
+ mLatch.countDown();
+ }
+ }
+
+ public void cancelSync(ISyncContext syncContext) throws RemoteException {
+ mAccount = null;
+ mAuthority = null;
+ mExtras = null;
+
+ mInitialized = false;
+ mStartSync = false;
+ mCancelSync = true;
+
+ if (null != mLatch) {
+ mLatch.countDown();
+ }
+ }
+
+ public void initialize(android.accounts.Account account, java.lang.String authority)
+ throws android.os.RemoteException {
+
+ mAccount = account;
+ mAuthority = authority;
+
+ mInitialized = true;
+ mStartSync = false;
+ mCancelSync = false;
+
+ if (null != mLatch) {
+ mLatch.countDown();
+ }
+ }
+}
diff --git a/tests/tests/content/src/android/content/cts/MockSyncAdapterService.java b/tests/tests/content/src/android/content/cts/MockSyncAdapterService.java
new file mode 100644
index 0000000..6fd05af
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/MockSyncAdapterService.java
@@ -0,0 +1,28 @@
+/*
+ * 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.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class MockSyncAdapterService extends Service {
+ @Override
+ public IBinder onBind(Intent intent) {
+ return ContentResolverSyncTestCase.getMockSyncAdapter();
+ }
+}