1bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan/* 2bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Copyright (C) 2010 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 Chan 21bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.app.IntentService; 22bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentProviderOperation; 23bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentResolver; 24bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.ContentValues; 25bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.Context; 26bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.Intent; 27bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.content.OperationApplicationException; 28bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.database.Cursor; 29bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.net.Uri; 30bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.Handler; 31bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.Message; 32bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.RemoteException; 33bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.os.SystemClock; 34bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport android.util.Log; 35bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 36bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.ArrayList; 37bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.Arrays; 38bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.Iterator; 39bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.PriorityQueue; 40bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.concurrent.Delayed; 41bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanimport java.util.concurrent.TimeUnit; 42bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 43bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chanpublic class AsyncQueryServiceHelper extends IntentService { 44bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan private static final String TAG = "AsyncQuery"; 45bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 46bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan private static final PriorityQueue<OperationInfo> sWorkQueue = 47bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan new PriorityQueue<OperationInfo>(); 48bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 49bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan protected Class<AsyncQueryService> mService = AsyncQueryService.class; 50bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 51bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan protected static class OperationInfo implements Delayed{ 52bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public int token; // Used for cancel 53bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public int op; 54bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public ContentResolver resolver; 55bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public Uri uri; 56bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public String authority; 57bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public Handler handler; 58bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public String[] projection; 59bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public String selection; 60bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public String[] selectionArgs; 61bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public String orderBy; 62bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public Object result; 63bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public Object cookie; 64bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public ContentValues values; 65bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public ArrayList<ContentProviderOperation> cpo; 66bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 67bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /** 68bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * delayMillis is relative time e.g. 10,000 milliseconds 69bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 70bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public long delayMillis; 71bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 72bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /** 73bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * scheduleTimeMillis is the time scheduled for this to be processed. 74bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * e.g. SystemClock.elapsedRealtime() + 10,000 milliseconds Based on 75bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * {@link android.os.SystemClock#elapsedRealtime } 76bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 77bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan private long mScheduledTimeMillis = 0; 78bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 79bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // @VisibleForTesting 80bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan void calculateScheduledTime() { 81bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan mScheduledTimeMillis = SystemClock.elapsedRealtime() + delayMillis; 82bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 83bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 84bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // @Override // Uncomment with Java6 85bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public long getDelay(TimeUnit unit) { 86bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return unit.convert(mScheduledTimeMillis - SystemClock.elapsedRealtime(), 87bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan TimeUnit.MILLISECONDS); 88bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 89bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 90bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // @Override // Uncomment with Java6 91bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public int compareTo(Delayed another) { 92bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan OperationInfo anotherArgs = (OperationInfo) another; 93bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (this.mScheduledTimeMillis == anotherArgs.mScheduledTimeMillis) { 94bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return 0; 95bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } else if (this.mScheduledTimeMillis < anotherArgs.mScheduledTimeMillis) { 96bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return -1; 97bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } else { 98bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return 1; 99bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 100bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 101bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 102bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan @Override 103bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public String toString() { 104bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan StringBuilder builder = new StringBuilder(); 105bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append("OperationInfo [\n\t token= "); 106bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(token); 107bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t op= "); 108bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(Operation.opToChar(op)); 109bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t uri= "); 110bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(uri); 111bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t authority= "); 112bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(authority); 113bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t delayMillis= "); 114bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(delayMillis); 115bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t mScheduledTimeMillis= "); 116bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(mScheduledTimeMillis); 117bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t resolver= "); 118bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(resolver); 119bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t handler= "); 120bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(handler); 121bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t projection= "); 122bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(Arrays.toString(projection)); 123bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t selection= "); 124bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(selection); 125bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t selectionArgs= "); 126bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(Arrays.toString(selectionArgs)); 127bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t orderBy= "); 128bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(orderBy); 129bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t result= "); 130bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(result); 131bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t cookie= "); 132bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(cookie); 133bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t values= "); 134bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(values); 135bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(",\n\t cpo= "); 136bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append(cpo); 137bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan builder.append("\n]"); 138bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return builder.toString(); 139bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 140bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 141bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /** 142bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Compares an user-visible operation to this private OperationInfo 143bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * object 144bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * 145bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * @param o operation to be compared 146bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * @return true if logically equivalent 147bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 148bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public boolean equivalent(Operation o) { 149bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return o.token == this.token && o.op == this.op; 150bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 151bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 152bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 153bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /** 154bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Queues the operation for execution 155bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * 156bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * @param context 157bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * @param args OperationInfo object describing the operation 158bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 159bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan static public void queueOperation(Context context, OperationInfo args) { 160bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // Set the schedule time for execution based on the desired delay. 161bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.calculateScheduledTime(); 162bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 163bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan synchronized (sWorkQueue) { 164bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan sWorkQueue.add(args); 165bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan sWorkQueue.notify(); 166bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 167bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 168bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan context.startService(new Intent(context, AsyncQueryServiceHelper.class)); 169bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 170bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 171bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /** 172bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Gets the last delayed operation. It is typically used for canceling. 173bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * 174bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * @return Operation object which contains of the last cancelable operation 175bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 176bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan static public Operation getLastCancelableOperation() { 177bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan long lastScheduleTime = Long.MIN_VALUE; 178bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Operation op = null; 179bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 180bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan synchronized (sWorkQueue) { 181bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // Unknown order even for a PriorityQueue 182bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Iterator<OperationInfo> it = sWorkQueue.iterator(); 183bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan while (it.hasNext()) { 184bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan OperationInfo info = it.next(); 185bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (info.delayMillis > 0 && lastScheduleTime < info.mScheduledTimeMillis) { 186bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (op == null) { 187bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan op = new Operation(); 188bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 189bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 190bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan op.token = info.token; 191bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan op.op = info.op; 192bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan op.scheduledExecutionTime = info.mScheduledTimeMillis; 193bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 194bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan lastScheduleTime = info.mScheduledTimeMillis; 195bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 196bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 197bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 198bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 199bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 200bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "getLastCancelableOperation -> Operation:" + Operation.opToChar(op.op) 201bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan + " token:" + op.token); 202bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 203bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return op; 204bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 205bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 206bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /** 207bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Attempts to cancel operation that has not already started. Note that 208bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * there is no guarantee that the operation will be canceled. They still may 209bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * result in a call to on[Query/Insert/Update/Delete/Batch]Complete after 210bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * this call has completed. 211bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * 212bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * @param token The token representing the operation to be canceled. If 213bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * multiple operations have the same token they will all be 214bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * canceled. 215bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 216bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan static public int cancelOperation(int token) { 217bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan int canceled = 0; 218bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan synchronized (sWorkQueue) { 219bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Iterator<OperationInfo> it = sWorkQueue.iterator(); 220bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan while (it.hasNext()) { 221bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (it.next().token == token) { 222bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan it.remove(); 223bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan ++canceled; 224bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 225bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 226bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 227bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 228bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 229bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "cancelOperation(" + token + ") -> " + canceled); 230bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 231bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return canceled; 232bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 233bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 234bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public AsyncQueryServiceHelper(String name) { 235bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan super(name); 236bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 237bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 238bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public AsyncQueryServiceHelper() { 239bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan super("AsyncQueryServiceHelper"); 240bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 241bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 242bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan @Override 243bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan protected void onHandleIntent(Intent intent) { 244bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan OperationInfo args; 245bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 246bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 247bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "onHandleIntent: queue size=" + sWorkQueue.size()); 248bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 249bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan synchronized (sWorkQueue) { 250bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan while (true) { 251bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /* 252bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * This method can be called with no work because of 253bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * cancellations 254bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 255bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (sWorkQueue.size() == 0) { 256bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan return; 257bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } else if (sWorkQueue.size() == 1) { 258bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan OperationInfo first = sWorkQueue.peek(); 259bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan long waitTime = first.mScheduledTimeMillis - SystemClock.elapsedRealtime(); 260bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (waitTime > 0) { 261bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan try { 262bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan sWorkQueue.wait(waitTime); 263bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } catch (InterruptedException e) { 264bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 265bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 266bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 267bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 268bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args = sWorkQueue.poll(); 269bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (args != null) { 270bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan // Got work to do. Break out of waiting loop 271bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan break; 272bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 273bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 274bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 275bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 276bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 277bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "onHandleIntent: " + args); 278bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 279bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 280bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan ContentResolver resolver = args.resolver; 281bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (resolver != null) { 282bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 283bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan switch (args.op) { 284bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan case Operation.EVENT_ARG_QUERY: 285bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Cursor cursor; 286bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan try { 287bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan cursor = resolver.query(args.uri, args.projection, args.selection, 288bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.selectionArgs, args.orderBy); 289bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /* 290bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * Calling getCount() causes the cursor window to be 291bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * filled, which will make the first access on the main 292bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * thread a lot faster 293bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 294bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (cursor != null) { 295bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan cursor.getCount(); 296bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 297bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } catch (Exception e) { 298bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.w(TAG, e.toString()); 299bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan cursor = null; 300bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 301bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 302bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.result = cursor; 303bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan break; 304bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 305bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan case Operation.EVENT_ARG_INSERT: 306bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.result = resolver.insert(args.uri, args.values); 307bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan break; 308bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 309bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan case Operation.EVENT_ARG_UPDATE: 310bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.result = resolver.update(args.uri, args.values, args.selection, 311bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.selectionArgs); 312bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan break; 313bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 314bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan case Operation.EVENT_ARG_DELETE: 315ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen try { 316ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen args.result = resolver.delete(args.uri, args.selection, args.selectionArgs); 317ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen } catch (IllegalArgumentException e) { 318ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen Log.w(TAG, "Delete failed."); 319ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen Log.w(TAG, e.toString()); 320ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen args.result = 0; 321ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen } 322ae0a1002a66b13fcedffaa9561f3e9c92eb99f95Huaqiang Chen 323bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan break; 324bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 325bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan case Operation.EVENT_ARG_BATCH: 326bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan try { 327bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.result = resolver.applyBatch(args.authority, args.cpo); 328bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } catch (RemoteException e) { 329bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.e(TAG, e.toString()); 330bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.result = null; 331bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } catch (OperationApplicationException e) { 332bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.e(TAG, e.toString()); 333bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan args.result = null; 334bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 335bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan break; 336bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 337bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 338bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan /* 339bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * passing the original token value back to the caller on top of the 340bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan * event values in arg1. 341bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan */ 342bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Message reply = args.handler.obtainMessage(args.token); 343bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan reply.obj = args; 344bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan reply.arg1 = args.op; 345bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 346bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 347bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "onHandleIntent: op=" + Operation.opToChar(args.op) + ", token=" 348bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan + reply.what); 349bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 350bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 351bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan reply.sendToTarget(); 352bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 353bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 354bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 355bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan @Override 356bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public void onStart(Intent intent, int startId) { 357bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 358bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "onStart startId=" + startId); 359bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 360bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan super.onStart(intent, startId); 361bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 362bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 363bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan @Override 364bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public void onCreate() { 365bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 366bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "onCreate"); 367bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 368bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan super.onCreate(); 369bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 370bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan 371bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan @Override 372bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public void onDestroy() { 373bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan if (AsyncQueryService.localLOGV) { 374bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan Log.d(TAG, "onDestroy"); 375bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 376bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan super.onDestroy(); 377bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan } 378bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan} 379