Merge "Settings: Phone force close when set viocemail in speed dial settings"
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 111e263..47833ea 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -249,6 +249,8 @@
 
         Preference cdmaOptions = prefSet.findPreference(BUTTON_CDMA_OPTIONS);
         Preference gsmOptions = prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS);
+        Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
+        fdnButton.setIntent(mSubscriptionInfoHelper.getIntent(FdnSetting.class));
         if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) {
             cdmaOptions.setIntent(mSubscriptionInfoHelper.getIntent(CdmaCallOptions.class));
             gsmOptions.setIntent(mSubscriptionInfoHelper.getIntent(GsmUmtsCallOptions.class));
@@ -257,7 +259,6 @@
             prefSet.removePreference(gsmOptions);
 
             int phoneType = mPhone.getPhoneType();
-            Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
             if (carrierConfig.getBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL)) {
                 prefSet.removePreference(fdnButton);
             } else {
@@ -269,7 +270,6 @@
                         addPreferencesFromResource(R.xml.cdma_call_privacy);
                     }
                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    fdnButton.setIntent(mSubscriptionInfoHelper.getIntent(FdnSetting.class));
 
                     if (carrierConfig.getBoolean(
                             CarrierConfigManager.KEY_ADDITIONAL_CALL_SETTING_BOOL)) {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index ce840a6..da58d2b 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -83,7 +83,9 @@
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.uicc.SIMRecords;
 import com.android.internal.telephony.uicc.UiccCard;
+import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.util.HexDump;
 import com.android.phone.settings.VisualVoicemailSettingsUtil;
@@ -151,6 +153,8 @@
     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
+    private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
+    private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
 
     /** The singleton instance. */
     private static PhoneInterfaceManager sInstance;
@@ -835,6 +839,56 @@
                     }
                     break;
 
+                case EVENT_GET_FORBIDDEN_PLMNS_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null && ar.result != null) {
+                        request.result = ar.result;
+                    } else {
+                        request.result = new IllegalArgumentException(
+                                "Failed to retrieve Forbidden Plmns");
+                        if (ar.result == null) {
+                            loge("getForbiddenPlmns: Empty response");
+                        } else {
+                            loge("getForbiddenPlmns: Unknown exception");
+                        }
+                    }
+                    synchronized (request) {
+                        request.notifyAll();
+                    }
+                    break;
+
+                case CMD_GET_FORBIDDEN_PLMNS:
+                    request = (MainThreadRequest) msg.obj;
+                    uiccCard = getUiccCardFromRequest(request);
+                    if (uiccCard == null) {
+                        loge("getForbiddenPlmns() UiccCard is null");
+                        request.result = new IllegalArgumentException(
+                                "getForbiddenPlmns() UiccCard is null");
+                        synchronized (request) {
+                            request.notifyAll();
+                        }
+                        break;
+                    }
+                    Integer appType = (Integer) request.argument;
+                    UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
+                    if (uiccApp == null) {
+                        loge("getForbiddenPlmns() no app with specified type -- "
+                                + appType);
+                        request.result = new IllegalArgumentException("Failed to get UICC App");
+                        synchronized (request) {
+                            request.notifyAll();
+                        }
+                        break;
+                    } else {
+                        if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
+                                + " specified type -- " + appType);
+                    }
+                    onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
+                    ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
+                              onCompleted);
+                    break;
+
                 default:
                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
                     break;
@@ -2322,6 +2376,26 @@
         return result;
     }
 
+    /**
+     * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
+     * on a particular subscription
+     */
+    public String[] getForbiddenPlmns(int subId, int appType) {
+        mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+                "Requires READ_PRIVILEGED_PHONE_STATE");
+        if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
+            loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
+            return null;
+        }
+        Object response = sendRequest(
+            CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
+        if (response instanceof String[]) {
+            return (String[]) response;
+        }
+        // Response is an Exception of some kind, which is signalled to the user as a NULL retval
+        return null;
+    }
+
     @Override
     public String sendEnvelopeWithStatus(int subId, String content) {
         enforceModifyPermissionOrCarrierPrivilege(subId);
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index fc65616..9db20e8 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -237,6 +237,7 @@
         mPhoneAccountHandle = PhoneUtils.makePstnPhoneAccountHandle(mPhone);
         mOmtpVvmCarrierConfigHelper = new OmtpVvmCarrierConfigHelper(
                 mPhone.getContext(), mPhone.getSubId());
+        addPreferencesFromResource(R.xml.voicemail_settings);
     }
 
     @Override
@@ -244,19 +245,17 @@
         super.onResume();
         mForeground = true;
 
-        PreferenceScreen preferenceScreen = getPreferenceScreen();
-        if (preferenceScreen != null) {
-            preferenceScreen.removeAll();
-        }
-
-        addPreferencesFromResource(R.xml.voicemail_settings);
-
         PreferenceScreen prefSet = getPreferenceScreen();
 
         if (mSubMenuVoicemailSettings == null) {
             mSubMenuVoicemailSettings =
                     (EditPhoneNumberPreference) findPreference(BUTTON_VOICEMAIL_KEY);
         }
+        if (mSubMenuVoicemailSettings != null) {
+            mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
+            mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
+            mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
+        }
 
         mVoicemailProviders = (VoicemailProviderListPreference) findPreference(
                 BUTTON_VOICEMAIL_PROVIDER_KEY);
@@ -275,34 +274,36 @@
                 getResources().getString(R.string.voicemail_notification_vibrate_key));
         mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
 
-        mVoicemailVisualVoicemail = (SwitchPreference) findPreference(
+        mVoicemailVisualVoicemail = (SwitchPreference) prefSet.findPreference(
                 getResources().getString(R.string.voicemail_visual_voicemail_key));
 
-        mVoicemailChangePinPreference = findPreference(
+        mVoicemailChangePinPreference = prefSet.findPreference(
                 getResources().getString(R.string.voicemail_change_pin_key));
-        Intent changePinIntent = new Intent(new Intent(this, VoicemailChangePinActivity.class));
-        changePinIntent.putExtra(VoicemailChangePinActivity.EXTRA_PHONE_ACCOUNT_HANDLE,
-                mPhoneAccountHandle);
+        if (mVoicemailChangePinPreference != null) {
+            Intent changePinIntent = new Intent(new Intent(this, VoicemailChangePinActivity.class));
+            changePinIntent.putExtra(VoicemailChangePinActivity.EXTRA_PHONE_ACCOUNT_HANDLE,
+                    mPhoneAccountHandle);
 
-        mVoicemailChangePinPreference.setIntent(changePinIntent);
-        if (VoicemailChangePinActivity.isDefaultOldPinSet(this, mPhoneAccountHandle)) {
-            mVoicemailChangePinPreference.setTitle(R.string.voicemail_set_pin_dialog_title);
-        } else {
-            mVoicemailChangePinPreference.setTitle(R.string.voicemail_change_pin_dialog_title);
+            mVoicemailChangePinPreference.setIntent(changePinIntent);
+            if (VoicemailChangePinActivity.isDefaultOldPinSet(this, mPhoneAccountHandle)) {
+                mVoicemailChangePinPreference.setTitle(R.string.voicemail_set_pin_dialog_title);
+            } else {
+                mVoicemailChangePinPreference.setTitle(R.string.voicemail_change_pin_dialog_title);
+            }
         }
-
-        if (mOmtpVvmCarrierConfigHelper.isValid()) {
-            mVoicemailVisualVoicemail.setOnPreferenceChangeListener(this);
-            mVoicemailVisualVoicemail.setChecked(
-                    VisualVoicemailSettingsUtil.isEnabled(this, mPhoneAccountHandle));
-            if (!isVisualVoicemailActivated()) {
+        if (mVoicemailVisualVoicemail != null) {
+            if (mOmtpVvmCarrierConfigHelper.isValid()) {
+                mVoicemailVisualVoicemail.setOnPreferenceChangeListener(this);
+                mVoicemailVisualVoicemail.setChecked(
+                        VisualVoicemailSettingsUtil.isEnabled(this, mPhoneAccountHandle));
+                if (!isVisualVoicemailActivated()) {
+                    prefSet.removePreference(mVoicemailChangePinPreference);
+                }
+            } else {
+                prefSet.removePreference(mVoicemailVisualVoicemail);
                 prefSet.removePreference(mVoicemailChangePinPreference);
             }
-        } else {
-            prefSet.removePreference(mVoicemailVisualVoicemail);
-            prefSet.removePreference(mVoicemailChangePinPreference);
         }
-
         updateVMPreferenceWidgets(mVoicemailProviders.getValue());
 
         // check the intent that started this activity and pop up the voicemail
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 279f087..6e8e61a 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -42,12 +42,12 @@
 
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.GsmCdmaPhone;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.phone.MMIDialogActivity;
@@ -727,6 +727,18 @@
         try {
             if (phone != null) {
                 originalConnection = phone.dial(number, null, videoState, extras);
+
+                if (phone instanceof GsmCdmaPhone) {
+                    GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
+                    if (gsmCdmaPhone.isNotificationOfWfcCallRequired(number)) {
+                        // Send connection event to InCall UI to inform the user of the fact they
+                        // are potentially placing an international call on WFC.
+                        Log.i(this, "placeOutgoingConnection - sending international call on WFC " +
+                                "confirmation event");
+                        connection.sendConnectionEvent(
+                                TelephonyManager.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC, null);
+                    }
+                }
             }
         } catch (CallStateException e) {
             Log.e(this, e, "placeOutgoingConnection, phone.dial exception: " + e);
@@ -802,7 +814,7 @@
         Phone chosenPhone = null;
         int subId = PhoneUtils.getSubIdForPhoneAccountHandle(accountHandle);
         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            int phoneId = SubscriptionController.getInstance().getPhoneId(subId);
+            int phoneId = SubscriptionManager.getPhoneId(subId);
             chosenPhone = PhoneFactory.getPhone(phoneId);
         }
         // If this is an emergency call and the phone we originally planned to make this call