| /* |
| * Copyright (C) 2007 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 com.android.calendar; |
| |
| import com.android.calendar.AsyncQueryService.Operation; |
| import com.android.calendar.AsyncQueryServiceHelper.OperationInfo; |
| |
| import android.content.ComponentName; |
| import android.content.ContentProvider; |
| import android.content.ContentProviderOperation; |
| import android.content.ContentProviderResult; |
| import android.content.ContentResolver; |
| import android.content.ContentValues; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.res.Resources; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.os.Handler; |
| import android.os.HandlerThread; |
| import android.os.Message; |
| import android.test.IsolatedContext; |
| import android.test.RenamingDelegatingContext; |
| import android.test.ServiceTestCase; |
| import android.test.mock.MockContentResolver; |
| import android.test.mock.MockContext; |
| import android.test.mock.MockCursor; |
| import android.test.suitebuilder.annotation.LargeTest; |
| import android.test.suitebuilder.annotation.SmallTest; |
| import android.test.suitebuilder.annotation.Smoke; |
| import android.util.Log; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.concurrent.Semaphore; |
| import java.util.concurrent.TimeUnit; |
| |
| /** |
| * Unit tests for {@link android.text.format.DateUtils#formatDateRange}. |
| */ |
| public class AsyncQueryServiceTest extends ServiceTestCase<AsyncQueryServiceHelper> { |
| private static final String TAG = "AsyncQueryServiceTest"; |
| |
| private static final String AUTHORITY_URI = "content://AsyncQueryAuthority/"; |
| |
| private static final String AUTHORITY = "AsyncQueryAuthority"; |
| |
| private static final int MIN_DELAY = 50; |
| |
| private static final int BASE_TEST_WAIT_TIME = MIN_DELAY * 5; |
| |
| private static int mId = 0; |
| |
| private static final String[] TEST_PROJECTION = new String[] { |
| "col1", "col2", "col3" |
| }; |
| |
| private static final String TEST_SELECTION = "selection"; |
| |
| private static final String[] TEST_SELECTION_ARGS = new String[] { |
| "arg1", "arg2", "arg3" |
| }; |
| |
| public AsyncQueryServiceTest() { |
| super(AsyncQueryServiceHelper.class); |
| } |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| } |
| |
| private class MockContext2 extends MockContext { |
| @Override |
| public Resources getResources() { |
| return getContext().getResources(); |
| } |
| |
| @Override |
| public File getDir(String name, int mode) { |
| return getContext().getDir("mockcontext2_+" + name, mode); |
| } |
| |
| @Override |
| public Context getApplicationContext() { |
| return this; |
| } |
| } |
| |
| @Smoke |
| @SmallTest |
| public void testQuery() throws Exception { |
| int index = 0; |
| final OperationInfo[] work = new OperationInfo[1]; |
| work[index] = new OperationInfo(); |
| work[index].op = Operation.EVENT_ARG_QUERY; |
| |
| work[index].token = ++mId; |
| work[index].cookie = ++mId; |
| work[index].uri = Uri.parse(AUTHORITY_URI + "blah"); |
| work[index].projection = TEST_PROJECTION; |
| work[index].selection = TEST_SELECTION; |
| work[index].selectionArgs = TEST_SELECTION_ARGS; |
| work[index].orderBy = "order"; |
| |
| work[index].delayMillis = 0; |
| work[index].result = new TestCursor(); |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work); |
| aqs.startQuery(work[index].token, work[index].cookie, work[index].uri, |
| work[index].projection, work[index].selection, work[index].selectionArgs, |
| work[index].orderBy); |
| |
| Log.d(TAG, "testQuery Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", work.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testQuery Done <<<<<<<<<<<<<<"); |
| } |
| |
| @SmallTest |
| public void testInsert() throws Exception { |
| int index = 0; |
| final OperationInfo[] work = new OperationInfo[1]; |
| work[index] = new OperationInfo(); |
| work[index].op = Operation.EVENT_ARG_INSERT; |
| |
| work[index].token = ++mId; |
| work[index].cookie = ++mId; |
| work[index].uri = Uri.parse(AUTHORITY_URI + "blah"); |
| work[index].values = new ContentValues(); |
| work[index].values.put("key", ++mId); |
| |
| work[index].delayMillis = 0; |
| work[index].result = Uri.parse(AUTHORITY_URI + "Result=" + ++mId); |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work); |
| aqs.startInsert(work[index].token, work[index].cookie, work[index].uri, work[index].values, |
| work[index].delayMillis); |
| |
| Log.d(TAG, "testInsert Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", work.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testInsert Done <<<<<<<<<<<<<<"); |
| } |
| |
| @SmallTest |
| public void testUpdate() throws Exception { |
| int index = 0; |
| final OperationInfo[] work = new OperationInfo[1]; |
| work[index] = new OperationInfo(); |
| work[index].op = Operation.EVENT_ARG_UPDATE; |
| |
| work[index].token = ++mId; |
| work[index].cookie = ++mId; |
| work[index].uri = Uri.parse(AUTHORITY_URI + ++mId); |
| work[index].values = new ContentValues(); |
| work[index].values.put("key", ++mId); |
| work[index].selection = TEST_SELECTION; |
| work[index].selectionArgs = TEST_SELECTION_ARGS; |
| |
| work[index].delayMillis = 0; |
| work[index].result = ++mId; |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work); |
| aqs.startUpdate(work[index].token, work[index].cookie, work[index].uri, work[index].values, |
| work[index].selection, work[index].selectionArgs, work[index].delayMillis); |
| |
| Log.d(TAG, "testUpdate Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", work.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testUpdate Done <<<<<<<<<<<<<<"); |
| } |
| |
| @SmallTest |
| public void testDelete() throws Exception { |
| int index = 0; |
| final OperationInfo[] work = new OperationInfo[1]; |
| work[index] = new OperationInfo(); |
| work[index].op = Operation.EVENT_ARG_DELETE; |
| |
| work[index].token = ++mId; |
| work[index].cookie = ++mId; |
| work[index].uri = Uri.parse(AUTHORITY_URI + "blah"); |
| work[index].selection = TEST_SELECTION; |
| work[index].selectionArgs = TEST_SELECTION_ARGS; |
| |
| work[index].delayMillis = 0; |
| work[index].result = ++mId; |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work); |
| aqs.startDelete(work[index].token, |
| work[index].cookie, |
| work[index].uri, |
| work[index].selection, |
| work[index].selectionArgs, |
| work[index].delayMillis); |
| |
| Log.d(TAG, "testDelete Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", work.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testDelete Done <<<<<<<<<<<<<<"); |
| } |
| |
| @SmallTest |
| public void testBatch() throws Exception { |
| int index = 0; |
| final OperationInfo[] work = new OperationInfo[1]; |
| work[index] = new OperationInfo(); |
| work[index].op = Operation.EVENT_ARG_BATCH; |
| |
| work[index].token = ++mId; |
| work[index].cookie = ++mId; |
| work[index].authority = AUTHORITY; |
| work[index].cpo = new ArrayList<ContentProviderOperation>(); |
| work[index].cpo.add(ContentProviderOperation.newInsert(Uri.parse(AUTHORITY_URI + ++mId)) |
| .build()); |
| |
| work[index].delayMillis = 0; |
| ContentProviderResult[] resultArray = new ContentProviderResult[1]; |
| resultArray[0] = new ContentProviderResult(++mId); |
| work[index].result = resultArray; |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work); |
| aqs.startBatch(work[index].token, |
| work[index].cookie, |
| work[index].authority, |
| work[index].cpo, |
| work[index].delayMillis); |
| |
| Log.d(TAG, "testBatch Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", work.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testBatch Done <<<<<<<<<<<<<<"); |
| } |
| |
| @LargeTest |
| public void testDelay() throws Exception { |
| // Tests the ordering of the workqueue |
| int index = 0; |
| OperationInfo[] work = new OperationInfo[5]; |
| work[index++] = generateWork(MIN_DELAY * 2); |
| work[index++] = generateWork(0); |
| work[index++] = generateWork(MIN_DELAY * 1); |
| work[index++] = generateWork(0); |
| work[index++] = generateWork(MIN_DELAY * 3); |
| |
| OperationInfo[] sorted = generateSortedWork(work, work.length); |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(sorted), sorted); |
| startWork(aqs, work); |
| |
| Log.d(TAG, "testDelay Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", work.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testDelay Done <<<<<<<<<<<<<<"); |
| } |
| |
| @LargeTest |
| public void testCancel_simpleCancelLastTest() throws Exception { |
| int index = 0; |
| OperationInfo[] work = new OperationInfo[5]; |
| work[index++] = generateWork(MIN_DELAY * 2); |
| work[index++] = generateWork(0); |
| work[index++] = generateWork(MIN_DELAY); |
| work[index++] = generateWork(0); |
| work[index] = generateWork(MIN_DELAY * 3); |
| |
| // Not part of the expected as it will be canceled |
| OperationInfo toBeCancelled1 = work[index]; |
| OperationInfo[] expected = generateSortedWork(work, work.length - 1); |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected); |
| startWork(aqs, work); |
| Operation lastOne = aqs.getLastCancelableOperation(); |
| // Log.d(TAG, "lastOne = " + lastOne.toString()); |
| // Log.d(TAG, "toBeCancelled1 = " + toBeCancelled1.toString()); |
| assertTrue("1) delay=3 is not last", toBeCancelled1.equivalent(lastOne)); |
| assertEquals("Can't cancel delay 3", 1, aqs.cancelOperation(lastOne.token)); |
| |
| Log.d(TAG, "testCancel_simpleCancelLastTest Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", expected.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testCancel_simpleCancelLastTest Done <<<<<<<<<<<<<<"); |
| } |
| |
| @LargeTest |
| public void testCancel_cancelSecondToLast() throws Exception { |
| int index = 0; |
| OperationInfo[] work = new OperationInfo[5]; |
| work[index++] = generateWork(MIN_DELAY * 2); |
| work[index++] = generateWork(0); |
| work[index++] = generateWork(MIN_DELAY); |
| work[index++] = generateWork(0); |
| work[index] = generateWork(MIN_DELAY * 3); |
| |
| // Not part of the expected as it will be canceled |
| OperationInfo toBeCancelled1 = work[index]; |
| OperationInfo[] expected = new OperationInfo[4]; |
| expected[0] = work[1]; // delay = 0 |
| expected[1] = work[3]; // delay = 0 |
| expected[2] = work[2]; // delay = MIN_DELAY |
| expected[3] = work[4]; // delay = MIN_DELAY * 3 |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected); |
| startWork(aqs, work); |
| |
| Operation lastOne = aqs.getLastCancelableOperation(); // delay = 3 |
| assertTrue("2) delay=3 is not last", toBeCancelled1.equivalent(lastOne)); |
| assertEquals("Can't cancel delay 2", 1, aqs.cancelOperation(work[0].token)); |
| assertEquals("Delay 2 should be gone", 0, aqs.cancelOperation(work[0].token)); |
| |
| Log.d(TAG, "testCancel_cancelSecondToLast Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", expected.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testCancel_cancelSecondToLast Done <<<<<<<<<<<<<<"); |
| } |
| |
| @LargeTest |
| public void testCancel_multipleCancels() throws Exception { |
| int index = 0; |
| OperationInfo[] work = new OperationInfo[5]; |
| work[index++] = generateWork(MIN_DELAY * 2); |
| work[index++] = generateWork(0); |
| work[index++] = generateWork(MIN_DELAY); |
| work[index++] = generateWork(0); |
| work[index] = generateWork(MIN_DELAY * 3); |
| |
| // Not part of the expected as it will be canceled |
| OperationInfo[] expected = new OperationInfo[3]; |
| expected[0] = work[1]; // delay = 0 |
| expected[1] = work[3]; // delay = 0 |
| expected[2] = work[2]; // delay = MIN_DELAY |
| |
| TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected); |
| startWork(aqs, work); |
| |
| Operation lastOne = aqs.getLastCancelableOperation(); // delay = 3 |
| assertTrue("3) delay=3 is not last", work[4].equivalent(lastOne)); |
| assertEquals("Can't cancel delay 2", 1, aqs.cancelOperation(work[0].token)); |
| assertEquals("Delay 2 should be gone", 0, aqs.cancelOperation(work[0].token)); |
| assertEquals("Can't cancel delay 3", 1, aqs.cancelOperation(work[4].token)); |
| assertEquals("Delay 3 should be gone", 0, aqs.cancelOperation(work[4].token)); |
| |
| Log.d(TAG, "testCancel_multipleCancels Waiting >>>>>>>>>>>"); |
| assertEquals("Not all operations were executed.", expected.length, aqs |
| .waitForCompletion(BASE_TEST_WAIT_TIME)); |
| Log.d(TAG, "testCancel_multipleCancels Done <<<<<<<<<<<<<<"); |
| } |
| |
| private OperationInfo generateWork(long delayMillis) { |
| OperationInfo work = new OperationInfo(); |
| work.op = Operation.EVENT_ARG_DELETE; |
| |
| work.token = ++mId; |
| work.cookie = 100 + work.token; |
| work.uri = Uri.parse(AUTHORITY_URI + "blah"); |
| work.selection = TEST_SELECTION; |
| work.selectionArgs = TEST_SELECTION_ARGS; |
| |
| work.delayMillis = delayMillis; |
| work.result = 1000 + work.token; |
| return work; |
| } |
| |
| private void startWork(TestAsyncQueryService aqs, OperationInfo[] work) { |
| for (OperationInfo w : work) { |
| if (w != null) { |
| aqs.startDelete(w.token, w.cookie, w.uri, w.selection, w.selectionArgs, |
| w.delayMillis); |
| } |
| } |
| } |
| |
| OperationInfo[] generateSortedWork(OperationInfo[] work, int length) { |
| OperationInfo[] sorted = new OperationInfo[length]; |
| System.arraycopy(work, 0, sorted, 0, length); |
| |
| // Set the scheduled time so they get sorted properly |
| for (OperationInfo w : sorted) { |
| if (w != null) { |
| w.calculateScheduledTime(); |
| } |
| } |
| |
| // Stable sort by scheduled time |
| Arrays.sort(sorted); |
| |
| Log.d(TAG, "Unsorted work: " + work.length); |
| for (OperationInfo w : work) { |
| if (w != null) { |
| Log.d(TAG, "Token#" + w.token + " delay=" + w.delayMillis); |
| } |
| } |
| Log.d(TAG, "Sorted work: " + sorted.length); |
| for (OperationInfo w : sorted) { |
| if (w != null) { |
| Log.d(TAG, "Token#" + w.token + " delay=" + w.delayMillis); |
| } |
| } |
| |
| return sorted; |
| } |
| |
| private Context buildTestContext(final OperationInfo[] work) { |
| MockContext context = new MockContext() { |
| MockContentResolver mResolver; |
| |
| @Override |
| public ContentResolver getContentResolver() { |
| if (mResolver == null) { |
| mResolver = new MockContentResolver(); |
| |
| final String filenamePrefix = "test."; |
| RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext( |
| new MockContext2(), getContext(), filenamePrefix); |
| IsolatedContext providerContext = |
| new IsolatedContext(mResolver, targetContextWrapper); |
| |
| ContentProvider provider = new TestProvider(work); |
| provider.attachInfo(providerContext, null); |
| |
| mResolver.addProvider(AUTHORITY, provider); |
| } |
| return mResolver; |
| } |
| |
| @Override |
| public String getPackageName() { |
| return AsyncQueryServiceTest.class.getPackage().getName(); |
| } |
| |
| @Override |
| public ComponentName startService(Intent service) { |
| AsyncQueryServiceTest.this.startService(service); |
| return service.getComponent(); |
| } |
| }; |
| |
| return context; |
| } |
| |
| private final class TestCursor extends MockCursor { |
| int mUnique = ++mId; |
| |
| @Override |
| public int getCount() { |
| return mUnique; |
| } |
| } |
| |
| /** |
| * TestAsyncQueryService takes the expected results in the constructor. They |
| * are used to verify the data passed to the callbacks. |
| */ |
| class TestAsyncQueryService extends AsyncQueryService { |
| int mIndex = 0; |
| |
| private OperationInfo[] mWork; |
| |
| private Semaphore mCountingSemaphore; |
| |
| public TestAsyncQueryService(Context context, OperationInfo[] work) { |
| super(context); |
| mCountingSemaphore = new Semaphore(0); |
| |
| // run in a separate thread but call the same code |
| HandlerThread thread = new HandlerThread("TestAsyncQueryService"); |
| thread.start(); |
| super.setTestHandler(new Handler(thread.getLooper()) { |
| @Override |
| public void handleMessage(Message msg) { |
| TestAsyncQueryService.this.handleMessage(msg); |
| } |
| }); |
| |
| mWork = work; |
| } |
| |
| @Override |
| protected void onQueryComplete(int token, Object cookie, Cursor cursor) { |
| Log.d(TAG, "onQueryComplete tid=" + Thread.currentThread().getId()); |
| Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex); |
| |
| assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_QUERY); |
| assertEquals(mWork[mIndex].token, token); |
| /* |
| * Even though our TestProvider returned mWork[mIndex].result, it is |
| * wrapped with new'ed CursorWrapperInner and there's no equal() in |
| * CursorWrapperInner. assertEquals the two cursor will always fail. |
| * So just compare the count which will be unique in our TestCursor; |
| */ |
| assertEquals(((Cursor) mWork[mIndex].result).getCount(), cursor.getCount()); |
| |
| mIndex++; |
| mCountingSemaphore.release(); |
| } |
| |
| @Override |
| protected void onInsertComplete(int token, Object cookie, Uri uri) { |
| Log.d(TAG, "onInsertComplete tid=" + Thread.currentThread().getId()); |
| Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex); |
| |
| assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_INSERT); |
| assertEquals(mWork[mIndex].token, token); |
| assertEquals(mWork[mIndex].result, uri); |
| |
| mIndex++; |
| mCountingSemaphore.release(); |
| } |
| |
| @Override |
| protected void onUpdateComplete(int token, Object cookie, int result) { |
| Log.d(TAG, "onUpdateComplete tid=" + Thread.currentThread().getId()); |
| Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex); |
| |
| assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_UPDATE); |
| assertEquals(mWork[mIndex].token, token); |
| assertEquals(mWork[mIndex].result, result); |
| |
| mIndex++; |
| mCountingSemaphore.release(); |
| } |
| |
| @Override |
| protected void onDeleteComplete(int token, Object cookie, int result) { |
| Log.d(TAG, "onDeleteComplete tid=" + Thread.currentThread().getId()); |
| Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex); |
| |
| assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_DELETE); |
| assertEquals(mWork[mIndex].token, token); |
| assertEquals(mWork[mIndex].result, result); |
| |
| mIndex++; |
| mCountingSemaphore.release(); |
| } |
| |
| @Override |
| protected void onBatchComplete(int token, Object cookie, ContentProviderResult[] results) { |
| Log.d(TAG, "onBatchComplete tid=" + Thread.currentThread().getId()); |
| Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex); |
| |
| assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_BATCH); |
| assertEquals(mWork[mIndex].token, token); |
| |
| ContentProviderResult[] expected = (ContentProviderResult[]) mWork[mIndex].result; |
| assertEquals(expected.length, results.length); |
| for (int i = 0; i < expected.length; ++i) { |
| assertEquals(expected[i].count, results[i].count); |
| assertEquals(expected[i].uri, results[i].uri); |
| } |
| |
| mIndex++; |
| mCountingSemaphore.release(); |
| } |
| |
| public int waitForCompletion(long timeoutMills) { |
| Log.d(TAG, "waitForCompletion tid=" + Thread.currentThread().getId()); |
| int count = 0; |
| try { |
| while (count < mWork.length) { |
| if (!mCountingSemaphore.tryAcquire(timeoutMills, TimeUnit.MILLISECONDS)) { |
| break; |
| } |
| count++; |
| } |
| } catch (InterruptedException e) { |
| } |
| return count; |
| } |
| } |
| |
| /** |
| * This gets called by AsyncQueryServiceHelper to read or write the data. It |
| * also verifies the data against the data passed in the constructor |
| */ |
| class TestProvider extends ContentProvider { |
| OperationInfo[] mWork; |
| |
| int index = 0; |
| |
| public TestProvider(OperationInfo[] work) { |
| mWork = work; |
| } |
| |
| @Override |
| public final Cursor query(Uri uri, String[] projection, String selection, |
| String[] selectionArgs, String orderBy) { |
| Log.d(TAG, "Provider query index=" + index); |
| assertEquals(mWork[index].op, Operation.EVENT_ARG_QUERY); |
| assertEquals(mWork[index].uri, uri); |
| assertEquals(mWork[index].projection, projection); |
| assertEquals(mWork[index].selection, selection); |
| assertEquals(mWork[index].selectionArgs, selectionArgs); |
| assertEquals(mWork[index].orderBy, orderBy); |
| return (Cursor) mWork[index++].result; |
| } |
| |
| @Override |
| public Uri insert(Uri uri, ContentValues values) { |
| Log.d(TAG, "Provider insert index=" + index); |
| assertEquals(mWork[index].op, Operation.EVENT_ARG_INSERT); |
| assertEquals(mWork[index].uri, uri); |
| assertEquals(mWork[index].values, values); |
| return (Uri) mWork[index++].result; |
| } |
| |
| @Override |
| public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { |
| Log.d(TAG, "Provider update index=" + index); |
| assertEquals(mWork[index].op, Operation.EVENT_ARG_UPDATE); |
| assertEquals(mWork[index].uri, uri); |
| assertEquals(mWork[index].values, values); |
| assertEquals(mWork[index].selection, selection); |
| assertEquals(mWork[index].selectionArgs, selectionArgs); |
| return (Integer) mWork[index++].result; |
| } |
| |
| @Override |
| public int delete(Uri uri, String selection, String[] selectionArgs) { |
| Log.d(TAG, "Provider delete index=" + index); |
| assertEquals(mWork[index].op, Operation.EVENT_ARG_DELETE); |
| assertEquals(mWork[index].uri, uri); |
| assertEquals(mWork[index].selection, selection); |
| assertEquals(mWork[index].selectionArgs, selectionArgs); |
| return (Integer) mWork[index++].result; |
| } |
| |
| @Override |
| public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) { |
| Log.d(TAG, "Provider applyBatch index=" + index); |
| assertEquals(mWork[index].op, Operation.EVENT_ARG_BATCH); |
| assertEquals(mWork[index].cpo, operations); |
| return (ContentProviderResult[]) mWork[index++].result; |
| } |
| |
| @Override |
| public String getType(Uri uri) { |
| return null; |
| } |
| |
| @Override |
| public boolean onCreate() { |
| return false; |
| } |
| } |
| } |