Merge "SubId are Integers." into lmp-mr1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4c7f558..5701dfb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -180,7 +180,7 @@
<!-- Cell Broadcast settings title. [CHAR LIMIT=50] -->
<string name="cell_broadcast_settings">Emergency broadcasts</string>
<!-- Call settings screen title -->
- <string name="call_settings">Call Settings</string>
+ <string name="call_settings">Call settings</string>
<!-- GSM Call settings screen, setting option name -->
<string name="additional_gsm_call_settings">Additional settings</string>
<!-- GSM-only Call settings screen, setting option name-->
@@ -260,6 +260,8 @@
<!-- Title of the progress dialog displayed while updating Call settings -->
<string name="updating_title">Call settings</string>
+ <!-- Title of the "Call settings" settings screen, with a text label identifying which SIM the settings are for. -->
+ <string name="call_settings_with_label">Call settings (<xliff:g id="subscriptionlabel" example="Verizon">%s</xliff:g>)</string>
<!-- Title of the alert dialog displayed if an error occurs while updating Call settings -->
<string name="error_updating_title">Call settings error</string>
<!-- Toast in Call settings dialog while settings are being read -->
@@ -688,11 +690,17 @@
<string name="carrier_settings_title">Carrier settings</string>
<!-- FDN settings strings -->
- <!-- Call settings screen, setting option name -->
+ <!-- Label for "Fixed Dialing Number" settings in call settings. -->
<string name="fdn">Fixed Dialing Numbers</string>
- <!-- Call settings screen, button label that takes you to
- the Fixed Dialing Number management screen -->
+ <!-- Title for "Fixed Dialing Number" settings, with a label to identify the SIM the settings
+ apply to. -->
+ <string name="fdn_with_label">Fixed Dialing Numbers (<xliff:g id="subscriptionlabel" example="Verizon">%s</xliff:g>)</string>
+
+ <!-- Call settings screen, button label that takes you to the Fixed Dialing Number management screen -->
<string name="manage_fdn_list">FDN list</string>
+ <!-- Title for settings screen to manage Fixed Dialing Number contacts, with a label to identify
+ the SIM the settings apply to. -->
+ <string name="fdn_list_with_label">FDN list (<xliff:g id="subscriptionlabel" example="Verizon">%s</xliff:g>)</string>
<!-- Call settings screen, preference item label -->
<string name="fdn_activation">FDN activation</string>
<!-- Call settings setting option name when FDN is enabled -->
@@ -854,9 +862,6 @@
<!-- SIM PIN screen: button label -->
<string name="doneButton">Done</string>
- <!-- In-call screen: status label for a conference call -->
- <string name="caller_manage_header">Conference call <xliff:g id="conf_call_time">%s</xliff:g></string>
-
<!-- Used in FakePhoneActivity test code. DO NOT TRANSLATE. -->
<string name="fake_phone_activity_phoneNumber_text" translatable="false">(650) 555-1234</string>
<!-- Used in FakePhoneActivity test code. DO NOT TRANSLATE. -->
@@ -884,9 +889,6 @@
<string name="card_title_hanging_up">Hanging up</string>
<!-- In-call screen: status label for a call that's in CDMA flash mode -->
<string name="card_title_in_call">In call</string>
- <!-- In-call screen: special status label that shows your own phone
- number during emergency callback mode (ECM) [CHAR LIMIT=30] -->
- <string name="card_title_my_phone_number">My number is <xliff:g id="my_phone_number">%s</xliff:g></string>
<!-- Notification strings -->
<!-- The "label" of the in-call Notification for a dialing call, used
diff --git a/res/xml/call_feature_setting.xml b/res/xml/call_feature_setting.xml
index bcda6b0..0182ac0 100644
--- a/res/xml/call_feature_setting.xml
+++ b/res/xml/call_feature_setting.xml
@@ -15,7 +15,7 @@
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
- android:title="@string/updating_title">
+ android:title="@string/call_settings">
<PreferenceScreen
android:key="phone_account_settings_preference_screen"
@@ -81,13 +81,7 @@
<PreferenceScreen
android:key="button_fdn_key"
android:title="@string/fdn"
- android:persistent="false">
-
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.phone"
- android:targetClass="com.android.phone.settings.fdn.FdnSetting" />
-
- </PreferenceScreen>
+ android:persistent="false" />
<CheckBoxPreference
android:key="button_enable_video_calling"
diff --git a/res/xml/fdn_setting.xml b/res/xml/fdn_setting.xml
index d03cf7c..7501dc8 100644
--- a/res/xml/fdn_setting.xml
+++ b/res/xml/fdn_setting.xml
@@ -30,17 +30,12 @@
android:summary="@string/sum_fdn_change_pin"
android:persistent="false"/>
+ <!-- The intent to launch the FDN List is set on this PreferenceScreen in FdnSetting, so that
+ its extras can be dynamically changed to include subscription information. -->
<PreferenceScreen
- android:key="button_fdn_list_key"
+ android:key="fdn_list_pref_screen_key"
android:title="@string/manage_fdn_list"
android:summary="@string/sum_fdn_manage_list"
- android:persistent="false">
-
- <!-- Intent to lauch the FDN list. -->
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.phone"
- android:targetClass="com.android.phone.settings.fdn.FdnList" />
-
- </PreferenceScreen>
+ android:persistent="false"/>
</PreferenceScreen>
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index d56a274..f996922 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -57,16 +57,18 @@
import com.android.ims.ImsManager;
import com.android.internal.telephony.CallForwardInfo;
-import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.phone.common.util.SettingsUtil;
import com.android.phone.settings.AccountSelectionPreference;
+import com.android.phone.settings.CallForwardInfoUtil;
import com.android.phone.settings.VoicemailProviderSettings;
import com.android.phone.settings.VoicemailProviderSettingsUtil;
+import com.android.phone.settings.fdn.FdnSetting;
import com.android.services.telephony.sip.SipUtil;
import java.lang.String;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -114,13 +116,6 @@
// to trigger its configuration UI
public static final String ACTION_CONFIGURE_VOICEMAIL =
"com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
- // Extra on intent to Call Settings containing the id of the subscription to modify.
- public static final String SUB_ID_EXTRA =
- "com.android.phone.CallFeaturesSetting.SubscriptionId";
- // Extra on intent to Call Settings containing the label of the subscription to modify.
- public static final String SUB_LABEL_EXTRA =
- "com.android.phone.CallFeaturesSetting.SubscriptionLabel";
-
// Extra put in the return from VM provider config containing voicemail number to set
public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
// Extra put in the return from VM provider config containing call forwarding number to set
@@ -206,25 +201,12 @@
private static final int VOICEMAIL_FWD_READING_DIALOG = 602;
private static final int VOICEMAIL_REVERTING_DIALOG = 603;
- // status message sent back from handlers
- private static final int MSG_OK = 100;
-
- // special statuses for voicemail controls.
- private static final int MSG_VM_EXCEPTION = 400;
- private static final int MSG_FW_SET_EXCEPTION = 401;
- private static final int MSG_FW_GET_EXCEPTION = 402;
- private static final int MSG_VM_OK = 600;
- private static final int MSG_VM_NOCHANGE = 700;
-
- /**
- * @see CallForwardInfo#status
- */
- private static final int CALL_FORWARD_INFO_INACTIVE_STATUS = 0;
-
// voicemail notification vibration string constants
private static final String VOICEMAIL_VIBRATION_ALWAYS = "always";
private static final String VOICEMAIL_VIBRATION_NEVER = "never";
+ private SubscriptionInfoHelper mSubscriptionInfoHelper;
+
private EditPhoneNumberPreference mSubMenuVoicemailSettings;
/** Whether dialpad plays DTMF tone or not. */
@@ -240,12 +222,17 @@
private CheckBoxPreference mEnableVideoCalling;
private class VoiceMailProvider {
+ public String name;
+ public Intent intent;
+
public VoiceMailProvider(String name, Intent intent) {
this.name = name;
this.intent = intent;
}
- public String name;
- public Intent intent;
+
+ public String toString() {
+ return "[ Name: " + name + ", Intent: " + intent + " ]";
+ }
}
/**
@@ -576,24 +563,16 @@
Log.i(LOG_TAG, "Requested to rollback Fwd changes.");
final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
if (prevFwdSettings != null) {
- Map<Integer, AsyncResult> results =
- mForwardingChangeResults;
+ Map<Integer, AsyncResult> results = mForwardingChangeResults;
resetForwardingChangeState();
for (int i = 0; i < prevFwdSettings.length; i++) {
CallForwardInfo fi = prevFwdSettings[i];
if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
- // Only revert the settings for which the update
- // succeeded
+ // Only revert the settings for which the update succeeded.
AsyncResult result = results.get(fi.reason);
if (result != null && result.exception == null) {
mExpectedChangeResultReasons.add(fi.reason);
- mPhone.setCallForwardingOption(
- (fi.status == 1 ?
- CommandsInterface.CF_ACTION_REGISTRATION :
- CommandsInterface.CF_ACTION_DISABLE),
- fi.reason,
- fi.number,
- fi.timeSeconds,
+ CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
mRevertOptionComplete.obtainMessage(
EVENT_FORWARDING_CHANGED, i, 0));
}
@@ -613,7 +592,7 @@
updateVMPreferenceWidgets(mPreviousVMProviderKey);
updateVoiceNumberField();
if (mVMOrFwdSetError != 0) {
- showVMDialog(mVMOrFwdSetError);
+ showDialogIfForeground(mVMOrFwdSetError);
mVMOrFwdSetError = 0;
}
}
@@ -739,6 +718,9 @@
// actual work to handle these events whether or not we're in the
// foreground (see the Handler code in mSetOptionComplete for
// example.)
+ //
+ // TODO: It's a bit worrisome that we don't do anything in error cases when we're not in the
+ // foreground. Consider displaying a toast instead.
private void showDialogIfForeground(int id) {
if (mForeground) {
showDialog(id);
@@ -778,7 +760,7 @@
// Throw a warning if the voicemail is the same and we did not change forwarding.
if (mNewVMNumber.equals(mOldVmNumber)
&& mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
- showVMDialog(MSG_VM_NOCHANGE);
+ showDialogIfForeground(VM_NOCHANGE_ERROR);
return;
}
@@ -819,14 +801,12 @@
if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
Throwable error = null;
if (ar.exception != null) {
- if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" +
- ar.exception.getMessage());
error = ar.exception;
+ if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" + error.getMessage());
}
if (ar.userObj instanceof Throwable) {
- if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" +
- ((Throwable)ar.userObj).getMessage());
- error = (Throwable)ar.userObj;
+ error = (Throwable) ar.userObj;
+ if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" + error.getMessage());
}
// We may have already gotten an error and decided to ignore the other results.
@@ -840,37 +820,14 @@
if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
mForwardingReadResults = null;
dismissDialogSafely(VOICEMAIL_FWD_READING_DIALOG);
- showVMDialog(MSG_FW_GET_EXCEPTION);
+ showDialogIfForeground(FW_GET_RESPONSE_ERROR);
return;
}
- // Get the forwarding info
- final CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result;
- CallForwardInfo fi = null;
- for (int i = 0 ; i < cfInfoArray.length; i++) {
- if ((cfInfoArray[i].serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) {
- fi = cfInfoArray[i];
- break;
- }
- }
- if (fi == null) {
-
- // In case we go nothing it means we need this reason disabled
- // so create a CallForwardInfo for capturing this
- if (DBG) Log.d(LOG_TAG, "Creating default info for " + idx);
- fi = new CallForwardInfo();
- fi.status = 0;
- fi.reason = VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx];
- fi.serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
- } else {
- // if there is not a forwarding number, ensure the entry is set to "not active."
- if (fi.number == null || fi.number.length() == 0) {
- fi.status = 0;
- }
-
- if (DBG) Log.d(LOG_TAG, "Got " + fi.toString() + " for " + idx);
- }
- mForwardingReadResults[idx] = fi;
+ // Get the forwarding info.
+ mForwardingReadResults[idx] = CallForwardInfoUtil.getCallForwardInfo(
+ (CallForwardInfo[]) ar.result,
+ VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx]);
// Check if we got all the results already
boolean done = true;
@@ -880,9 +837,11 @@
break;
}
}
+
if (done) {
if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
dismissDialogSafely(VOICEMAIL_FWD_READING_DIALOG);
+
if (mReadingSettingsForDefaultProvider) {
mVmProviderSettingsUtil.save(DEFAULT_VM_PROVIDER_KEY,
new VoicemailProviderSettings(this.mOldVmNumber, mForwardingReadResults));
@@ -893,34 +852,6 @@
if (DBG) Log.d(LOG_TAG, "Not done receiving fwd info");
}
}
-
- private CallForwardInfo infoForReason(CallForwardInfo[] infos, int reason) {
- CallForwardInfo result = null;
- if (null != infos) {
- for (CallForwardInfo info : infos) {
- if (info.reason == reason) {
- result = info;
- break;
- }
- }
- }
- return result;
- }
-
- private boolean isUpdateRequired(CallForwardInfo oldInfo, CallForwardInfo newInfo) {
- if (oldInfo == null) {
- return true;
- }
-
- // If we're disabling a type of forwarding, don't make any change if it's already disabled.
- if (newInfo.status == CALL_FORWARD_INFO_INACTIVE_STATUS
- && oldInfo.status == CALL_FORWARD_INFO_INACTIVE_STATUS) {
- return false;
- }
-
- return true;
- }
-
private void resetForwardingChangeState() {
mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
mExpectedChangeResultReasons = new HashSet<Integer>();
@@ -935,21 +866,15 @@
resetForwardingChangeState();
for (int i = 0; i < mNewFwdSettings.length; i++) {
CallForwardInfo fi = mNewFwdSettings[i];
-
- final boolean doUpdate = isUpdateRequired(infoForReason(
- mForwardingReadResults, fi.reason), fi);
+ CallForwardInfo fiForReason =
+ CallForwardInfoUtil.infoForReason(mForwardingReadResults, fi.reason);
+ final boolean doUpdate = CallForwardInfoUtil.isUpdateRequired(fiForReason, fi);
if (doUpdate) {
if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
mExpectedChangeResultReasons.add(i);
- mPhone.setCallForwardingOption(
- fi.status == 1 ?
- CommandsInterface.CF_ACTION_REGISTRATION :
- CommandsInterface.CF_ACTION_DISABLE,
- fi.reason,
- fi.number,
- fi.timeSeconds,
+ CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
mSetOptionComplete.obtainMessage(
EVENT_FORWARDING_CHANGED, fi.reason, 0));
}
@@ -1116,12 +1041,12 @@
if (DBG) log("handleSetVMMessage: set VM request complete");
if (!isFwdChangeSuccess()) {
- handleVmOrFwdSetError(MSG_FW_SET_EXCEPTION);
+ handleVmOrFwdSetError(FW_SET_RESPONSE_ERROR);
} else if (!isVmChangeSuccess()) {
- handleVmOrFwdSetError(MSG_VM_EXCEPTION);
+ handleVmOrFwdSetError(VM_RESPONSE_ERROR);
} else {
if (DBG) log("change VM success!");
- handleVmAndFwdSetSuccess(MSG_VM_OK);
+ handleVmAndFwdSetSuccess(VOICEMAIL_DIALOG_CONFIRM);
}
}
@@ -1129,18 +1054,18 @@
* Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
* changes to those settings and show "failure" dialog.
*
- * @param msgId Message ID used for the specific error case. {@link #MSG_FW_SET_EXCEPTION} or
- * {@link #MSG_VM_EXCEPTION}
+ * @param dialogId ID of the dialog to show for the specific error case. Either
+ * {@link #FW_SET_RESPONSE_ERROR} or {@link #VM_RESPONSE_ERROR}
*/
- private void handleVmOrFwdSetError(int msgId) {
+ private void handleVmOrFwdSetError(int dialogId) {
if (mChangingVMorFwdDueToProviderChange) {
- mVMOrFwdSetError = msgId;
+ mVMOrFwdSetError = dialogId;
mChangingVMorFwdDueToProviderChange = false;
switchToPreviousVoicemailProvider();
return;
}
mChangingVMorFwdDueToProviderChange = false;
- showVMDialog(msgId);
+ showDialogIfForeground(dialogId);
updateVoiceNumberField();
}
@@ -1148,14 +1073,14 @@
* Called when Voicemail Provider and its forwarding settings were successfully finished.
* This updates a bunch of variables and show "success" dialog.
*/
- private void handleVmAndFwdSetSuccess(int msg) {
+ private void handleVmAndFwdSetSuccess(int dialogId) {
if (DBG) {
log("handleVmAndFwdSetSuccess(). current voicemail provider key: "
+ getCurrentVoicemailProviderKey());
}
mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
mChangingVMorFwdDueToProviderChange = false;
- showVMDialog(msg);
+ showDialogIfForeground(dialogId);
updateVoiceNumberField();
}
@@ -1257,7 +1182,7 @@
} else if (id == VOICEMAIL_FWD_SAVING_DIALOG || id == VOICEMAIL_FWD_READING_DIALOG ||
id == VOICEMAIL_REVERTING_DIALOG) {
ProgressDialog dialog = new ProgressDialog(this);
- dialog.setTitle(getText(R.string.updating_title));
+ dialog.setTitle(getText(R.string.call_settings));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.setMessage(getText(
@@ -1310,32 +1235,6 @@
}
}
- // set the app state with optional status.
- private void showVMDialog(int msgStatus) {
- switch (msgStatus) {
- // It's a bit worrisome to punt in the error cases here when we're
- // not in the foreground; maybe toast instead?
- case MSG_VM_EXCEPTION:
- showDialogIfForeground(VM_RESPONSE_ERROR);
- break;
- case MSG_FW_SET_EXCEPTION:
- showDialogIfForeground(FW_SET_RESPONSE_ERROR);
- break;
- case MSG_FW_GET_EXCEPTION:
- showDialogIfForeground(FW_GET_RESPONSE_ERROR);
- break;
- case MSG_VM_NOCHANGE:
- showDialogIfForeground(VM_NOCHANGE_ERROR);
- break;
- case MSG_VM_OK:
- showDialogIfForeground(VOICEMAIL_DIALOG_CONFIRM);
- break;
- case MSG_OK:
- default:
- // This should never happen.
- }
- }
-
/*
* Activity class methods
*/
@@ -1352,7 +1251,11 @@
// ACTION_ADD_VOICEMAIL action.
mShowVoicemailPreference = (icicle == null) &&
getIntent().getAction().equals(ACTION_ADD_VOICEMAIL);
- }
+
+ mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
+ mSubscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResources(), R.string.call_settings_with_label);
+ }
private void initPhoneAccountPreferences() {
mPhoneAccountSettingsPreference = findPreference(PHONE_ACCOUNT_SETTINGS_KEY);
@@ -1383,6 +1286,7 @@
}
addPreferencesFromResource(R.xml.call_feature_setting);
+
initPhoneAccountPreferences();
PreferenceScreen prefSet = getPreferenceScreen();
@@ -1460,15 +1364,16 @@
}
int phoneType = mPhone.getPhoneType();
+ Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
- Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
- if (fdnButton != null) {
- prefSet.removePreference(fdnButton);
- }
+ prefSet.removePreference(fdnButton);
+
if (!getResources().getBoolean(R.bool.config_voice_privacy_disable)) {
addPreferencesFromResource(R.xml.cdma_call_privacy);
}
} else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
+ fdnButton.setIntent(mSubscriptionInfoHelper.getIntent(this, FdnSetting.class));
+
if (getResources().getBoolean(R.bool.config_additional_call_setting)) {
addPreferencesFromResource(R.xml.gsm_umts_call_options);
}
@@ -1635,81 +1540,59 @@
if (DBG) log("initVoiceMailProviders()");
String providerToIgnore = null;
- if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
- if (getIntent().hasExtra(IGNORE_PROVIDER_EXTRA)) {
- providerToIgnore = getIntent().getStringExtra(IGNORE_PROVIDER_EXTRA);
- }
- if (DBG) log("Found ACTION_ADD_VOICEMAIL. providerToIgnore=" + providerToIgnore);
- if (providerToIgnore != null) {
- // IGNORE_PROVIDER_EXTRA implies we want to remove the choice from the list.
+ if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)
+ && getIntent().hasExtra(IGNORE_PROVIDER_EXTRA)) {
+ providerToIgnore = getIntent().getStringExtra(IGNORE_PROVIDER_EXTRA);
+ // Remove this provider from the list.
+ if (!TextUtils.isEmpty(providerToIgnore)) {
+ if (DBG) log("Found ACTION_ADD_VOICEMAIL. providerToIgnore= " + providerToIgnore);
mVmProviderSettingsUtil.delete(providerToIgnore);
}
}
mVMProvidersData.clear();
- // Stick the default element which is always there
+ List<String> entries = new ArrayList<String>();
+ List<String> values = new ArrayList<String>();
+
+ // Add default voicemail provider.
final String myCarrier = getString(R.string.voicemail_default);
mVMProvidersData.put(DEFAULT_VM_PROVIDER_KEY, new VoiceMailProvider(myCarrier, null));
+ entries.add(myCarrier);
+ values.add(DEFAULT_VM_PROVIDER_KEY);
- // Enumerate providers
+ // Add other voicemail providers.
PackageManager pm = getPackageManager();
- Intent intent = new Intent();
- intent.setAction(ACTION_CONFIGURE_VOICEMAIL);
+ Intent intent = new Intent(ACTION_CONFIGURE_VOICEMAIL);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
- int len = resolveInfos.size() + 1; // +1 for the default choice we will insert.
-
- // Go through the list of discovered providers populating the data map
- // skip the provider we were instructed to ignore if there was one
for (int i = 0; i < resolveInfos.size(); i++) {
final ResolveInfo ri= resolveInfos.get(i);
final ActivityInfo currentActivityInfo = ri.activityInfo;
final String key = currentActivityInfo.name;
+
if (key.equals(providerToIgnore)) {
- if (DBG) log("Ignoring key: " + key);
- len--;
continue;
}
+
if (DBG) log("Loading key: " + key);
final String nameForDisplay = ri.loadLabel(pm).toString();
Intent providerIntent = new Intent();
providerIntent.setAction(ACTION_CONFIGURE_VOICEMAIL);
- providerIntent.setClassName(currentActivityInfo.packageName,
- currentActivityInfo.name);
- if (DBG) {
- log("Store loaded VoiceMailProvider. key: " + key
- + " -> name: " + nameForDisplay + ", intent: " + providerIntent);
- }
- mVMProvidersData.put(
- key,
- new VoiceMailProvider(nameForDisplay, providerIntent));
+ providerIntent.setClassName(currentActivityInfo.packageName, currentActivityInfo.name);
+ VoiceMailProvider vmProvider = new VoiceMailProvider(nameForDisplay, providerIntent);
+ if (DBG) log("Store VoiceMailProvider. Key: " + key + " -> " + vmProvider.toString());
+ mVMProvidersData.put(key, vmProvider);
+ entries.add(vmProvider.name);
+ values.add(key);
}
- // Now we know which providers to display - create entries and values array for
- // the list preference
- String [] entries = new String [len];
- String [] values = new String [len];
- entries[0] = myCarrier;
- values[0] = DEFAULT_VM_PROVIDER_KEY;
- int entryIdx = 1;
- for (int i = 0; i < resolveInfos.size(); i++) {
- final String key = resolveInfos.get(i).activityInfo.name;
- if (!mVMProvidersData.containsKey(key)) {
- continue;
- }
- entries[entryIdx] = mVMProvidersData.get(key).name;
- values[entryIdx] = key;
- entryIdx++;
- }
+ mVoicemailProviders.setEntries(entries.toArray(new String[0]));
+ mVoicemailProviders.setEntryValues(values.toArray(new String[0]));
- // ListPreference is now updated.
- mVoicemailProviders.setEntries(entries);
- mVoicemailProviders.setEntryValues(values);
-
- // Remember the current Voicemail Provider key as a "previous" key. This will be used
- // when we fail to update Voicemail Provider, which requires rollback.
- // We will update this when the VM Provider setting is successfully updated.
+ // Remember the current Voicemail Provider key as a "previous" key. This will be used when
+ // we fail to update Voicemail Provider, which requires rollback. We will update this when
+ // the VM Provider setting is successfully updated.
mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
if (DBG) log("Set up the first mPreviousVMProviderKey: " + mPreviousVMProviderKey);
diff --git a/src/com/android/phone/SubscriptionInfoHelper.java b/src/com/android/phone/SubscriptionInfoHelper.java
new file mode 100644
index 0000000..926a156
--- /dev/null
+++ b/src/com/android/phone/SubscriptionInfoHelper.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright (C) 2014 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
+ */
+
+package com.android.phone;
+
+import android.app.ActionBar;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.telephony.SubInfoRecord;
+import android.telephony.SubscriptionManager;
+import android.text.TextUtils;
+
+import com.android.phone.PhoneGlobals;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+/**
+ * Helper for manipulating intents or components with subscription-related information.
+ *
+ * In settings, subscription ids and labels are passed along to indicate that settings
+ * are being changed for particular subscriptions. This helper provides functions for
+ * helping extract this info and perform common operations using this info.
+ */
+public class SubscriptionInfoHelper {
+ private static final int NO_SUB_ID = -1;
+
+ // Extra on intent containing the id of a subscription.
+ private static final String SUB_ID_EXTRA =
+ "com.android.phone.settings.SubscriptionInfoHelper.SubscriptionId";
+ // Extra on intent containing the label of a subscription.
+ private static final String SUB_LABEL_EXTRA =
+ "com.android.phone.settings.SubscriptionInfoHelper.SubscriptionLabel";
+
+ private static int mSubId = NO_SUB_ID;
+ private static String mSubLabel;
+
+ /**
+ * Instantiates the helper, by extracting the subscription id and label from the intent.
+ */
+ public SubscriptionInfoHelper(Intent intent) {
+ mSubId = intent.getIntExtra(SUB_ID_EXTRA, NO_SUB_ID);
+ mSubLabel = intent.getStringExtra(SUB_LABEL_EXTRA);
+ }
+
+ /**
+ * @param context The context.
+ * @param newActivityClass The class of the activity for the intent to start.
+ * @return Intent containing extras for the subscription id and label if they exist.
+ */
+ public Intent getIntent(Context context, Class newActivityClass) {
+ Intent intent = new Intent(context, newActivityClass);
+
+ if (hasSubId()) {
+ intent.putExtra(SUB_ID_EXTRA, mSubId);
+ }
+
+ if (!TextUtils.isEmpty(mSubLabel)) {
+ intent.putExtra(SUB_LABEL_EXTRA, mSubLabel);
+ }
+
+ return intent;
+ }
+
+ public static void addExtrasToIntent(Intent intent, SubInfoRecord subscription) {
+ intent.putExtra(SubscriptionInfoHelper.SUB_ID_EXTRA, subscription.getSubscriptionId());
+ intent.putExtra(
+ SubscriptionInfoHelper.SUB_LABEL_EXTRA, subscription.getDisplayName().toString());
+ }
+
+ /**
+ * @return Phone object. If a subscription id exists, it returns the phone for the id.
+ */
+ public Phone getPhone() {
+ return hasSubId()
+ ? PhoneFactory.getPhone(SubscriptionManager.getPhoneId(mSubId))
+ : PhoneGlobals.getPhone();
+ }
+
+ /**
+ * Sets the action bar title to the string specified by the given resource id, formatting
+ * it with the subscription label. This assumes the resource string is formattable with a
+ * string-type specifier.
+ *
+ * If the subscription label does not exists, leave the existing title.
+ */
+ public void setActionBarTitle(ActionBar actionBar, Resources res, int resId) {
+ if (actionBar == null || TextUtils.isEmpty(mSubLabel)) {
+ return;
+ }
+
+ String title = String.format(res.getString(resId), mSubLabel);
+ actionBar.setTitle(title);
+ }
+
+ public boolean hasSubId() {
+ return mSubId != NO_SUB_ID;
+ }
+
+ public int getSubId() {
+ return mSubId;
+ }
+}
diff --git a/src/com/android/phone/settings/CallForwardInfoUtil.java b/src/com/android/phone/settings/CallForwardInfoUtil.java
new file mode 100644
index 0000000..1983fab
--- /dev/null
+++ b/src/com/android/phone/settings/CallForwardInfoUtil.java
@@ -0,0 +1,129 @@
+/**
+ * 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.
+ */
+
+package com.android.phone.settings;
+
+import android.os.Message;
+import android.util.Log;
+
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+import com.android.phone.PhoneGlobals;
+
+public class CallForwardInfoUtil {
+ private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+ private static final String LOG_TAG = CallForwardInfoUtil.class.getSimpleName();
+
+ /**
+ * @see CallForwardInfo#status
+ */
+ private static final int CALL_FORWARD_INFO_INACTIVE_STATUS = 0;
+ private static final int CALL_FORWARD_INFO_ACTIVE_STATUS = 1;
+
+ /**
+ * Returns the first CallForwardInfo in infos which has the specified reason.
+ * @param infos array of CallForwardInfo objects.
+ * @param reason The reason we want to find a CallForwardInfo for.
+ */
+ public static CallForwardInfo infoForReason(CallForwardInfo[] infos, int reason) {
+ if (infos == null) {
+ return null;
+ }
+
+ CallForwardInfo result = null;
+ for (int i = 0; i < infos.length; i++) {
+ if (infos[i].reason == reason) {
+ return infos[i];
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Update, unless we're disabling a type of forwarding and it's already disabled.
+ */
+ public static boolean isUpdateRequired(CallForwardInfo oldInfo, CallForwardInfo newInfo) {
+ if (oldInfo == null) {
+ return true;
+ }
+
+ if (newInfo.status == CALL_FORWARD_INFO_INACTIVE_STATUS
+ && oldInfo.status == CALL_FORWARD_INFO_INACTIVE_STATUS) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the call forwarding option on the phone, with the command interface action set to the
+ * appropriate value depending on whether the CallForwardInfo is active or inactive.
+ */
+ public static void setCallForwardingOption(Phone phone, CallForwardInfo info, Message message) {
+ int commandInterfaceCfAction = info.status == CALL_FORWARD_INFO_ACTIVE_STATUS
+ ? CommandsInterface.CF_ACTION_REGISTRATION
+ : CommandsInterface.CF_ACTION_DISABLE;
+
+ phone.setCallForwardingOption(commandInterfaceCfAction,
+ info.reason,
+ info.number,
+ info.timeSeconds,
+ message);
+ }
+
+ /**
+ * Retrieves a CallForwardInfo object of type {@link CommandInterface.SERVICE_CLASS_VOICE} from
+ * the array of CallForwardInfo objects. If one does not exist, instantiates an CallForwardInfo
+ * object which disables the specified reason.
+ */
+ public static CallForwardInfo getCallForwardInfo(CallForwardInfo[] infos, int reason) {
+ CallForwardInfo info = null;
+ for (int i = 0 ; i < infos.length; i++) {
+ if (isServiceClassVoice(infos[i])) {
+ info = infos[i];
+ break;
+ }
+ }
+
+ if (info == null) {
+ // If there is no info, create a CallForwardInfo to disable this reason.
+ info = new CallForwardInfo();
+ info.status = CALL_FORWARD_INFO_INACTIVE_STATUS;
+ info.reason = reason;
+ info.serviceClass = CommandsInterface.SERVICE_CLASS_VOICE;
+
+ if (DBG) Log.d(LOG_TAG, "Created default info for reason: " + reason);
+ } else {
+ if (!hasForwardingNumber(info)) {
+ info.status = CALL_FORWARD_INFO_INACTIVE_STATUS;
+ }
+
+ if (DBG) Log.d(LOG_TAG, "Retrieved " + info.toString() + " for " + reason);
+ }
+
+ return info;
+ }
+
+ private static boolean isServiceClassVoice(CallForwardInfo info) {
+ return (info.serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0;
+ }
+
+ private static boolean hasForwardingNumber(CallForwardInfo info) {
+ return info.number != null && info.number.length() > 0;
+ }
+}
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 09083ac..6f436fd 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -19,6 +19,7 @@
import com.android.phone.R;
import com.android.phone.CallFeaturesSetting;
+import com.android.phone.SubscriptionInfoHelper;
import com.android.services.telephony.sip.SipAccountRegistry;
import com.android.services.telephony.sip.SipSharedPreferences;
import com.android.services.telephony.sip.SipUtil;
@@ -294,8 +295,8 @@
for (SubInfoRecord subscription : SubscriptionManager.getActiveSubInfoList()) {
CharSequence label = subscription.getDisplayName();
Intent intent = new Intent(TelecomManager.ACTION_SHOW_CALL_SETTINGS);
- intent.putExtra(CallFeaturesSetting.SUB_ID_EXTRA, subscription.getSubscriptionId());
- intent.putExtra(CallFeaturesSetting.SUB_LABEL_EXTRA, label);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ SubscriptionInfoHelper.addExtrasToIntent(intent, subscription);
Preference accountPreference = new Preference(mApplicationContext);
accountPreference.setTitle(label);
diff --git a/src/com/android/phone/settings/fdn/DeleteFdnContactScreen.java b/src/com/android/phone/settings/fdn/DeleteFdnContactScreen.java
index c0fc1e8..d54de43 100644
--- a/src/com/android/phone/settings/fdn/DeleteFdnContactScreen.java
+++ b/src/com/android/phone/settings/fdn/DeleteFdnContactScreen.java
@@ -31,6 +31,7 @@
import com.android.phone.PhoneGlobals;
import com.android.phone.R;
+import com.android.phone.SubscriptionInfoHelper;
import static android.view.Window.PROGRESS_VISIBILITY_OFF;
import static android.view.Window.PROGRESS_VISIBILITY_ON;
@@ -47,6 +48,8 @@
private static final int PIN2_REQUEST_CODE = 100;
+ private SubscriptionInfoHelper mSubscriptionInfoHelper;
+
private String mName;
private String mNumber;
private String mPin2;
@@ -92,6 +95,8 @@
private void resolveIntent() {
Intent intent = getIntent();
+ mSubscriptionInfoHelper = new SubscriptionInfoHelper(intent);
+
mName = intent.getStringExtra(INTENT_EXTRA_NAME);
mNumber = intent.getStringExtra(INTENT_EXTRA_NUMBER);
@@ -114,7 +119,7 @@
buf.append(mPin2);
buf.append("'");
- Uri uri = Uri.parse("content://icc/fdn");
+ Uri uri = FdnList.getContentUri(mSubscriptionInfoHelper);
mQueryHandler = new QueryHandler(getContentResolver());
mQueryHandler.startDelete(0, null, uri, buf.toString(), null);
@@ -124,6 +129,7 @@
private void authenticatePin2() {
Intent intent = new Intent();
intent.setClass(this, GetPin2Screen.class);
+ intent.setData(FdnList.getContentUri(mSubscriptionInfoHelper));
startActivityForResult(intent, PIN2_REQUEST_CODE);
}
diff --git a/src/com/android/phone/settings/fdn/EditFdnContactScreen.java b/src/com/android/phone/settings/fdn/EditFdnContactScreen.java
index 3064a7a..944eaad 100644
--- a/src/com/android/phone/settings/fdn/EditFdnContactScreen.java
+++ b/src/com/android/phone/settings/fdn/EditFdnContactScreen.java
@@ -49,6 +49,7 @@
import com.android.phone.PhoneGlobals;
import com.android.phone.R;
+import com.android.phone.SubscriptionInfoHelper;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
@@ -68,6 +69,8 @@
private static final int PIN2_REQUEST_CODE = 100;
+ private SubscriptionInfoHelper mSubscriptionInfoHelper;
+
private String mName;
private String mNumber;
private String mPin2;
@@ -107,8 +110,7 @@
getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.edit_fdn_contact_screen);
setupView();
- setTitle(mAddContact ?
- R.string.add_fdn_contact : R.string.edit_fdn_contact);
+ setTitle(mAddContact ? R.string.add_fdn_contact : R.string.edit_fdn_contact);
displayProgress(false);
}
@@ -214,6 +216,8 @@
private void resolveIntent() {
Intent intent = getIntent();
+ mSubscriptionInfoHelper = new SubscriptionInfoHelper(intent);
+
mName = intent.getStringExtra(INTENT_EXTRA_NAME);
mNumber = intent.getStringExtra(INTENT_EXTRA_NUMBER);
@@ -266,10 +270,6 @@
return mNumberField.getText().toString();
}
- private Uri getContentURI() {
- return Uri.parse("content://icc/fdn");
- }
-
/**
* @param number is voice mail number
* @return true if number length is less than 20-digit limit
@@ -291,7 +291,7 @@
return;
}
- Uri uri = getContentURI();
+ Uri uri = FdnList.getContentUri(mSubscriptionInfoHelper);
ContentValues bundle = new ContentValues(3);
bundle.put("tag", getNameFromTextField());
@@ -314,7 +314,7 @@
handleResult(false, true);
return;
}
- Uri uri = getContentURI();
+ Uri uri = FdnList.getContentUri(mSubscriptionInfoHelper);
ContentValues bundle = new ContentValues();
bundle.put("tag", mName);
@@ -335,8 +335,7 @@
private void deleteSelected() {
// delete ONLY if this is NOT a new contact.
if (!mAddContact) {
- Intent intent = new Intent();
- intent.setClass(this, DeleteFdnContactScreen.class);
+ Intent intent = mSubscriptionInfoHelper.getIntent(this, DeleteFdnContactScreen.class);
intent.putExtra(INTENT_EXTRA_NAME, mName);
intent.putExtra(INTENT_EXTRA_NUMBER, mNumber);
startActivity(intent);
@@ -347,6 +346,7 @@
private void authenticatePin2() {
Intent intent = new Intent();
intent.setClass(this, GetPin2Screen.class);
+ intent.setData(FdnList.getContentUri(mSubscriptionInfoHelper));
startActivityForResult(intent, PIN2_REQUEST_CODE);
}
diff --git a/src/com/android/phone/settings/fdn/FdnList.java b/src/com/android/phone/settings/fdn/FdnList.java
index 0f189d4..d7bfde2 100644
--- a/src/com/android/phone/settings/fdn/FdnList.java
+++ b/src/com/android/phone/settings/fdn/FdnList.java
@@ -26,8 +26,9 @@
import android.view.View;
import android.widget.ListView;
-import com.android.phone.R;
import com.android.phone.ADNList;
+import com.android.phone.R;
+import com.android.phone.SubscriptionInfoHelper;
/**
* Fixed Dialing Number (FDN) List UI for the Phone app. FDN is a feature of the service provider
@@ -41,6 +42,11 @@
private static final String INTENT_EXTRA_NAME = "name";
private static final String INTENT_EXTRA_NUMBER = "number";
+ private static final Uri FDN_CONTENT_URI = Uri.parse("content://icc/fdn");
+ private static final String FDN_CONTENT_PATH_WITH_SUB_ID = "content://icc/fdn/subId/";
+
+ private SubscriptionInfoHelper mSubscriptionInfoHelper;
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -50,12 +56,16 @@
// android.R.id.home will be triggered in onOptionsItemSelected()
actionBar.setDisplayHomeAsUpEnabled(true);
}
+
+ mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
+ mSubscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResources(), R.string.fdn_list_with_label);
}
@Override
protected Uri resolveIntent() {
Intent intent = getIntent();
- intent.setData(Uri.parse("content://icc/fdn"));
+ intent.setData(getContentUri(mSubscriptionInfoHelper));
return intent.getData();
}
@@ -91,7 +101,7 @@
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: // See ActionBar#setDisplayHomeAsUpEnabled()
- Intent intent = new Intent(this, FdnSetting.class);
+ Intent intent = mSubscriptionInfoHelper.getIntent(this, FdnSetting.class);
intent.setAction(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
@@ -121,10 +131,8 @@
}
private void addContact() {
- // if we don't put extras "name" when starting this activity, then
- // EditFdnContactScreen treats it like add contact.
- Intent intent = new Intent();
- intent.setClass(this, EditFdnContactScreen.class);
+ //If there is no INTENT_EXTRA_NAME provided, EditFdnContactScreen treats it as an "add".
+ Intent intent = mSubscriptionInfoHelper.getIntent(this, EditFdnContactScreen.class);
startActivity(intent);
}
@@ -146,8 +154,7 @@
String name = mCursor.getString(NAME_COLUMN);
String number = mCursor.getString(NUMBER_COLUMN);
- Intent intent = new Intent();
- intent.setClass(this, EditFdnContactScreen.class);
+ Intent intent = mSubscriptionInfoHelper.getIntent(this, EditFdnContactScreen.class);
intent.putExtra(INTENT_EXTRA_NAME, name);
intent.putExtra(INTENT_EXTRA_NUMBER, number);
startActivity(intent);
@@ -159,11 +166,20 @@
String name = mCursor.getString(NAME_COLUMN);
String number = mCursor.getString(NUMBER_COLUMN);
- Intent intent = new Intent();
- intent.setClass(this, DeleteFdnContactScreen.class);
+ Intent intent = mSubscriptionInfoHelper.getIntent(this, DeleteFdnContactScreen.class);
intent.putExtra(INTENT_EXTRA_NAME, name);
intent.putExtra(INTENT_EXTRA_NUMBER, number);
startActivity(intent);
}
}
+
+ /**
+ * Returns the uri for updating the ICC FDN entry, taking into account the subscription id.
+ */
+ public static Uri getContentUri(SubscriptionInfoHelper subscriptionInfoHelper) {
+ return subscriptionInfoHelper.hasSubId()
+ ? Uri.parse(FDN_CONTENT_PATH_WITH_SUB_ID + subscriptionInfoHelper.getSubId())
+ : FDN_CONTENT_URI;
+ }
+
}
diff --git a/src/com/android/phone/settings/fdn/FdnSetting.java b/src/com/android/phone/settings/fdn/FdnSetting.java
index 35e15e5..8716d37 100644
--- a/src/com/android/phone/settings/fdn/FdnSetting.java
+++ b/src/com/android/phone/settings/fdn/FdnSetting.java
@@ -35,6 +35,7 @@
import com.android.phone.CallFeaturesSetting;
import com.android.phone.PhoneGlobals;
import com.android.phone.R;
+import com.android.phone.SubscriptionInfoHelper;
/**
* FDN settings UI for the Phone app.
@@ -46,6 +47,7 @@
private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
private static final boolean DBG = false;
+ private SubscriptionInfoHelper mSubscriptionInfoHelper;
private Phone mPhone;
/**
@@ -56,10 +58,9 @@
private static final int EVENT_PIN2_CHANGE_COMPLETE = 200;
// String keys for preference lookup
- // We only care about the pin preferences here, the manage FDN contacts
- // Preference is handled solely in xml.
private static final String BUTTON_FDN_ENABLE_KEY = "button_fdn_enable_key";
private static final String BUTTON_CHANGE_PIN2_KEY = "button_change_pin2_key";
+ private static final String FDN_LIST_PREF_SCREEN_KEY = "fdn_list_pref_screen_key";
private EditPinPreference mButtonEnableFDN;
private EditPinPreference mButtonChangePin2;
@@ -454,9 +455,10 @@
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
- addPreferencesFromResource(R.xml.fdn_setting);
+ mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
+ mPhone = mSubscriptionInfoHelper.getPhone();
- mPhone = PhoneGlobals.getPhone();
+ addPreferencesFromResource(R.xml.fdn_setting);
//get UI object references
PreferenceScreen prefSet = getPreferenceScreen();
@@ -469,6 +471,10 @@
mButtonChangePin2.setOnPinEnteredListener(this);
+ PreferenceScreen fdnListPref =
+ (PreferenceScreen) prefSet.findPreference(FDN_LIST_PREF_SCREEN_KEY);
+ fdnListPref.setIntent(mSubscriptionInfoHelper.getIntent(this, FdnList.class));
+
// Only reset the pin change dialog if we're not in the middle of changing it.
if (icicle == null) {
resetPinChangeState();
@@ -485,13 +491,15 @@
if (actionBar != null) {
// android.R.id.home will be triggered in onOptionsItemSelected()
actionBar.setDisplayHomeAsUpEnabled(true);
+ mSubscriptionInfoHelper.setActionBarTitle(
+ actionBar, getResources(), R.string.fdn_with_label);
}
}
@Override
protected void onResume() {
super.onResume();
- mPhone = PhoneGlobals.getPhone();
+ mPhone = mSubscriptionInfoHelper.getPhone();
updateEnableFDN();
}
diff --git a/src/com/android/services/telephony/ConferenceParticipantConnection.java b/src/com/android/services/telephony/ConferenceParticipantConnection.java
index 7874404..e748634 100644
--- a/src/com/android/services/telephony/ConferenceParticipantConnection.java
+++ b/src/com/android/services/telephony/ConferenceParticipantConnection.java
@@ -61,6 +61,10 @@
* @param newState The new state.
*/
public void updateState(int newState) {
+ if (newState == getState()) {
+ return;
+ }
+
switch (newState) {
case STATE_INITIALIZING:
setInitializing();
@@ -78,7 +82,8 @@
setActive();
break;
case STATE_DISCONNECTED:
- setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+ setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
+ destroy();
break;
default:
setActive();
@@ -86,6 +91,21 @@
}
/**
+ * Disconnects the current {@code ConferenceParticipantConnection} from the conference.
+ * <p>
+ * Sends a participant disconnect signal to the associated parent connection. The participant
+ * connection is not disconnected and cleaned up here. On successful disconnection of the
+ * participant, the conference server will send an update to the conference controller
+ * indicating the disconnection was successful.
+ */
+ @Override
+ public void onDisconnect() {
+ Log.v(this, "onDisconnect");
+
+ mParentConnection.onDisconnectConferenceParticipant(mEndpoint);
+ }
+
+ /**
* Configures the {@link android.telecom.PhoneCapabilities} applicable to this connection. A
* conference participant can only be disconnected from a conference since there is not
* actual connection to the participant which could be split from the conference.
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index 892f3f9..43385fd 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -31,6 +31,8 @@
import android.telecom.PhoneAccountHandle;
import com.android.internal.telephony.Call;
+import com.android.internal.telephony.gsm.GsmConnection;
+import com.android.internal.telephony.imsphone.ImsPhoneConnection;
/**
* Maintains a list of all the known TelephonyConnections connections and controls GSM and
@@ -55,7 +57,7 @@
@Override
public void onDestroyed(Connection connection) {
- remove((TelephonyConnection) connection);
+ remove(connection);
}
/**
@@ -103,9 +105,15 @@
recalculate();
}
- void remove(TelephonyConnection connection) {
+ void remove(Connection connection) {
connection.removeConnectionListener(mConnectionListener);
- mTelephonyConnections.remove(connection);
+
+ if (connection instanceof ConferenceParticipantConnection) {
+ mConferenceParticipantConnections.remove(connection);
+ } else {
+ mTelephonyConnections.remove(connection);
+ }
+
recalculate();
}
@@ -185,6 +193,9 @@
private void recalculateConference() {
Set<Connection> conferencedConnections = new HashSet<>();
+ int numGsmConnections = 0;
+ int numImsConnections = 0;
+
for (TelephonyConnection connection : mTelephonyConnections) {
com.android.internal.telephony.Connection radioConnection =
connection.getOriginalConnection();
@@ -194,22 +205,30 @@
Call call = radioConnection.getCall();
if ((state == Call.State.ACTIVE || state == Call.State.HOLDING) &&
(call != null && call.isMultiparty())) {
+
+ if (radioConnection instanceof GsmConnection) {
+ numGsmConnections++;
+ } else if (radioConnection instanceof ImsPhoneConnection) {
+ numImsConnections++;
+ }
conferencedConnections.add(connection);
}
}
}
- // Include conference participants in the list of conferenced connections.
- for (ConferenceParticipantConnection participant :
- mConferenceParticipantConnections.values()) {
- conferencedConnections.add(participant);
- }
-
Log.d(this, "Recalculate conference calls %s %s.",
mTelephonyConference, conferencedConnections);
- if (conferencedConnections.size() < 2) {
- Log.d(this, "less than two conference calls!");
+ // If the number of telephony connections drops below the limit, the conference can be
+ // considered terminated.
+ // We must have less than 2 GSM connections and less than 1 IMS connection.
+ if (numGsmConnections < 2 && numImsConnections < 1) {
+ Log.d(this, "not enough connections to be a conference!");
+
+ // The underlying telephony connections have been disconnected -- disconnect the
+ // conference participants now.
+ disconnectConferenceParticipants();
+
// No more connections are conferenced, destroy any existing conference.
if (mTelephonyConference != null) {
Log.d(this, "with a conference to destroy!");
@@ -232,6 +251,17 @@
mTelephonyConference.addConnection(connection);
}
}
+
+ // Add new conference participants
+ for (Connection conferenceParticipant :
+ mConferenceParticipantConnections.values()) {
+
+ if (conferenceParticipant.getState() == Connection.STATE_ACTIVE) {
+ if (!existingConnections.contains(conferenceParticipant)) {
+ mTelephonyConference.addConnection(conferenceParticipant);
+ }
+ }
+ }
} else {
mTelephonyConference = new TelephonyConference(null);
for (Connection connection : conferencedConnections) {
@@ -239,6 +269,13 @@
mTelephonyConference, connection);
mTelephonyConference.addConnection(connection);
}
+
+ // Add the conference participants
+ for (Connection conferenceParticipant :
+ mConferenceParticipantConnections.values()) {
+ mTelephonyConference.addConnection(conferenceParticipant);
+ }
+
mConnectionService.addConference(mTelephonyConference);
}
@@ -256,6 +293,23 @@
}
/**
+ * Disconnects all conference participants from the conference.
+ */
+ private void disconnectConferenceParticipants() {
+ for (Connection connection : mConferenceParticipantConnections.values()) {
+ // Disconnect listener so that the connection doesn't fire events on the conference
+ // controller, causing a recursive call.
+ connection.removeConnectionListener(mConnectionListener);
+ mConferenceParticipantConnections.remove(connection);
+
+ // Mark disconnect cause as cancelled to ensure that the call is not logged in the
+ // call log.
+ connection.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
+ connection.destroy();
+ }
+ }
+
+ /**
* Handles state changes for a conference participant.
*
* @param parent The connection which was notified of the conference participant.
@@ -297,8 +351,8 @@
PhoneAccountHandle phoneAccountHandle =
TelecomAccountRegistry.makePstnPhoneAccountHandle(parent.getPhone());
mConnectionService.addExistingConnection(phoneAccountHandle, connection);
-
// Recalculate to add to the conference and set its state appropriately.
recalculateConference();
+ connection.updateState(participant.getState());
}
}
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 3af7481..e478d11 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -211,6 +211,23 @@
hangup(android.telephony.DisconnectCause.LOCAL);
}
+ /**
+ * Notifies this Connection of a request to disconnect a participant of the conference managed
+ * by the connection.
+ *
+ * @param endpoint the {@link Uri} of the participant to disconnect.
+ */
+ @Override
+ public void onDisconnectConferenceParticipant(Uri endpoint) {
+ Log.v(this, "onDisconnectConferenceParticipant %s", endpoint);
+
+ if (mOriginalConnection == null) {
+ return;
+ }
+
+ mOriginalConnection.onDisconnectConferenceParticipant(endpoint);
+ }
+
@Override
public void onSeparate() {
Log.v(this, "onSeparate");