188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov/* 288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project 388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * 488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * you may not use this file except in compliance with the License. 688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * You may obtain a copy of the License at 788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * 888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * 1088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 1188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 1288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * See the License for the specific language governing permissions and 1488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * limitations under the License 1588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov */ 1688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 1788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovpackage com.android.common.content; 1888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 1988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.content.ContentProvider; 2088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.content.ContentProviderOperation; 2188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.content.ContentProviderResult; 2288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.content.ContentValues; 2388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.content.Context; 2488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.content.OperationApplicationException; 2588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.database.sqlite.SQLiteDatabase; 2688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.database.sqlite.SQLiteOpenHelper; 2788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.database.sqlite.SQLiteTransactionListener; 2888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport android.net.Uri; 2988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 3088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovimport java.util.ArrayList; 3188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 3288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov/** 3388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * General purpose {@link ContentProvider} base class that uses SQLiteDatabase for storage. 3488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov */ 3588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikovpublic abstract class SQLiteContentProvider extends ContentProvider 3688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov implements SQLiteTransactionListener { 3788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 3888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private static final String TAG = "SQLiteContentProvider"; 3988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 4088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private SQLiteOpenHelper mOpenHelper; 4188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private volatile boolean mNotifyChange; 4288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected SQLiteDatabase mDb; 4388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 4488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private final ThreadLocal<Boolean> mApplyingBatch = new ThreadLocal<Boolean>(); 4588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private static final int SLEEP_AFTER_YIELD_DELAY = 4000; 4688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 4788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov /** 4888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * Maximum number of operations allowed in a batch between yield points. 4988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov */ 5088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private static final int MAX_OPERATIONS_PER_YIELD_POINT = 500; 5188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 52698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson /** 53698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson * @return Number of operations that can be applied at once without a yield point. 54698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson */ 55698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson public int getMaxOperationsPerYield() { 56698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson return MAX_OPERATIONS_PER_YIELD_POINT; 57698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson } 58698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson 5988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov @Override 6088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public boolean onCreate() { 6188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov Context context = getContext(); 6288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mOpenHelper = getDatabaseHelper(context); 6388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return true; 6488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 6588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 6688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected abstract SQLiteOpenHelper getDatabaseHelper(Context context); 6788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 6888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov /** 6988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * The equivalent of the {@link #insert} method, but invoked within a transaction. 7088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov */ 7188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected abstract Uri insertInTransaction(Uri uri, ContentValues values); 7288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 7388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov /** 7488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * The equivalent of the {@link #update} method, but invoked within a transaction. 7588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov */ 7688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected abstract int updateInTransaction(Uri uri, ContentValues values, String selection, 7788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov String[] selectionArgs); 7888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 7988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov /** 8088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov * The equivalent of the {@link #delete} method, but invoked within a transaction. 8188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov */ 8288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected abstract int deleteInTransaction(Uri uri, String selection, String[] selectionArgs); 8388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 8488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected abstract void notifyChange(); 8588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 8688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public SQLiteOpenHelper getDatabaseHelper() { 8788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return mOpenHelper; 8888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 8988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 9088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov private boolean applyingBatch() { 9188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return mApplyingBatch.get() != null && mApplyingBatch.get(); 9288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 9388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 9488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov @Override 9588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public Uri insert(Uri uri, ContentValues values) { 9688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov Uri result = null; 9788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov boolean applyingBatch = applyingBatch(); 9888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (!applyingBatch) { 9988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = mOpenHelper.getWritableDatabase(); 10088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.beginTransactionWithListener(this); 10188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov try { 10288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov result = insertInTransaction(uri, values); 10388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (result != null) { 10488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 10588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 10688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.setTransactionSuccessful(); 10788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } finally { 10888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.endTransaction(); 10988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 11088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 11188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov onEndTransaction(); 11288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } else { 11388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov result = insertInTransaction(uri, values); 11488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (result != null) { 11588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 11688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 11788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 11888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return result; 11988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 12088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 12188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov @Override 12288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public int bulkInsert(Uri uri, ContentValues[] values) { 12388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov int numValues = values.length; 12488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = mOpenHelper.getWritableDatabase(); 12588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.beginTransactionWithListener(this); 12688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov try { 12788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov for (int i = 0; i < numValues; i++) { 12888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov Uri result = insertInTransaction(uri, values[i]); 12988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (result != null) { 13088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 13188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 13288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov boolean savedNotifyChange = mNotifyChange; 13388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov SQLiteDatabase savedDb = mDb; 13488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.yieldIfContendedSafely(); 13588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = savedDb; 13688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = savedNotifyChange; 13788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 13888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.setTransactionSuccessful(); 13988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } finally { 14088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.endTransaction(); 14188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 14288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 14388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov onEndTransaction(); 14488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return numValues; 14588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 14688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 14788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov @Override 14888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 14988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov int count = 0; 15088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov boolean applyingBatch = applyingBatch(); 15188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (!applyingBatch) { 15288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = mOpenHelper.getWritableDatabase(); 15388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.beginTransactionWithListener(this); 15488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov try { 15588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov count = updateInTransaction(uri, values, selection, selectionArgs); 15688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (count > 0) { 15788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 15888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 15988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.setTransactionSuccessful(); 16088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } finally { 16188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.endTransaction(); 16288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 16388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 16488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov onEndTransaction(); 16588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } else { 16688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov count = updateInTransaction(uri, values, selection, selectionArgs); 16788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (count > 0) { 16888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 16988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 17088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 17188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 17288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return count; 17388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 17488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 17588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov @Override 17688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public int delete(Uri uri, String selection, String[] selectionArgs) { 17788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov int count = 0; 17888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov boolean applyingBatch = applyingBatch(); 17988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (!applyingBatch) { 18088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = mOpenHelper.getWritableDatabase(); 18188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.beginTransactionWithListener(this); 18288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov try { 18388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov count = deleteInTransaction(uri, selection, selectionArgs); 18488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (count > 0) { 18588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 18688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 18788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.setTransactionSuccessful(); 18888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } finally { 18988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.endTransaction(); 19088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 19188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 19288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov onEndTransaction(); 19388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } else { 19488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov count = deleteInTransaction(uri, selection, selectionArgs); 19588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (count > 0) { 19688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = true; 19788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 19888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 19988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return count; 20088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 20188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 20288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov @Override 20388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) 20488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov throws OperationApplicationException { 20588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov int ypCount = 0; 20688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov int opCount = 0; 20788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = mOpenHelper.getWritableDatabase(); 20888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.beginTransactionWithListener(this); 20988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov try { 21088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mApplyingBatch.set(true); 21188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov final int numOperations = operations.size(); 21288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov final ContentProviderResult[] results = new ContentProviderResult[numOperations]; 21388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov for (int i = 0; i < numOperations; i++) { 214698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson if (++opCount > getMaxOperationsPerYield()) { 21588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov throw new OperationApplicationException( 21688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov "Too many content provider operations between yield points. " 21788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov + "The maximum number of operations per yield point is " 21888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov + MAX_OPERATIONS_PER_YIELD_POINT, ypCount); 21988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 22088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov final ContentProviderOperation operation = operations.get(i); 22188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (i > 0 && operation.isYieldAllowed()) { 22288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov opCount = 0; 22388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov boolean savedNotifyChange = mNotifyChange; 22488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (mDb.yieldIfContendedSafely(SLEEP_AFTER_YIELD_DELAY)) { 22588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb = mOpenHelper.getWritableDatabase(); 22688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = savedNotifyChange; 22788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov ypCount++; 22888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 22988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 23088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 23188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov results[i] = operation.apply(this, results, i); 23288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 23388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.setTransactionSuccessful(); 23488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov return results; 23588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } finally { 23688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mApplyingBatch.set(false); 23788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mDb.endTransaction(); 23888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov onEndTransaction(); 23988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 24088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 24188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 242698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson @Override 24388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public void onBegin() { 24488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov onBeginTransaction(); 24588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 24688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 247698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson @Override 24888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public void onCommit() { 24988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov beforeTransactionCommit(); 25088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 25188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 252698c55f3a36fe972b381ad216dc5de3760936858Tom Wilson @Override 25388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov public void onRollback() { 25488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov // not used 25588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 25688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 25788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected void onBeginTransaction() { 25888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 25988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 26088287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected void beforeTransactionCommit() { 26188287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 26288287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov 26388287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov protected void onEndTransaction() { 26488287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov if (mNotifyChange) { 26588287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov mNotifyChange = false; 26688287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov notifyChange(); 26788287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 26888287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov } 26988287b58d54e7a6413992fe290832a5835fd0c0fDmitri Plotnikov} 270