Merge "Implement bulkInsert in TelephonyProvider"
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 2ece324..f4efb1d 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -44,6 +44,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Xml;
 
 import com.android.internal.util.XmlUtils;
@@ -1820,16 +1821,44 @@
     }
 
     @Override
-    public synchronized Uri insert(Uri url, ContentValues initialValues)
-    {
+    public synchronized int bulkInsert(Uri url, ContentValues[] values) {
+        int count = 0;
+        boolean notify = false;
+        for (ContentValues value : values) {
+            Pair<Uri, Boolean> rowAndNotify = insertSingleRow(url, value);
+            if (rowAndNotify.first != null) {
+                count++;
+            }
+            if (rowAndNotify.second == true) {
+                notify = true;
+            }
+        }
+        if (notify) {
+            getContext().getContentResolver().notifyChange(CONTENT_URI, null,
+                    true, UserHandle.USER_ALL);
+        }
+        return count;
+    }
+
+    @Override
+    public synchronized Uri insert(Uri url, ContentValues initialValues) {
+        Pair<Uri, Boolean> rowAndNotify = insertSingleRow(url, initialValues);
+        if (rowAndNotify.second) {
+            getContext().getContentResolver().notifyChange(CONTENT_URI, null,
+                    true, UserHandle.USER_ALL);
+        }
+        return rowAndNotify.first;
+    }
+
+    private Pair<Uri, Boolean> insertSingleRow(Uri url, ContentValues initialValues) {
         Uri result = null;
         int subId = SubscriptionManager.getDefaultSubscriptionId();
 
         checkPermission();
 
+        boolean notify = false;
         SQLiteDatabase db = getWritableDatabase();
         int match = s_urlMatcher.match(url);
-        boolean notify = false;
         switch (match)
         {
             case URL_TELEPHONY_USING_SUBID:
@@ -1839,7 +1868,7 @@
                     subId = Integer.parseInt(subIdString);
                 } catch (NumberFormatException e) {
                     loge("NumberFormatException" + e);
-                    return result;
+                    return Pair.create(result, notify);
                 }
                 if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
             }
@@ -1894,7 +1923,7 @@
                     subId = Integer.parseInt(subIdString);
                 } catch (NumberFormatException e) {
                     loge("NumberFormatException" + e);
-                    return result;
+                    return Pair.create(result, notify);
                 }
                 if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
                 // FIXME use subId in the query
@@ -1929,7 +1958,7 @@
                     subId = Integer.parseInt(subIdString);
                 } catch (NumberFormatException e) {
                     loge("NumberFormatException" + e);
-                    return result;
+                    return Pair.create(result, notify);
                 }
                 if (DBG) log("subIdString = " + subIdString + " subId = " + subId);
             }
@@ -1953,12 +1982,7 @@
             }
         }
 
-        if (notify) {
-            getContext().getContentResolver().notifyChange(CONTENT_URI, null,
-                    true, UserHandle.USER_ALL);
-        }
-
-        return result;
+        return Pair.create(result, notify);
     }
 
     @Override
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index dd505d9..1f221f5 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -25,6 +25,7 @@
 import android.content.pm.ProviderInfo;
 import android.content.res.Resources;
 import android.database.Cursor;
+import android.database.ContentObserver;
 import android.database.DatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
@@ -70,6 +71,8 @@
     private MockContentResolver mContentResolver;
     private TelephonyProviderTestable mTelephonyProviderTestable;
 
+    private int notifyChangeCount;
+
 
     /**
      * This is used to give the TelephonyProviderTest a mocked context which takes a
@@ -80,7 +83,13 @@
         private final MockContentResolver mResolver;
 
         public MockContextWithProvider(TelephonyProvider telephonyProvider) {
-            mResolver = new MockContentResolver();
+            mResolver = new MockContentResolver() {
+                @Override
+                public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork,
+                        int userHandle) {
+                    notifyChangeCount++;
+                }
+            };
 
             // Add authority="telephony" to given telephonyProvider
             ProviderInfo providerInfo = new ProviderInfo();
@@ -135,6 +144,7 @@
         mTelephonyProviderTestable = new TelephonyProviderTestable();
         mContext = new MockContextWithProvider(mTelephonyProviderTestable);
         mContentResolver = (MockContentResolver) mContext.getContentResolver();
+        notifyChangeCount = 0;
     }
 
     @Override
@@ -144,6 +154,68 @@
     }
 
     /**
+     * Test bulk inserting, querying;
+     * Verify that the inserted values match the result of the query.
+     */
+    @Test
+    @SmallTest
+    public void testBulkInsertCarriers() {
+        // insert 2 test contentValues
+        ContentValues contentValues = new ContentValues();
+        final String insertApn = "exampleApnName";
+        final String insertName = "exampleName";
+        final Integer insertCurrent = 1;
+        final String insertNumeric = "123456";
+        contentValues.put(Carriers.APN, insertApn);
+        contentValues.put(Carriers.NAME, insertName);
+        contentValues.put(Carriers.CURRENT, insertCurrent);
+        contentValues.put(Carriers.NUMERIC, insertNumeric);
+
+        ContentValues contentValues2 = new ContentValues();
+        final String insertApn2 = "exampleApnName2";
+        final String insertName2 = "exampleName2";
+        final Integer insertCurrent2 = 1;
+        final String insertNumeric2 = "789123";
+        contentValues2.put(Carriers.APN, insertApn2);
+        contentValues2.put(Carriers.NAME, insertName2);
+        contentValues2.put(Carriers.CURRENT, insertCurrent2);
+        contentValues2.put(Carriers.NUMERIC, insertNumeric2);
+
+        Log.d(TAG, "testInsertCarriers: Bulk inserting contentValues=" + contentValues
+                + ", " + contentValues2);
+        ContentValues[] values = new ContentValues[]{ contentValues, contentValues2 };
+        int rows = mContentResolver.bulkInsert(Carriers.CONTENT_URI, values);
+        assertEquals(2, rows);
+        assertEquals(1, notifyChangeCount);
+
+        // get values in table
+        final String[] testProjection =
+        {
+            Carriers.APN,
+            Carriers.NAME,
+            Carriers.CURRENT,
+        };
+        final String selection = Carriers.NUMERIC + "=?";
+        String[] selectionArgs = { insertNumeric };
+        Log.d(TAG, "testInsertCarriers query projection: " + testProjection
+                + "\ntestInsertCarriers selection: " + selection
+                + "\ntestInsertCarriers selectionArgs: " + selectionArgs);
+        Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI,
+                testProjection, selection, selectionArgs, null);
+
+        // verify that inserted values match results of query
+        assertNotNull(cursor);
+        assertEquals(1, cursor.getCount());
+        cursor.moveToFirst();
+        final String resultApn = cursor.getString(0);
+        final String resultName = cursor.getString(1);
+        final Integer resultCurrent = cursor.getInt(2);
+        assertEquals(insertApn, resultApn);
+        assertEquals(insertName, resultName);
+        assertEquals(insertCurrent, resultCurrent);
+    }
+
+    /**
      * Test inserting, querying, and deleting values in carriers table.
      * Verify that the inserted values match the result of the query and are deleted.
      */