Merge "Narrow concession for nested transactions." into rvc-dev
diff --git a/src/com/android/providers/media/DatabaseHelper.java b/src/com/android/providers/media/DatabaseHelper.java
index 1688ee3..5795b89 100644
--- a/src/com/android/providers/media/DatabaseHelper.java
+++ b/src/com/android/providers/media/DatabaseHelper.java
@@ -445,6 +445,10 @@
         public final ArrayList<Runnable> backgroundTasks = new ArrayList<>();
     }
 
+    public boolean isTransactionActive() {
+        return (mTransactionState.get() != null);
+    }
+
     public void beginTransaction() {
         Trace.beginSection("transaction " + getDatabaseName());
         Trace.beginSection("beginTransaction");
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index 50ce212..0188b48 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -3198,9 +3198,20 @@
         try {
             for (ContentProviderOperation op : operations) {
                 final DatabaseHelper helper = getDatabaseForUri(op.getUri());
-                if (!transactions.contains(helper)) {
+                if (transactions.contains(helper)) continue;
+
+                if (!helper.isTransactionActive()) {
                     helper.beginTransaction();
                     transactions.add(helper);
+                } else {
+                    // We normally don't allow nested transactions (since we
+                    // don't have a good way to selectively roll them back) but
+                    // if the incoming operation is ignoring exceptions, then we
+                    // don't need to worry about partial rollback and can
+                    // piggyback on the larger active transaction
+                    if (!op.isExceptionAllowed()) {
+                        throw new IllegalStateException("Nested transactions not supported");
+                    }
                 }
             }