OSDN Git Service

Do updateWorkspaceScreenOrder inside a single transaction.
authorYura <yura@google.com>
Tue, 11 Feb 2014 15:15:29 +0000 (15:15 +0000)
committerYura <yura@google.com>
Tue, 11 Feb 2014 15:15:29 +0000 (15:15 +0000)
The workspacescreens table is updated in LauncherModel.updateWorkspaceScreenOrder
and that the operation to remove all screens, then reinsert the new list of
screens in not inside a single transaction, so if the app is updating or
crashes between ContentResolver.delete and ContentResolver.bulkInsert then
the data will be lost. This CL makes it all happen inside 1 transaction.

Bug: 12523285
Change-Id: I409dbc9f48fa9c8bd4bf3b1453204a4daac1689a

src/com/android/launcher3/LauncherModel.java
src/com/android/launcher3/LauncherProvider.java

index ff8a356..f4fa10f 100644 (file)
@@ -1063,18 +1063,23 @@ public class LauncherModel extends BroadcastReceiver {
         Runnable r = new Runnable() {
             @Override
             public void run() {
+                ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
                 // Clear the table
-                cr.delete(uri, null, null);
+                ops.add(ContentProviderOperation.newDelete(uri).build());
                 int count = screensCopy.size();
-                ContentValues[] values = new ContentValues[count];
                 for (int i = 0; i < count; i++) {
                     ContentValues v = new ContentValues();
                     long screenId = screensCopy.get(i);
                     v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
                     v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-                    values[i] = v;
+                    ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build());
+                }
+
+                try {
+                    cr.applyBatch(LauncherProvider.AUTHORITY, ops);
+                } catch (Exception ex) {
+                    throw new RuntimeException(ex);
                 }
-                cr.bulkInsert(uri, values);
 
                 synchronized (sBgLock) {
                     sBgWorkspaceScreens.clear();
index cec9167..a69f423 100644 (file)
@@ -22,11 +22,14 @@ import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.ContentProvider;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.OperationApplicationException;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
@@ -194,6 +197,20 @@ public class LauncherProvider extends ContentProvider {
     }
 
     @Override
+    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
+            throws OperationApplicationException {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            ContentProviderResult[] result =  super.applyBatch(operations);
+            db.setTransactionSuccessful();
+            return result;
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    @Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
         SqlArguments args = new SqlArguments(uri, selection, selectionArgs);