Manually merge changes from giant AOSP topic

Change-Id: Iae0f83ee9bfacb251a64bcd36f72573cbb3aab4d
diff --git a/OWNERS b/OWNERS
index f63da0c..7aabde8 100644
--- a/OWNERS
+++ b/OWNERS
@@ -3,4 +3,5 @@
 jminjie@google.com
 rgreenwalt@google.com
 tomtaylor@google.com
-jackyu@google.com
\ No newline at end of file
+jackyu@google.com
+refuhoo@google.com
\ No newline at end of file
diff --git a/res/values-en-rCA/config.xml b/res/values-en-rCA/config.xml
new file mode 100644
index 0000000..99877a6
--- /dev/null
+++ b/res/values-en-rCA/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="persist_apns_for_plmn">
+    <item msgid="6413072509259000954">"20404"</item>
+    <item msgid="5639159280778239123">"310004"</item>
+    <item msgid="3860605521380788028">"310120"</item>
+    <item msgid="537693705785480198">"311480"</item>
+  </string-array>
+</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..f11997b
--- /dev/null
+++ b/res/values-en-rCA/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" product="tablet" msgid="9194799012395299737">"Mobile Network Configuration"</string>
+    <string name="app_label" product="default" msgid="8338087656149558019">"Phone and Messaging Storage"</string>
+</resources>
diff --git a/res/values-en-rXC/config.xml b/res/values-en-rXC/config.xml
new file mode 100644
index 0000000..274d8aa
--- /dev/null
+++ b/res/values-en-rXC/config.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+  <string-array name="persist_apns_for_plmn">
+    <item msgid="6413072509259000954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎20404‎‏‎‎‏‎"</item>
+    <item msgid="5639159280778239123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎310004‎‏‎‎‏‎"</item>
+    <item msgid="3860605521380788028">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎310120‎‏‎‎‏‎"</item>
+    <item msgid="537693705785480198">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎311480‎‏‎‎‏‎"</item>
+  </string-array>
+</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..22950f7
--- /dev/null
+++ b/res/values-en-rXC/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" product="tablet" msgid="9194799012395299737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎Mobile Network Configuration‎‏‎‎‏‎"</string>
+    <string name="app_label" product="default" msgid="8338087656149558019">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‏‎Phone and Messaging Storage‎‏‎‎‏‎"</string>
+</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index e1e6246..6d618f7 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -17,5 +17,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" product="tablet" msgid="9194799012395299737">"Конфигурација на мобилна мрежа"</string>
-    <string name="app_label" product="default" msgid="8338087656149558019">"Меморија за телефонот и пораките"</string>
+    <string name="app_label" product="default" msgid="8338087656149558019">"Капацитет за телефонот и пораките"</string>
 </resources>
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
index 547b22e..30158c3 100644
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ b/src/com/android/providers/telephony/MmsProvider.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.content.ContentProvider;
+import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -38,6 +39,7 @@
 import android.provider.Telephony.CanonicalAddressesColumns;
 import android.provider.Telephony.Mms;
 import android.provider.Telephony.Mms.Addr;
+import android.provider.Telephony.Mms.Inbox;
 import android.provider.Telephony.Mms.Part;
 import android.provider.Telephony.Mms.Rate;
 import android.provider.Telephony.MmsSms;
@@ -360,6 +362,7 @@
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         ContentValues finalValues;
         Uri res = Mms.CONTENT_URI;
+        Uri caseSpecificUri = null;
         long rowId;
 
         if (table.equals(TABLE_PDU)) {
@@ -409,6 +412,11 @@
                 return null;
             }
 
+            // Notify change when an MMS is received.
+            if (msgBox == Mms.MESSAGE_BOX_INBOX) {
+                caseSpecificUri = ContentUris.withAppendedId(Mms.Inbox.CONTENT_URI, rowId);
+            }
+
             res = Uri.parse(res + "/" + rowId);
         } else if (table.equals(TABLE_ADDR)) {
             finalValues = new ContentValues(values);
@@ -584,7 +592,7 @@
         }
 
         if (notify) {
-            notifyChange(res);
+            notifyChange(res, caseSpecificUri);
         }
         return res;
     }
@@ -680,7 +688,7 @@
         }
 
         if ((deletedRows > 0) && notify) {
-            notifyChange(uri);
+            notifyChange(uri, null);
         }
         return deletedRows;
     }
@@ -856,7 +864,7 @@
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         int count = db.update(table, finalValues, finalSelection, selectionArgs);
         if (notify && (count > 0)) {
-            notifyChange(uri);
+            notifyChange(uri, null);
         }
         return count;
     }
@@ -973,11 +981,16 @@
         values.remove(Mms._ID);
     }
 
-    private void notifyChange(final Uri uri) {
+    private void notifyChange(final Uri uri, final Uri caseSpecificUri) {
         final Context context = getContext();
+        if (caseSpecificUri != null) {
+            context.getContentResolver().notifyChange(
+                caseSpecificUri, null, true, UserHandle.USER_ALL);
+        }
         context.getContentResolver().notifyChange(
                 MmsSms.CONTENT_URI, null, true, UserHandle.USER_ALL);
-        ProviderUtil.notifyIfNotDefaultSmsApp(uri, getCallingPackage(), context);
+        ProviderUtil.notifyIfNotDefaultSmsApp(caseSpecificUri == null ? uri : caseSpecificUri,
+                getCallingPackage(), context);
     }
 
     private final static String TAG = "MmsProvider";
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 8994b83..62a945e 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -101,6 +101,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IApnSourceService;
+import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -123,7 +124,7 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false; // STOPSHIP if true
 
-    private static final int DATABASE_VERSION = 22 << 16;
+    private static final int DATABASE_VERSION = 23 << 16;
     private static final int URL_UNKNOWN = 0;
     private static final int URL_TELEPHONY = 1;
     private static final int URL_CURRENT = 2;
@@ -164,6 +165,9 @@
     private static final String OTA_UPDATED_APNS_PATH = "misc/apns-conf.xml";
     private static final String OLD_APNS_PATH = "etc/old-apns-conf.xml";
 
+    private static final String DEFAULT_PROTOCOL = "IP";
+    private static final String DEFAULT_ROAMING_PROTOCOL = "IP";
+
     private static final UriMatcher s_urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 
     private static final ContentValues s_currentNullMap;
@@ -245,8 +249,8 @@
                 AUTH_TYPE + " INTEGER DEFAULT -1," +
                 TYPE + " TEXT DEFAULT ''," +
                 CURRENT + " INTEGER," +
-                PROTOCOL + " TEXT DEFAULT 'IP'," +
-                ROAMING_PROTOCOL + " TEXT DEFAULT 'IP'," +
+                PROTOCOL + " TEXT DEFAULT " + DEFAULT_PROTOCOL + "," +
+                ROAMING_PROTOCOL + " TEXT DEFAULT " + DEFAULT_ROAMING_PROTOCOL + "," +
                 CARRIER_ENABLED + " BOOLEAN DEFAULT 1," +
                 BEARER + " INTEGER DEFAULT 0," +
                 BEARER_BITMASK + " INTEGER DEFAULT 0," +
@@ -307,7 +311,13 @@
             + SubscriptionManager.CB_ETWS_TEST_ALERT + " INTEGER DEFAULT 0,"
             + SubscriptionManager.CB_CHANNEL_50_ALERT + " INTEGER DEFAULT 1,"
             + SubscriptionManager.CB_CMAS_TEST_ALERT + " INTEGER DEFAULT 0,"
-            + SubscriptionManager.CB_OPT_OUT_DIALOG + " INTEGER DEFAULT 1"
+            + SubscriptionManager.CB_OPT_OUT_DIALOG + " INTEGER DEFAULT 1,"
+            + SubscriptionManager.ENHANCED_4G_MODE_ENABLED + " INTEGER DEFAULT -1,"
+            + SubscriptionManager.VT_IMS_ENABLED + " INTEGER DEFAULT -1,"
+            + SubscriptionManager.WFC_IMS_ENABLED + " INTEGER DEFAULT -1,"
+            + SubscriptionManager.WFC_IMS_MODE + " INTEGER DEFAULT -1,"
+            + SubscriptionManager.WFC_IMS_ROAMING_MODE + " INTEGER DEFAULT -1,"
+            + SubscriptionManager.WFC_IMS_ROAMING_ENABLED + " INTEGER DEFAULT -1"
             + ");";
 
     static {
@@ -908,6 +918,30 @@
             }
             if (oldVersion < (22 << 16 | 6)) {
                 try {
+                    // Try to update the siminfo table. It might not be there.
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.ENHANCED_4G_MODE_ENABLED
+                            + " INTEGER DEFAULT -1;");
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.VT_IMS_ENABLED + " INTEGER DEFAULT -1;");
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.WFC_IMS_ENABLED + " INTEGER DEFAULT -1;");
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.WFC_IMS_MODE + " INTEGER DEFAULT -1;");
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.WFC_IMS_ROAMING_MODE + " INTEGER DEFAULT -1;");
+                    db.execSQL("ALTER TABLE " + SIMINFO_TABLE + " ADD COLUMN "
+                            + SubscriptionManager.WFC_IMS_ROAMING_ENABLED + " INTEGER DEFAULT -1;");
+                } catch (SQLiteException e) {
+                    if (DBG) {
+                        log("onUpgrade skipping " + CARRIERS_TABLE + " upgrade. " +
+                                "The table will get created in onOpen.");
+                    }
+                }
+                oldVersion = 22 << 16 | 6;
+            }
+            if (oldVersion < (23 << 16 | 6)) {
+                try {
                     db.execSQL("ALTER TABLE " + CARRIERS_TABLE + " ADD COLUMN " +
                             OWNED_BY + " INTEGER DEFAULT " + OWNED_BY_OTHERS + ";");
                 } catch (SQLiteException e) {
@@ -916,7 +950,7 @@
                                 "The table will get created in onOpen.");
                     }
                 }
-                oldVersion = 22 << 16 | 6;
+                oldVersion = 23 << 16 | 6;
             }
             if (DBG) {
                 log("dbh.onUpgrade:- db=" + db + " oldV=" + oldVersion + " newV=" + newVersion);
@@ -1054,9 +1088,9 @@
             whereArgs[i++] = values.containsKey(TYPE) ?
                     values.getAsString(TYPE) : "";
             whereArgs[i++] = values.containsKey(PROTOCOL) ?
-                    values.getAsString(PROTOCOL) : "IP";
+                    values.getAsString(PROTOCOL) : DEFAULT_PROTOCOL;
             whereArgs[i++] = values.containsKey(ROAMING_PROTOCOL) ?
-                    values.getAsString(ROAMING_PROTOCOL) : "IP";
+                    values.getAsString(ROAMING_PROTOCOL) : DEFAULT_ROAMING_PROTOCOL;
 
             if (values.containsKey(CARRIER_ENABLED) &&
                     (values.getAsString(CARRIER_ENABLED).
@@ -1901,6 +1935,7 @@
         SQLiteDatabase db = getWritableDatabase();
         // query all unique fields from id
         String[] proj = CARRIERS_UNIQUE_FIELDS.toArray(new String[CARRIERS_UNIQUE_FIELDS.size()]);
+
         Cursor c = db.query(CARRIERS_TABLE, proj, "_id=" + id, null, null, null, null);
         if (c != null) {
             if (c.getCount() == 1) {
@@ -2557,6 +2592,21 @@
                 count = db.updateWithOnConflict(CARRIERS_TABLE, values,
                         _ID + "=?" + " and " + NOT_OWNED_BY_DPC,
                         new String[] { url.getLastPathSegment() }, SQLiteDatabase.CONFLICT_REPLACE);
+                try {
+                    count = db.updateWithOnConflict(CARRIERS_TABLE, values,
+                        _ID + "=?" + " and " + NOT_OWNED_BY_DPC,
+                        new String[] { url.getLastPathSegment() }, SQLiteDatabase.CONFLICT_ABORT);
+                } catch (SQLException e) {
+                    // Update failed which could be due to a conflict. Check if that is
+                    // the case and merge the entries
+                    Cursor oldRow = DatabaseHelper.selectConflictingRow(db, CARRIERS_TABLE, values);
+                    if (oldRow != null) {
+                        ContentValues mergedValues = new ContentValues();
+                        DatabaseHelper.mergeFieldsAndUpdateDb(db, CARRIERS_TABLE, oldRow, values,
+                                mergedValues, false, getContext());
+                        oldRow.close();
+                    }
+                }
                 break;
             }