Snap for 4448085 from 09a4b06010a777e26020d884712291f5af577883 to oc-m3-release

Change-Id: I1ae7fde9a26b275e30bd5f50ac2cf6d3808f6e67
diff --git a/src/com/android/providers/telephony/CarrierProvider.java b/src/com/android/providers/telephony/CarrierProvider.java
index a13c7e3..a4b6ea0 100644
--- a/src/com/android/providers/telephony/CarrierProvider.java
+++ b/src/com/android/providers/telephony/CarrierProvider.java
@@ -90,7 +90,17 @@
 
     @Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException("Cannot delete URL: " + uri);
+        if (VDBG) {
+            Log.d(TAG, "delete:"
+                    + " uri=" + uri
+                    + " selection={" + selection + "}"
+                    + " selection=" + selection
+                    + " selectionArgs=" + Arrays.toString(selectionArgs));
+        }
+        final int count = getWritableDatabase().delete(CarrierDatabaseHelper.CARRIER_KEY_TABLE,
+                selection, selectionArgs);
+        Log.d(TAG, "  delete.count=" + count);
+        return count;
     }
 
     @Override
diff --git a/src/com/android/providers/telephony/ProviderUtil.java b/src/com/android/providers/telephony/ProviderUtil.java
index 4234b06..cd0f351 100644
--- a/src/com/android/providers/telephony/ProviderUtil.java
+++ b/src/com/android/providers/telephony/ProviderUtil.java
@@ -109,6 +109,7 @@
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.d(TAG, "notifyIfNotDefaultSmsApp - called from " + callingPackage + ", notifying");
         }
+        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         context.sendBroadcast(intent);
     }
 
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index a74ceb0..49c3d10 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -144,6 +144,7 @@
 
     private static final String PREF_FILE_APN = "preferred-apn";
     private static final String COLUMN_APN_ID = "apn_id";
+    private static final String EXPLICIT_SET_CALLED = "explicit_set_called";
 
     private static final String PREF_FILE_FULL_APN = "preferred-full-apn";
     private static final String DB_VERSION_KEY = "version";
@@ -1818,15 +1819,23 @@
         return true;
     }
 
-    private void setPreferredApnId(Long id, int subId) {
+    private void setPreferredApnId(Long id, int subId, boolean saveApn) {
         SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_APN,
                 Context.MODE_PRIVATE);
         SharedPreferences.Editor editor = sp.edit();
-        editor.putLong(COLUMN_APN_ID + subId, id != null ? id.longValue() : INVALID_APN_ID);
+        editor.putLong(COLUMN_APN_ID + subId, id != null ? id : INVALID_APN_ID);
+        // This is for debug purposes. It indicates if this APN was set by DcTracker or user (true)
+        // or if this was restored from APN saved in PREF_FILE_FULL_APN (false).
+        editor.putBoolean(EXPLICIT_SET_CALLED + subId, saveApn);
         editor.apply();
-        // remove saved apn if apnId is invalid
         if (id == null || id.longValue() == INVALID_APN_ID) {
             deletePreferredApn(subId);
+        } else {
+            // If id is not invalid, and saveApn is true, save the actual APN in PREF_FILE_FULL_APN
+            // too.
+            if (saveApn) {
+                setPreferredApn(id, subId);
+            }
         }
     }
 
@@ -1837,8 +1846,7 @@
         if (apnId == INVALID_APN_ID && checkApnSp) {
             apnId = getPreferredApnIdFromApn(subId);
             if (apnId != INVALID_APN_ID) {
-                setPreferredApnId(apnId, subId);
-                deletePreferredApn(subId);
+                setPreferredApnId(apnId, subId, false);
             }
         }
         return apnId;
@@ -1847,7 +1855,12 @@
     private void deletePreferredApnId() {
         SharedPreferences sp = getContext().getSharedPreferences(PREF_FILE_APN,
                 Context.MODE_PRIVATE);
-        // before deleting, save actual preferred apns (not the ids) in a separate SP
+
+        // Before deleting, save actual preferred apns (not the ids) in a separate SP.
+        // NOTE: This code to call setPreferredApn() can be removed since the function is now called
+        // from setPreferredApnId(). However older builds (pre oc-mr1) do not have that change, so
+        // when devices upgrade from those builds and this function is called, this code is needed
+        // otherwise the preferred APN will be lost.
         Map<String, ?> allPrefApnId = sp.getAll();
         for (String key : allPrefApnId.keySet()) {
             // extract subId from key by removing COLUMN_APN_ID
@@ -1861,6 +1874,7 @@
                 loge("Skipping over key " + key + " due to exception " + e);
             }
         }
+
         SharedPreferences.Editor editor = sp.edit();
         editor.clear();
         editor.apply();
@@ -1938,7 +1952,6 @@
             for (String key : CARRIERS_UNIQUE_FIELDS) {
                 editor.remove(key + subId);
             }
-            editor.remove(DB_VERSION_KEY + subId);
             editor.apply();
         }
     }
@@ -2257,7 +2270,7 @@
             {
                 if (initialValues != null) {
                     if(initialValues.containsKey(COLUMN_APN_ID)) {
-                        setPreferredApnId(initialValues.getAsLong(COLUMN_APN_ID), subId);
+                        setPreferredApnId(initialValues.getAsLong(COLUMN_APN_ID), subId, true);
                     }
                 }
                 break;
@@ -2296,6 +2309,8 @@
         {
             case URL_DELETE:
             {
+                // Delete preferred APN for all subIds
+                deletePreferredApnId();
                 // Delete unedited entries
                 count = db.delete(CARRIERS_TABLE, "(" + where + unedited, whereArgs);
                 break;
@@ -2394,7 +2409,7 @@
             case URL_PREFERAPN:
             case URL_PREFERAPN_NO_UPDATE:
             {
-                setPreferredApnId((long)INVALID_APN_ID, subId);
+                setPreferredApnId((long)INVALID_APN_ID, subId, true);
                 if ((match == URL_PREFERAPN) || (match == URL_PREFERAPN_USING_SUBID)) count = 1;
                 break;
             }
@@ -2527,7 +2542,7 @@
             {
                 if (values != null) {
                     if (values.containsKey(COLUMN_APN_ID)) {
-                        setPreferredApnId(values.getAsLong(COLUMN_APN_ID), subId);
+                        setPreferredApnId(values.getAsLong(COLUMN_APN_ID), subId, true);
                         if ((match == URL_PREFERAPN) ||
                                 (match == URL_PREFERAPN_USING_SUBID)) {
                             count = 1;
diff --git a/tests/src/com/android/providers/telephony/CarrierProviderTest.java b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
index b0b9b09..5146aa9 100644
--- a/tests/src/com/android/providers/telephony/CarrierProviderTest.java
+++ b/tests/src/com/android/providers/telephony/CarrierProviderTest.java
@@ -288,4 +288,38 @@
             Log.d(TAG, "Error inserting certificates:: " + e);
         }
     }
+
+    /**
+     * Test delete.
+     */
+    @Test
+    @SmallTest
+    public void testDelete() {
+        int numRowsDeleted = -1;
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(CarrierDatabaseHelper.KEY_TYPE, dummy_type);
+        contentValues.put(CarrierDatabaseHelper.MCC, dummy_mcc);
+        contentValues.put(CarrierDatabaseHelper.MNC, dummy_mnc);
+        contentValues.put(CarrierDatabaseHelper.MVNO_TYPE, dummy_mvno_type);
+        contentValues.put(CarrierDatabaseHelper.MVNO_MATCH_DATA, dummy_mvno_match_data);
+        contentValues.put(CarrierDatabaseHelper.KEY_IDENTIFIER, dummy_key_identifier_data);
+        contentValues.put(CarrierDatabaseHelper.PUBLIC_KEY, dummy_key1.getBytes());
+        contentValues.put(CarrierDatabaseHelper.EXPIRATION_TIME, dummy_key_expiration);
+
+        try {
+            mContentResolver.insert(CarrierProvider.CONTENT_URI, contentValues);
+        } catch (Exception e) {
+            Log.d(TAG, "Error inserting certificates:" + e);
+        }
+
+        try {
+            String whereClause = "mcc=? and mnc=?";
+            String[] whereArgs = new String[] { dummy_mcc, dummy_mnc };
+            numRowsDeleted = mContentResolver.delete(CarrierProvider.CONTENT_URI, whereClause, whereArgs);
+        } catch (Exception e) {
+            Log.d(TAG, "Error updating values:" + e);
+        }
+        assertEquals(numRowsDeleted, 1);
+    }
+
 }