1bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan/*
2bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Copyright (C) 2007 The Android Open Source Project
3bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan *
4bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Licensed under the Apache License, Version 2.0 (the "License");
5bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * you may not use this file except in compliance with the License.
6bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * You may obtain a copy of the License at
7bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan *
8bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan *      http://www.apache.org/licenses/LICENSE-2.0
9bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan *
10bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Unless required by applicable law or agreed to in writing, software
11bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * distributed under the License is distributed on an "AS IS" BASIS,
12bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * See the License for the specific language governing permissions and
14bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * limitations under the License.
15bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */
16bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
17bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanpackage com.android.calendar;
18bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
19bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport com.android.calendar.AsyncQueryService.Operation;
20bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport com.android.calendar.AsyncQueryServiceHelper.OperationInfo;
21bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
22bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ComponentName;
23bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentProvider;
24bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentProviderOperation;
25bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentProviderResult;
26bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentResolver;
27bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentValues;
28bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.Context;
29bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.Intent;
30b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzsteinimport android.content.res.Resources;
31bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.database.Cursor;
32bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.net.Uri;
33bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.Handler;
34bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.HandlerThread;
35bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.Message;
36b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzsteinimport android.test.IsolatedContext;
37b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzsteinimport android.test.RenamingDelegatingContext;
38bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.test.ServiceTestCase;
39bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.test.mock.MockContentResolver;
40bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.test.mock.MockContext;
41bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.test.mock.MockCursor;
42bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.test.suitebuilder.annotation.LargeTest;
43bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.test.suitebuilder.annotation.SmallTest;
447e4b2c1ddb6680d5b413c5f25592b0128e5f14dcMichael Chanimport android.test.suitebuilder.annotation.Smoke;
45bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.util.Log;
46bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
47b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzsteinimport java.io.File;
48bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.ArrayList;
49bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.Arrays;
50bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.concurrent.Semaphore;
51bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.concurrent.TimeUnit;
52bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
53bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan/**
54bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Unit tests for {@link android.text.format.DateUtils#formatDateRange}.
55bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */
56bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanpublic class AsyncQueryServiceTest extends ServiceTestCase<AsyncQueryServiceHelper> {
57bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final String TAG = "AsyncQueryServiceTest";
58bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
59bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final String AUTHORITY_URI = "content://AsyncQueryAuthority/";
60bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
61bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final String AUTHORITY = "AsyncQueryAuthority";
62bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
63bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final int MIN_DELAY = 50;
64bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
65bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final int BASE_TEST_WAIT_TIME = MIN_DELAY * 5;
66bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
67bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static int mId = 0;
68bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
69bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final String[] TEST_PROJECTION = new String[] {
70bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            "col1", "col2", "col3"
71bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    };
72bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
73bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final String TEST_SELECTION = "selection";
74bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
75bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private static final String[] TEST_SELECTION_ARGS = new String[] {
76bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            "arg1", "arg2", "arg3"
77bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    };
78bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
79bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public AsyncQueryServiceTest() {
80bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        super(AsyncQueryServiceHelper.class);
81bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
82bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
83bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @Override
84bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    protected void setUp() throws Exception {
85bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        super.setUp();
86bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
87bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
88b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein    private class MockContext2 extends MockContext {
89b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        @Override
90b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        public Resources getResources() {
91b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein            return getContext().getResources();
92b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        }
93b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein
94b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        @Override
95b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        public File getDir(String name, int mode) {
96b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein            return getContext().getDir("mockcontext2_+" + name, mode);
97b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        }
98b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein
99b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        @Override
100b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        public Context getApplicationContext() {
101b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein            return this;
102b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein        }
103b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein    }
104b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein
1057e4b2c1ddb6680d5b413c5f25592b0128e5f14dcMichael Chan    @Smoke
106bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @SmallTest
107bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testQuery() throws Exception {
108bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
109bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        final OperationInfo[] work = new OperationInfo[1];
110bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = new OperationInfo();
111bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].op = Operation.EVENT_ARG_QUERY;
112bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
113bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].token = ++mId;
114bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cookie = ++mId;
115bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].uri = Uri.parse(AUTHORITY_URI + "blah");
116bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].projection = TEST_PROJECTION;
117bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].selection = TEST_SELECTION;
118bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].selectionArgs = TEST_SELECTION_ARGS;
119bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].orderBy = "order";
120bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
121bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].delayMillis = 0;
122bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].result = new TestCursor();
123bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
124bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
125bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        aqs.startQuery(work[index].token, work[index].cookie, work[index].uri,
126bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].projection, work[index].selection, work[index].selectionArgs,
127bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].orderBy);
128bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
129bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testQuery Waiting >>>>>>>>>>>");
130bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", work.length, aqs
131bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
132bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testQuery Done <<<<<<<<<<<<<<");
133bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
134bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
135bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @SmallTest
136bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testInsert() throws Exception {
137bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
138bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        final OperationInfo[] work = new OperationInfo[1];
139bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = new OperationInfo();
140bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].op = Operation.EVENT_ARG_INSERT;
141bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
142bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].token = ++mId;
143bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cookie = ++mId;
144bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].uri = Uri.parse(AUTHORITY_URI + "blah");
145bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].values = new ContentValues();
146bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].values.put("key", ++mId);
147bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
148bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].delayMillis = 0;
149bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].result = Uri.parse(AUTHORITY_URI + "Result=" + ++mId);
150bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
151bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
152bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        aqs.startInsert(work[index].token, work[index].cookie, work[index].uri, work[index].values,
153bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].delayMillis);
154bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
155bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testInsert Waiting >>>>>>>>>>>");
156bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", work.length, aqs
157bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
158bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testInsert Done <<<<<<<<<<<<<<");
159bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
160bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
161bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @SmallTest
162bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testUpdate() throws Exception {
163bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
164bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        final OperationInfo[] work = new OperationInfo[1];
165bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = new OperationInfo();
166bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].op = Operation.EVENT_ARG_UPDATE;
167bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
168bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].token = ++mId;
169bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cookie = ++mId;
170bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].uri = Uri.parse(AUTHORITY_URI + ++mId);
171bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].values = new ContentValues();
172bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].values.put("key", ++mId);
173bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].selection = TEST_SELECTION;
174bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].selectionArgs = TEST_SELECTION_ARGS;
175bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
176bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].delayMillis = 0;
177bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].result = ++mId;
178bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
179bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
180bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        aqs.startUpdate(work[index].token, work[index].cookie, work[index].uri, work[index].values,
181bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].selection, work[index].selectionArgs, work[index].delayMillis);
182bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
183bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testUpdate Waiting >>>>>>>>>>>");
184bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", work.length, aqs
185bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
186bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testUpdate Done <<<<<<<<<<<<<<");
187bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
188bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
189bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @SmallTest
190bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testDelete() throws Exception {
191bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
192bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        final OperationInfo[] work = new OperationInfo[1];
193bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = new OperationInfo();
194bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].op = Operation.EVENT_ARG_DELETE;
195bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
196bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].token = ++mId;
197bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cookie = ++mId;
198bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].uri = Uri.parse(AUTHORITY_URI + "blah");
199bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].selection = TEST_SELECTION;
200bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].selectionArgs = TEST_SELECTION_ARGS;
201bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
202bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].delayMillis = 0;
203bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].result = ++mId;
204bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
205bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
206bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        aqs.startDelete(work[index].token,
207bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].cookie,
208bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].uri,
209bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].selection,
210bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].selectionArgs,
211bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].delayMillis);
212bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
213bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testDelete Waiting >>>>>>>>>>>");
214bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", work.length, aqs
215bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
216bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testDelete Done <<<<<<<<<<<<<<");
217bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
218bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
219bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @SmallTest
220bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testBatch() throws Exception {
221bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
222bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        final OperationInfo[] work = new OperationInfo[1];
223bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = new OperationInfo();
224bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].op = Operation.EVENT_ARG_BATCH;
225bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
226bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].token = ++mId;
227bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cookie = ++mId;
228bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].authority = AUTHORITY;
229bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cpo = new ArrayList<ContentProviderOperation>();
230bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].cpo.add(ContentProviderOperation.newInsert(Uri.parse(AUTHORITY_URI + ++mId))
231bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .build());
232bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
233bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].delayMillis = 0;
234bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        ContentProviderResult[] resultArray = new ContentProviderResult[1];
235bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        resultArray[0] = new ContentProviderResult(++mId);
236bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index].result = resultArray;
237bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
238bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(work), work);
239bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        aqs.startBatch(work[index].token,
240bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].cookie,
241bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].authority,
242bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].cpo,
243bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                work[index].delayMillis);
244bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
245bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testBatch Waiting >>>>>>>>>>>");
246bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", work.length, aqs
247bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
248bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testBatch Done <<<<<<<<<<<<<<");
249bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
250bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
251bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @LargeTest
252bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testDelay() throws Exception {
253bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Tests the ordering of the workqueue
254bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
255bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] work = new OperationInfo[5];
256bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY * 2);
257bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
258bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY * 1);
259bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
260bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY * 3);
261bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
262bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] sorted = generateSortedWork(work, work.length);
263bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
264bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(sorted), sorted);
265bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        startWork(aqs, work);
266bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
267bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testDelay Waiting >>>>>>>>>>>");
268bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", work.length, aqs
269bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
270bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testDelay Done <<<<<<<<<<<<<<");
271bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
272bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
273bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @LargeTest
274bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testCancel_simpleCancelLastTest() throws Exception {
275bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
276bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] work = new OperationInfo[5];
277bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY * 2);
278bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
279bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY);
280bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
281bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = generateWork(MIN_DELAY * 3);
282bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
283bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Not part of the expected as it will be canceled
284bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo toBeCancelled1 = work[index];
285bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] expected = generateSortedWork(work, work.length - 1);
286bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
287bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected);
288bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        startWork(aqs, work);
289bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Operation lastOne = aqs.getLastCancelableOperation();
290bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Log.d(TAG, "lastOne = " + lastOne.toString());
291bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Log.d(TAG, "toBeCancelled1 = " + toBeCancelled1.toString());
292bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertTrue("1) delay=3 is not last", toBeCancelled1.equivalent(lastOne));
293bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Can't cancel delay 3", 1, aqs.cancelOperation(lastOne.token));
294bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
295bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testCancel_simpleCancelLastTest Waiting >>>>>>>>>>>");
296bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", expected.length, aqs
297bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
298bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testCancel_simpleCancelLastTest Done <<<<<<<<<<<<<<");
299bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
300bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
301bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @LargeTest
302bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testCancel_cancelSecondToLast() throws Exception {
303bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
304bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] work = new OperationInfo[5];
305bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY * 2);
306bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
307bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY);
308bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
309bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = generateWork(MIN_DELAY * 3);
310bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
311bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Not part of the expected as it will be canceled
312bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo toBeCancelled1 = work[index];
313bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] expected = new OperationInfo[4];
314bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[0] = work[1]; // delay = 0
315bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[1] = work[3]; // delay = 0
316bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[2] = work[2]; // delay = MIN_DELAY
317bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[3] = work[4]; // delay = MIN_DELAY * 3
318bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
319bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected);
320bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        startWork(aqs, work);
321bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
322bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Operation lastOne = aqs.getLastCancelableOperation(); // delay = 3
323bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertTrue("2) delay=3 is not last", toBeCancelled1.equivalent(lastOne));
324bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Can't cancel delay 2", 1, aqs.cancelOperation(work[0].token));
325bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Delay 2 should be gone", 0, aqs.cancelOperation(work[0].token));
326bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
327bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testCancel_cancelSecondToLast Waiting >>>>>>>>>>>");
328bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", expected.length, aqs
329bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
330bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testCancel_cancelSecondToLast Done <<<<<<<<<<<<<<");
331bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
332bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
333bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    @LargeTest
334bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    public void testCancel_multipleCancels() throws Exception {
335bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
336bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] work = new OperationInfo[5];
337bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY * 2);
338bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
339bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(MIN_DELAY);
340bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index++] = generateWork(0);
341bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work[index] = generateWork(MIN_DELAY * 3);
342bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
343bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Not part of the expected as it will be canceled
344bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] expected = new OperationInfo[3];
345bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[0] = work[1]; // delay = 0
346bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[1] = work[3]; // delay = 0
347bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        expected[2] = work[2]; // delay = MIN_DELAY
348bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
349bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        TestAsyncQueryService aqs = new TestAsyncQueryService(buildTestContext(expected), expected);
350bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        startWork(aqs, work);
351bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
352bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Operation lastOne = aqs.getLastCancelableOperation(); // delay = 3
353bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertTrue("3) delay=3 is not last", work[4].equivalent(lastOne));
354bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Can't cancel delay 2", 1, aqs.cancelOperation(work[0].token));
355bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Delay 2 should be gone", 0, aqs.cancelOperation(work[0].token));
356bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Can't cancel delay 3", 1, aqs.cancelOperation(work[4].token));
357bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Delay 3 should be gone", 0, aqs.cancelOperation(work[4].token));
358bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
359bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testCancel_multipleCancels Waiting >>>>>>>>>>>");
360bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        assertEquals("Not all operations were executed.", expected.length, aqs
361bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                .waitForCompletion(BASE_TEST_WAIT_TIME));
362bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "testCancel_multipleCancels Done <<<<<<<<<<<<<<");
363bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
364bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
365bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private OperationInfo generateWork(long delayMillis) {
366bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo work = new OperationInfo();
367bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.op = Operation.EVENT_ARG_DELETE;
368bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
369bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.token = ++mId;
370bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.cookie = 100 + work.token;
371bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.uri = Uri.parse(AUTHORITY_URI + "blah");
372bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.selection = TEST_SELECTION;
373bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.selectionArgs = TEST_SELECTION_ARGS;
374bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
375bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.delayMillis = delayMillis;
376bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        work.result = 1000 + work.token;
377bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        return work;
378bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
379bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
380bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private void startWork(TestAsyncQueryService aqs, OperationInfo[] work) {
381bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        for (OperationInfo w : work) {
382bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            if (w != null) {
383bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                aqs.startDelete(w.token, w.cookie, w.uri, w.selection, w.selectionArgs,
384bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                        w.delayMillis);
385bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
386bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
387bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
388bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
389bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    OperationInfo[] generateSortedWork(OperationInfo[] work, int length) {
390bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] sorted = new OperationInfo[length];
391bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        System.arraycopy(work, 0, sorted, 0, length);
392bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
393bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Set the scheduled time so they get sorted properly
394bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        for (OperationInfo w : sorted) {
395bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            if (w != null) {
396bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                w.calculateScheduledTime();
397bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
398bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
399bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
400bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        // Stable sort by scheduled time
401bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Arrays.sort(sorted);
402bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
403bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "Unsorted work: " + work.length);
404bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        for (OperationInfo w : work) {
405bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            if (w != null) {
406bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                Log.d(TAG, "Token#" + w.token + " delay=" + w.delayMillis);
407bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
408bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
409bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        Log.d(TAG, "Sorted work: " + sorted.length);
410bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        for (OperationInfo w : sorted) {
411bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            if (w != null) {
412bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                Log.d(TAG, "Token#" + w.token + " delay=" + w.delayMillis);
413bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
414bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
415bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
416bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        return sorted;
417bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
418bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
419bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private Context buildTestContext(final OperationInfo[] work) {
420bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        MockContext context = new MockContext() {
421bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            MockContentResolver mResolver;
422bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
423bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            @Override
424bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            public ContentResolver getContentResolver() {
425bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                if (mResolver == null) {
426bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                    mResolver = new MockContentResolver();
427b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein
428b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                    final String filenamePrefix = "test.";
429b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                    RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
430b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                            new MockContext2(), getContext(), filenamePrefix);
431b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                    IsolatedContext providerContext =
432b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                            new IsolatedContext(mResolver, targetContextWrapper);
433b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein
434b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                    ContentProvider provider = new TestProvider(work);
435b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein                    provider.attachInfo(providerContext, null);
436b6b9cb4a6db19538b6d8ba3ad3cb26d2d7385a63Sam Blitzstein
437bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                    mResolver.addProvider(AUTHORITY, provider);
438bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                }
439bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                return mResolver;
440bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
441bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
442bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            @Override
443bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            public String getPackageName() {
444bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                return AsyncQueryServiceTest.class.getPackage().getName();
445bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
446bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
447e3f85db16cfc50b25b97c64d8ab99820d579e5deMichael Chan            @Override
448bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            public ComponentName startService(Intent service) {
449bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                AsyncQueryServiceTest.this.startService(service);
450bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                return service.getComponent();
451bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
452bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        };
453bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
454bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        return context;
455bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
456bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
457bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    private final class TestCursor extends MockCursor {
458bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int mUnique = ++mId;
459bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
460bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
461bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public int getCount() {
462bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return mUnique;
463bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
464bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
465bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
466bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    /**
467bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan     * TestAsyncQueryService takes the expected results in the constructor. They
468bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan     * are used to verify the data passed to the callbacks.
469bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan     */
470bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    class TestAsyncQueryService extends AsyncQueryService {
471bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int mIndex = 0;
472bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
473bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        private OperationInfo[] mWork;
474bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
475bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        private Semaphore mCountingSemaphore;
476bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
477bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public TestAsyncQueryService(Context context, OperationInfo[] work) {
478bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            super(context);
479bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mCountingSemaphore = new Semaphore(0);
480bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
481bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            // run in a separate thread but call the same code
482bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            HandlerThread thread = new HandlerThread("TestAsyncQueryService");
483bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            thread.start();
484bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            super.setTestHandler(new Handler(thread.getLooper()) {
485bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                @Override
486bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                public void handleMessage(Message msg) {
487bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                    TestAsyncQueryService.this.handleMessage(msg);
488bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                }
489bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            });
490bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
491bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mWork = work;
492bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
493bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
494bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
495bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
496bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "onQueryComplete tid=" + Thread.currentThread().getId());
497bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
498bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
499bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_QUERY);
500bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].token, token);
501bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            /*
502bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan             * Even though our TestProvider returned mWork[mIndex].result, it is
503bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan             * wrapped with new'ed CursorWrapperInner and there's no equal() in
504bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan             * CursorWrapperInner. assertEquals the two cursor will always fail.
505bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan             * So just compare the count which will be unique in our TestCursor;
506bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan             */
507bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(((Cursor) mWork[mIndex].result).getCount(), cursor.getCount());
508bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
509bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mIndex++;
510bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mCountingSemaphore.release();
511bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
512bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
513bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
514bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        protected void onInsertComplete(int token, Object cookie, Uri uri) {
515bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "onInsertComplete tid=" + Thread.currentThread().getId());
516bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
517bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
518bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_INSERT);
519bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].token, token);
520bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].result, uri);
521bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
522bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mIndex++;
523bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mCountingSemaphore.release();
524bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
525bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
526bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
527bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        protected void onUpdateComplete(int token, Object cookie, int result) {
528bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "onUpdateComplete tid=" + Thread.currentThread().getId());
529bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
530bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
531bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_UPDATE);
532bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].token, token);
533bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].result, result);
534bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
535bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mIndex++;
536bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mCountingSemaphore.release();
537bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
538bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
539bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
540bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        protected void onDeleteComplete(int token, Object cookie, int result) {
541bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "onDeleteComplete tid=" + Thread.currentThread().getId());
542bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
543bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
544bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_DELETE);
545bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].token, token);
546bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].result, result);
547bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
548bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mIndex++;
549bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mCountingSemaphore.release();
550bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
551bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
552bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
553bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        protected void onBatchComplete(int token, Object cookie, ContentProviderResult[] results) {
554bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "onBatchComplete tid=" + Thread.currentThread().getId());
555bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "mWork.length=" + mWork.length + " mIndex=" + mIndex);
556bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
557bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].op, Operation.EVENT_ARG_BATCH);
558bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[mIndex].token, token);
559bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
560bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            ContentProviderResult[] expected = (ContentProviderResult[]) mWork[mIndex].result;
561bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(expected.length, results.length);
562bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            for (int i = 0; i < expected.length; ++i) {
563bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                assertEquals(expected[i].count, results[i].count);
564bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                assertEquals(expected[i].uri, results[i].uri);
565bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
566bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
567bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mIndex++;
568bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mCountingSemaphore.release();
569bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
570bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
571bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public int waitForCompletion(long timeoutMills) {
572bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "waitForCompletion tid=" + Thread.currentThread().getId());
573bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            int count = 0;
574bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            try {
575bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                while (count < mWork.length) {
576bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                    if (!mCountingSemaphore.tryAcquire(timeoutMills, TimeUnit.MILLISECONDS)) {
577bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                        break;
578bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                    }
579bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                    count++;
580bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                }
581bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            } catch (InterruptedException e) {
582bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            }
583bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return count;
584bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
585bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
586bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
587bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    /**
588bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan     * This gets called by AsyncQueryServiceHelper to read or write the data. It
589bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan     * also verifies the data against the data passed in the constructor
590bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan     */
591bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    class TestProvider extends ContentProvider {
592bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        OperationInfo[] mWork;
593bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
594bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        int index = 0;
595bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
596bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public TestProvider(OperationInfo[] work) {
597bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            mWork = work;
598bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
599bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
600bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
601bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public final Cursor query(Uri uri, String[] projection, String selection,
602bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan                String[] selectionArgs, String orderBy) {
603bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "Provider query index=" + index);
604bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].op, Operation.EVENT_ARG_QUERY);
605bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].uri, uri);
606bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].projection, projection);
607bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].selection, selection);
608bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].selectionArgs, selectionArgs);
609bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].orderBy, orderBy);
610bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return (Cursor) mWork[index++].result;
611bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
612bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
613bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
614bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public Uri insert(Uri uri, ContentValues values) {
615bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "Provider insert index=" + index);
616bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].op, Operation.EVENT_ARG_INSERT);
617bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].uri, uri);
618bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].values, values);
619bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return (Uri) mWork[index++].result;
620bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
621bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
622bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
623bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
624bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "Provider update index=" + index);
625bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].op, Operation.EVENT_ARG_UPDATE);
626bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].uri, uri);
627bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].values, values);
628bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].selection, selection);
629bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].selectionArgs, selectionArgs);
630bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return (Integer) mWork[index++].result;
631bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
632bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
633bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
634bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public int delete(Uri uri, String selection, String[] selectionArgs) {
635bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "Provider delete index=" + index);
636bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].op, Operation.EVENT_ARG_DELETE);
637bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].uri, uri);
638bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].selection, selection);
639bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].selectionArgs, selectionArgs);
640bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return (Integer) mWork[index++].result;
641bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
642bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
643bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
644bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
645bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            Log.d(TAG, "Provider applyBatch index=" + index);
646bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].op, Operation.EVENT_ARG_BATCH);
647bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            assertEquals(mWork[index].cpo, operations);
648bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return (ContentProviderResult[]) mWork[index++].result;
649bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
650bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
651bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
652bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public String getType(Uri uri) {
653bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return null;
654bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
655bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan
656bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        @Override
657bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        public boolean onCreate() {
658bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan            return false;
659bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan        }
660bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan    }
661bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan}
662