Merge "Rename PROPERTY_SHOW_CALLBACK_NUMBER" into nyc-mr1-dev
diff --git a/res/xml/vvm_config.xml b/res/xml/vvm_config.xml
index 3bfdf75..8807ca9 100644
--- a/res/xml/vvm_config.xml
+++ b/res/xml/vvm_config.xml
@@ -23,34 +23,6 @@
   </pbundle_as_map>
 
   <pbundle_as_map>
-    <!-- Orange France -->
-    <string-array name="mccmnc">
-      <item value="20801"/>
-      <item value="20802"/>
-    </string-array>
-
-    <int name="vvm_port_number_int" value="20481"/>
-    <string name="vvm_destination_number_string">21101</string>
-    <string-array name="carrier_vvm_package_name_string_array">
-      <item value="com.orange.vvm"/>
-    </string-array>
-    <string name="vvm_type_string">vvm_type_omtp</string>
-    <boolean name="vvm_cellular_data_required_bool" value="true"/>
-  </pbundle_as_map>
-
-  <pbundle_as_map>
-    <!-- Orange UK -->
-    <string-array name="mccmnc">
-      <item value="23433"/>
-      <item value="23434"/>
-    </string-array>
-
-    <int name="vvm_port_number_int" value="20481"/>
-    <string name="vvm_destination_number_string">881</string>
-    <string name="vvm_type_string">vvm_type_omtp</string>
-  </pbundle_as_map>
-
-  <pbundle_as_map>
     <!-- T-Mobile USA-->
     <string-array name="mccmnc">
       <item value="310160"/>
@@ -139,4 +111,4 @@
          one -->
     <string name="default_vmg_url">https://mobile.vzw.com/VMGIMS/VMServices</string>
   </pbundle_as_map>
-</list>
\ No newline at end of file
+</list>
diff --git a/src/com/android/phone/VoicemailStatus.java b/src/com/android/phone/VoicemailStatus.java
index 4d7d388..00130f1 100644
--- a/src/com/android/phone/VoicemailStatus.java
+++ b/src/com/android/phone/VoicemailStatus.java
@@ -83,17 +83,29 @@
             return this;
         }
 
-        public void apply() {
+        /**
+         * Apply the changes to the {@link VoicemailStatus} {@link #Editor}.
+         *
+         * @return {@code true} if the changes were successfully applied, {@code false} otherwise.
+         */
+        public boolean apply() {
             if (mPhoneAccountHandle == null) {
-                return;
+                return false;
             }
             mValues.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
                     mPhoneAccountHandle.getComponentName().flattenToString());
             mValues.put(Status.PHONE_ACCOUNT_ID, mPhoneAccountHandle.getId());
             ContentResolver contentResolver = mContext.getContentResolver();
             Uri statusUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
-            contentResolver.insert(statusUri, mValues);
+            try {
+                contentResolver.insert(statusUri, mValues);
+            } catch (IllegalArgumentException iae) {
+                VvmLog.e(TAG, "apply :: failed to insert content resolver ", iae);
+                mValues.clear();
+                return false;
+            }
             mValues.clear();
+            return true;
         }
 
         public ContentValues getValues() {
@@ -114,8 +126,9 @@
         }
 
         @Override
-        public void apply() {
+        public boolean apply() {
             // Do nothing
+            return true;
         }
 
         public void deferredApply() {
diff --git a/src/com/android/phone/settings/VoicemailChangePinActivity.java b/src/com/android/phone/settings/VoicemailChangePinActivity.java
index 74adb12..8027dc1 100644
--- a/src/com/android/phone/settings/VoicemailChangePinActivity.java
+++ b/src/com/android/phone/settings/VoicemailChangePinActivity.java
@@ -629,7 +629,12 @@
 
         private void sendResult(@ChangePinResult int result) {
             VvmLog.i(TAG, "Change PIN result: " + result);
-            mProgressDialog.dismiss();
+            if (mProgressDialog.isShowing() && !VoicemailChangePinActivity.this.isDestroyed() &&
+                    !VoicemailChangePinActivity.this.isFinishing()) {
+                mProgressDialog.dismiss();
+            } else {
+                VvmLog.i(TAG, "Dialog not visible, not dismissing");
+            }
             mHandler.obtainMessage(MESSAGE_HANDLE_RESULT, result, 0).sendToTarget();
             releaseNetwork();
         }
diff --git a/src/com/android/phone/vvm/omtp/ActivationTask.java b/src/com/android/phone/vvm/omtp/ActivationTask.java
index 9c58b95..00dd49e 100644
--- a/src/com/android/phone/vvm/omtp/ActivationTask.java
+++ b/src/com/android/phone/vvm/omtp/ActivationTask.java
@@ -62,6 +62,8 @@
 
     private static final String EXTRA_MESSAGE_DATA_BUNDLE = "extra_message_data_bundle";
 
+    public static final String EXTRA_REGISTER_CONTENT_PROVIDER = "extra_register_content_provider";
+
     @Nullable
     private static DeviceProvisionedObserver sDeviceProvisionedObserver;
 
@@ -140,6 +142,21 @@
             VoicemailStatus.disable(getContext(), phoneAccountHandle);
             return;
         }
+
+        if (mData != null && mData.getBoolean(EXTRA_REGISTER_CONTENT_PROVIDER)) {
+            // OmtmVvmCarrierConfigHelper can start the activation process; it will pass in a vvm
+            // content provider URI which we will use.  On some occasions, setting that URI will
+            // fail, so we will perform a few attempts to ensure that the vvm content provider has
+            // a good chance of being started up.
+            if (!VoicemailStatus.edit(getContext(), phoneAccountHandle)
+                    .setType(helper.getVvmType())
+                    .apply()) {
+                VvmLog.e(TAG, "Failed to configure content provider - " + helper.getVvmType());
+                fail();
+            }
+            VvmLog.i(TAG, "VVM content provider configured - " + helper.getVvmType());
+        }
+
         if (!OmtpVvmSourceManager.getInstance(getContext())
                 .isVvmSourceRegistered(phoneAccountHandle)) {
             VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(getContext(),
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
index b4fbb3f..4d6c63c 100644
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
@@ -315,14 +315,22 @@
             // Error logged in getPhoneAccountHandle().
             return;
         }
-        VoicemailStatus.edit(mContext, phoneAccountHandle)
-                .setType(getVvmType())
-                .apply();
+
+        if (mVvmType == null || mVvmType.isEmpty()) {
+            // The VVM type is invalid; we should never have gotten here in the first place since
+            // this is loaded initially in the constructor, and callers should check isValid()
+            // before trying to start activation anyways.
+            VvmLog.e(TAG, "startActivation : vvmType is null or empty for account " +
+                    phoneAccountHandle);
+            return;
+        }
 
         activateSmsFilter();
 
         if (mProtocol != null) {
-            ActivationTask.start(mContext, mSubId, null);
+            Bundle extras = new Bundle();
+            extras.putBoolean(ActivationTask.EXTRA_REGISTER_CONTENT_PROVIDER, true);
+            ActivationTask.start(mContext, mSubId, extras);
         }
     }
 
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index a445d79..ac117b3 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -973,7 +973,8 @@
     private boolean canHoldImsCalls() {
         PersistableBundle b = getCarrierConfig();
         // Return true if the CarrierConfig is unavailable
-        return b == null || b.getBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL);
+        return !doesDeviceRespectHoldCarrierConfig() || b == null ||
+                b.getBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL);
     }
 
     private PersistableBundle getCarrierConfig() {
@@ -985,6 +986,23 @@
     }
 
     /**
+     * Determines if the device will respect the value of the
+     * {@link CarrierConfigManager#KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL} configuration option.
+     *
+     * @return {@code false} if the device always supports holding IMS calls, {@code true} if it
+     *      will use {@link CarrierConfigManager#KEY_ALLOW_HOLD_IN_IMS_CALL_BOOL} to determine if
+     *      hold is supported.
+     */
+    private boolean doesDeviceRespectHoldCarrierConfig() {
+        Phone phone = getPhone();
+        if (phone == null) {
+            return true;
+        }
+        return phone.getContext().getResources().getBoolean(
+                com.android.internal.R.bool.config_device_respects_hold_carrier_config);
+    }
+
+    /**
      * Whether the connection should be treated as an emergency.
      * @return {@code true} if the connection should be treated as an emergency call based
      * on the number dialed, {@code false} otherwise.