Merge "Make add-call a global property of telecom. (3/4)" into lmp-mr1-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5701dfb..a97d7c4 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -183,6 +183,8 @@
<string name="call_settings">Call settings</string>
<!-- GSM Call settings screen, setting option name -->
<string name="additional_gsm_call_settings">Additional settings</string>
+ <!-- GSM Call settings screen, setting option name, with label identifying the SIM the settings are for. -->
+ <string name="additional_gsm_call_settings_with_label">Additional settings (<xliff:g id="subscriptionlabel" example="Verizon">%s</xliff:g>)</string>
<!-- GSM-only Call settings screen, setting option name-->
<string name="sum_gsm_call_settings">Additional GSM only call settings</string>
<!-- CDMA Call settings screen, setting option name -->
@@ -209,6 +211,8 @@
<string name="sum_cw_disabled">During a call, notify me of incoming calls</string>
<!-- Call forwarding settings screen, section heading -->
<string name="call_forwarding_settings">Call forwarding settings</string>
+ <!-- Call forwarding settings screen, section heading, with a label identifying the SIM the settings are for. -->
+ <string name="call_forwarding_settings_with_label">Call forwarding settings (<xliff:g id="subscriptionlabel" example="Verizon">%s</xliff:g>)</string>
<!-- Call settings screen, setting option name -->
<string name="labelCF">Call forwarding</string>
diff --git a/res/xml/gsm_umts_additional_options.xml b/res/xml/gsm_umts_additional_options.xml
index 19ec56b..f2234e3 100644
--- a/res/xml/gsm_umts_additional_options.xml
+++ b/res/xml/gsm_umts_additional_options.xml
@@ -21,4 +21,5 @@
android:summaryOn="@string/sum_cw_enabled"
android:summaryOff="@string/sum_cw_disabled"
android:enabled="false"/>
+
</PreferenceScreen>
diff --git a/res/xml/gsm_umts_call_options.xml b/res/xml/gsm_umts_call_options.xml
index 2f3c235..5f3dfe4 100644
--- a/res/xml/gsm_umts_call_options.xml
+++ b/res/xml/gsm_umts_call_options.xml
@@ -1,25 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
+
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:phone="http://schemas.android.com/apk/res/com.android.phone"
android:title="@string/labelGSMMore">
<PreferenceScreen
- android:key="button_cf_expand_key"
+ android:key="call_forwarding_key"
android:title="@string/labelCF"
- android:persistent="false">
-
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.phone"
- android:targetClass="com.android.phone.GsmUmtsCallForwardOptions"/>
- </PreferenceScreen>
+ android:persistent="false" />
<PreferenceScreen
- android:key="button_more_expand_key"
+ android:key="additional_gsm_call_settings_key"
android:title="@string/additional_gsm_call_settings"
- android:persistent="false">
+ android:persistent="false" />
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.phone"
- android:targetClass="com.android.phone.GsmUmtsAdditionalCallOptions"/>
- </PreferenceScreen>
</PreferenceScreen>
diff --git a/src/com/android/phone/CLIRListPreference.java b/src/com/android/phone/CLIRListPreference.java
index 198bdb0..939caf0 100644
--- a/src/com/android/phone/CLIRListPreference.java
+++ b/src/com/android/phone/CLIRListPreference.java
@@ -23,15 +23,13 @@
private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
private final MyHandler mHandler = new MyHandler();
- private final Phone mPhone;
+ private Phone mPhone;
private TimeConsumingPreferenceListener mTcpListener;
int clirArray[];
public CLIRListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
-
- mPhone = PhoneGlobals.getPhone();
}
public CLIRListPreference(Context context) {
@@ -49,7 +47,9 @@
}
}
- /* package */ void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
+ /* package */ void init(
+ TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
+ mPhone = phone;
mTcpListener = listener;
if (!skipReading) {
mPhone.getOutgoingCallerIdDisplay(mHandler.obtainMessage(MyHandler.MESSAGE_GET_CLIR,
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 5e65a4a..02bbf6d 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -163,8 +163,9 @@
private static final String BUTTON_GSM_UMTS_OPTIONS = "button_gsm_more_expand_key";
private static final String BUTTON_CDMA_OPTIONS = "button_cdma_more_expand_key";
+ private static final String CALL_FORWARDING_KEY = "call_forwarding_key";
+ private static final String ADDITIONAL_GSM_SETTINGS_KEY = "additional_gsm_call_settings_key";
- private static final String DEFAULT_OUTGOING_ACCOUNT_KEY = "default_outgoing_account";
private static final String PHONE_ACCOUNT_SETTINGS_KEY =
"phone_account_settings_preference_screen";
@@ -367,32 +368,25 @@
mAudioManager.setParameter(HAC_KEY, hac != 0 ? HAC_VAL_ON : HAC_VAL_OFF);
return true;
} else if (preference == mVoicemailSettings) {
+ if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
+
final Dialog dialog = mVoicemailSettings.getDialog();
if (dialog != null) {
dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
}
- if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
+
if (preference.getIntent() != null) {
- if (DBG) {
- log("onPreferenceTreeClick: Invoking cfg intent "
- + preference.getIntent().getPackage());
- }
+ if (DBG) log("Invoking cfg intent " + preference.getIntent().getPackage());
// onActivityResult() will be responsible for resetting some of variables.
this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
return true;
} else {
- if (DBG) {
- log("onPreferenceTreeClick:"
- + " No Intent is available. Use default behavior defined in xml.");
- }
+ if (DBG) log("onPreferenceTreeClick(). No intent; use default behavior in xml.");
- // There's no onActivityResult(), so we need to take care of some of variables
- // which should be reset here.
+ // onActivityResult() will not be called, so reset variables here.
mPreviousVMProviderKey = DEFAULT_VM_PROVIDER_KEY;
mVMProviderSettingsForced = false;
-
- // This should let the preference use default behavior in the xml.
return false;
}
} else if (preference == mVoicemailSettingsScreen) {
@@ -415,10 +409,7 @@
*/
@Override
public boolean onPreferenceChange(Preference preference, Object objValue) {
- if (DBG) {
- log("onPreferenceChange(). preference: \"" + preference + "\""
- + ", value: \"" + objValue + "\"");
- }
+ if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
if (preference == mButtonDTMF) {
int index = mButtonDTMF.findIndexOfValue((String) objValue);
@@ -428,13 +419,10 @@
handleTTYChange(preference, objValue);
} else if (preference == mVoicemailProviders) {
final String newProviderKey = (String) objValue;
- if (DBG) {
- log("Voicemail Provider changes from \"" + mPreviousVMProviderKey
- + "\" to \"" + newProviderKey + "\".");
- }
+
// If previous provider key and the new one is same, we don't need to handle it.
if (mPreviousVMProviderKey.equals(newProviderKey)) {
- if (DBG) log("No change is made toward VM provider setting.");
+ if (DBG) log("No change is made to the VM provider setting.");
return true;
}
updateVMPreferenceWidgets(newProviderKey);
@@ -479,14 +467,15 @@
return false;
}
}
- // always let the preference setting proceed.
+
+ // Always let the preference setting proceed.
return true;
}
@Override
public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
- if (DBG) log("onPreferenceClick: request preference click on dialog close: " +
- buttonClicked);
+ if (DBG) log("onDialogClosed: Button clicked is " + buttonClicked);
+
if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
return;
}
@@ -528,67 +517,60 @@
private void switchToPreviousVoicemailProvider() {
if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
- if (mPreviousVMProviderKey != null) {
- if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
- // we have to revert with carrier
- if (DBG) {
- log("Needs to rollback."
- + " mVMChangeCompletedSuccessfully=" + mVMChangeCompletedSuccessfully
- + ", mFwdChangesRequireRollback=" + mFwdChangesRequireRollback);
- }
- showDialogIfForeground(VOICEMAIL_REVERTING_DIALOG);
- final VoicemailProviderSettings prevSettings =
- mVmProviderSettingsUtil.load(mPreviousVMProviderKey);
- if (prevSettings == null) {
- // prevSettings never becomes null since it should be already loaded!
- Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
- + mPreviousVMProviderKey + "\" becomes null, which is unexpected.");
- if (DBG) {
- Log.e(LOG_TAG,
- "mVMChangeCompletedSuccessfully: " + mVMChangeCompletedSuccessfully
- + ", mFwdChangesRequireRollback: " + mFwdChangesRequireRollback);
- }
- }
- if (mVMChangeCompletedSuccessfully) {
- mNewVMNumber = prevSettings.getVoicemailNumber();
- Log.i(LOG_TAG, "VM change is already completed successfully."
- + "Have to revert VM back to " + mNewVMNumber + " again.");
- mPhone.setVoiceMailNumber(
- mPhone.getVoiceMailAlphaTag().toString(),
- mNewVMNumber,
- Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
- }
- if (mFwdChangesRequireRollback) {
- Log.i(LOG_TAG, "Requested to rollback Fwd changes.");
- final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
- if (prevFwdSettings != null) {
- 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.
- AsyncResult result = results.get(fi.reason);
- if (result != null && result.exception == null) {
- mExpectedChangeResultReasons.add(fi.reason);
- CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
- mRevertOptionComplete.obtainMessage(
- EVENT_FORWARDING_CHANGED, i, 0));
- }
+ if (mPreviousVMProviderKey == null) {
+ return;
+ }
+
+ if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
+ showDialogIfForeground(VOICEMAIL_REVERTING_DIALOG);
+ final VoicemailProviderSettings prevSettings =
+ mVmProviderSettingsUtil.load(mPreviousVMProviderKey);
+ if (prevSettings == null) {
+ Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
+ + mPreviousVMProviderKey + "\" is null but should be loaded.");
+ }
+
+ if (mVMChangeCompletedSuccessfully) {
+ mNewVMNumber = prevSettings.getVoicemailNumber();
+ Log.i(LOG_TAG, "VM change is already completed successfully."
+ + "Have to revert VM back to " + mNewVMNumber + " again.");
+ mPhone.setVoiceMailNumber(
+ mPhone.getVoiceMailAlphaTag().toString(),
+ mNewVMNumber,
+ Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
+ }
+
+ if (mFwdChangesRequireRollback) {
+ Log.i(LOG_TAG, "Requested to rollback forwarding changes.");
+
+ final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
+ if (prevFwdSettings != null) {
+ 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.
+ AsyncResult result = results.get(fi.reason);
+ if (result != null && result.exception == null) {
+ mExpectedChangeResultReasons.add(fi.reason);
+ CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
+ mRevertOptionComplete.obtainMessage(
+ EVENT_FORWARDING_CHANGED, i, 0));
}
}
}
- } else {
- if (DBG) log("No need to revert");
- onRevertDone();
}
+ } else {
+ if (DBG) log("No need to revert");
+ onRevertDone();
}
}
private void onRevertDone() {
- if (DBG) log("Flipping provider key back to " + mPreviousVMProviderKey);
- mVoicemailProviders.setValue(mPreviousVMProviderKey);
+ if (DBG) log("onRevertDone: Changing provider key back to " + mPreviousVMProviderKey);
+
updateVMPreferenceWidgets(mPreviousVMProviderKey);
updateVoiceNumberField();
if (mVMOrFwdSetError != 0) {
@@ -604,6 +586,7 @@
+ ", resultCode: " + resultCode
+ ", data: " + data);
}
+
// there are cases where the contact picker may end up sending us more than one
// request. We want to ignore the request if we're not in the correct state.
if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
@@ -646,12 +629,11 @@
}
}
if (failure) {
- if (DBG) log("Failure in return from voicemail provider");
+ if (DBG) log("Failure in return from voicemail provider.");
if (isVMProviderSettingsForced) {
switchToPreviousVoicemailProvider();
- } else {
- if (DBG) log("Not switching back the provider since this is not forced config");
}
+
return;
}
mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
@@ -661,8 +643,7 @@
// send it to the provider when it's config is invoked so it can use this as default
final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
- if (DBG) log("onActivityResult: vm provider cfg result " +
- (fwdNum != null ? "has" : " does not have") + " forwarding number");
+ if (DBG) log("onActivityResult: cfg result has forwarding number " + fwdNum);
saveVoiceMailAndForwardingNumber(getCurrentVoicemailProviderKey(),
new VoicemailProviderSettings(vmNum, fwdNum, fwdNumTime));
return;
@@ -741,15 +722,8 @@
String key, VoicemailProviderSettings newSettings) {
if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
mNewVMNumber = newSettings.getVoicemailNumber();
- // empty vm number == clearing the vm number ?
- if (mNewVMNumber == null) {
- mNewVMNumber = "";
- }
-
+ mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
mNewFwdSettings = newSettings.getForwardingSettings();
- if (DBG) log("newFwdNumber "
- + String.valueOf((mNewFwdSettings != null ? mNewFwdSettings.length : 0))
- + " settings");
// No fwd settings on CDMA
if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
@@ -799,6 +773,7 @@
private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
+
Throwable error = null;
if (ar.exception != null) {
error = ar.exception;
@@ -811,7 +786,7 @@
// We may have already gotten an error and decided to ignore the other results.
if (mForwardingReadResults == null) {
- if (DBG) Log.d(LOG_TAG, "ignoring fwd reading result: " + idx);
+ if (DBG) Log.d(LOG_TAG, "Ignoring fwd reading result: " + idx);
return;
}
@@ -848,10 +823,9 @@
mReadingSettingsForDefaultProvider = false;
}
saveVoiceMailAndForwardingNumberStage2();
- } else {
- if (DBG) Log.d(LOG_TAG, "Not done receiving fwd info");
}
}
+
private void resetForwardingChangeState() {
mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
mExpectedChangeResultReasons = new HashSet<Integer>();
@@ -888,6 +862,7 @@
private void setVMNumberWithCarrier() {
if (DBG) log("save voicemail #: " + mNewVMNumber);
+
mPhone.setVoiceMailNumber(
mPhone.getVoiceMailAlphaTag().toString(),
mNewVMNumber,
@@ -913,8 +888,6 @@
if (result.exception != null) {
Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
result.exception.getMessage());
- } else {
- if (DBG) log("Success in setting fwd# " + msg.arg1);
}
if (isForwardingCompleted()) {
if (isFwdChangeSuccess()) {
@@ -945,6 +918,7 @@
default:
// TODO: should never reach this, may want to throw exception
}
+
if (done) {
if (DBG) log("All VM provider related changes done");
if (mForwardingChangeResults != null) {
@@ -964,25 +938,25 @@
AsyncResult result = (AsyncResult) msg.obj;
switch (msg.what) {
case EVENT_VOICEMAIL_CHANGED:
- mVoicemailChangeResult = result;
if (DBG) log("VM revert complete msg");
+ mVoicemailChangeResult = result;
break;
+
case EVENT_FORWARDING_CHANGED:
+ if (DBG) log("FWD revert complete msg ");
mForwardingChangeResults.put(msg.arg1, result);
if (result.exception != null) {
if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
result.exception.getMessage());
- } else {
- if (DBG) log("Success in reverting fwd# " + msg.arg1);
}
- if (DBG) log("FWD revert complete msg ");
break;
+
default:
// TODO: should never reach this, may want to throw exception
}
- final boolean done =
- (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null) &&
- (!mFwdChangesRequireRollback || isForwardingCompleted());
+
+ final boolean done = (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null)
+ && (!mFwdChangesRequireRollback || isForwardingCompleted());
if (done) {
if (DBG) log("All VM reverts done");
dismissDialogSafely(VOICEMAIL_REVERTING_DIALOG);
@@ -1032,8 +1006,6 @@
Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + msg);
return false;
}
-
- if (DBG) log("VM change completed successfully.");
return true;
}
@@ -1045,7 +1017,6 @@
} else if (!isVmChangeSuccess()) {
handleVmOrFwdSetError(VM_RESPONSE_ERROR);
} else {
- if (DBG) log("change VM success!");
handleVmAndFwdSetSuccess(VOICEMAIL_DIALOG_CONFIRM);
}
}
@@ -1074,10 +1045,8 @@
* This updates a bunch of variables and show "success" dialog.
*/
private void handleVmAndFwdSetSuccess(int dialogId) {
- if (DBG) {
- log("handleVmAndFwdSetSuccess(). current voicemail provider key: "
- + getCurrentVoicemailProviderKey());
- }
+ if (DBG) log("handleVmAndFwdSetSuccess: key is " + getCurrentVoicemailProviderKey());
+
mPreviousVMProviderKey = getCurrentVoicemailProviderKey();
mChangingVMorFwdDueToProviderChange = false;
showDialogIfForeground(dialogId);
@@ -1196,13 +1165,11 @@
// Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
// while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
public void onClick(DialogInterface dialog, int which) {
+ if (DBG) log("onClick: button clicked is " + which);
+
dialog.dismiss();
switch (which){
- case DialogInterface.BUTTON_NEUTRAL:
- if (DBG) log("Neutral button");
- break;
case DialogInterface.BUTTON_NEGATIVE:
- if (DBG) log("Negative button");
if (mCurrentDialogId == FW_GET_RESPONSE_ERROR) {
// We failed to get current forwarding settings and the user
// does not wish to continue.
@@ -1210,7 +1177,6 @@
}
break;
case DialogInterface.BUTTON_POSITIVE:
- if (DBG) log("Positive button");
if (mCurrentDialogId == FW_GET_RESPONSE_ERROR) {
// We failed to get current forwarding settings but the user
// wishes to continue changing settings to the new vm provider
@@ -1222,6 +1188,7 @@
default:
// just let the dialog close and go back to the input
}
+
// In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
// with settings UI. If we were called to explicitly configure voice mail then
// we finish the settings activity here to come back to whatever the user was doing.
@@ -1237,8 +1204,8 @@
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
- if (DBG) log("onCreate(). Intent: " + getIntent());
- mPhone = PhoneGlobals.getPhone();
+ if (DBG) log("onCreate: Intent is " + getIntent());
+
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mVmProviderSettingsUtil = new VoicemailProviderSettingsUtil(getApplicationContext());
@@ -1250,6 +1217,7 @@
mSubscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
mSubscriptionInfoHelper.setActionBarTitle(
getActionBar(), getResources(), R.string.call_settings_with_label);
+ mPhone = mSubscriptionInfoHelper.getPhone();
}
private void initPhoneAccountPreferences() {
@@ -1265,11 +1233,6 @@
}
}
- private boolean canLaunchIntent(Intent intent) {
- PackageManager pm = getPackageManager();
- return pm.resolveActivity(intent, PackageManager.GET_ACTIVITIES) != null;
- }
-
@Override
protected void onResume() {
super.onResume();
@@ -1305,7 +1268,6 @@
(CheckBoxPreference) findPreference(BUTTON_VOICEMAIL_NOTIFICATION_VIBRATE_KEY);
initVoiceMailProviders();
-
if (getResources().getBoolean(R.bool.dtmf_type_enabled)) {
mButtonDTMF.setOnPreferenceChangeListener(this);
int dtmf = Settings.System.getInt(getContentResolver(),
@@ -1349,14 +1311,12 @@
}
if (!getResources().getBoolean(R.bool.world_phone)) {
- Preference options = prefSet.findPreference(BUTTON_CDMA_OPTIONS);
- if (options != null) {
- prefSet.removePreference(options);
- }
- options = prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS);
- if (options != null) {
- prefSet.removePreference(options);
- }
+ Preference cdmaOptions = prefSet.findPreference(BUTTON_CDMA_OPTIONS);
+ prefSet.removePreference(cdmaOptions);
+
+ // TODO: Support MSIM for this preference option.
+ Preference gsmOptions = prefSet.findPreference(BUTTON_GSM_UMTS_OPTIONS);
+ prefSet.removePreference(gsmOptions);
int phoneType = mPhone.getPhoneType();
Preference fdnButton = prefSet.findPreference(BUTTON_FDN_KEY);
@@ -1371,6 +1331,15 @@
if (getResources().getBoolean(R.bool.config_additional_call_setting)) {
addPreferencesFromResource(R.xml.gsm_umts_call_options);
+
+ Preference callForwardingPref = prefSet.findPreference(CALL_FORWARDING_KEY);
+ callForwardingPref.setIntent(mSubscriptionInfoHelper.getIntent(
+ this, GsmUmtsCallForwardOptions.class));
+
+ Preference additionalGsmSettingsPref =
+ prefSet.findPreference(ADDITIONAL_GSM_SETTINGS_KEY);
+ additionalGsmSettingsPref.setIntent(mSubscriptionInfoHelper.getIntent(
+ this, GsmUmtsAdditionalCallOptions.class));
}
} else {
throw new IllegalStateException("Unexpected phone type: " + phoneType);
@@ -1501,25 +1470,19 @@
In this case we want to show the UI asking the user to select a voicemail provider as
opposed to silently falling back to default one. */
if (provider == null) {
- if (DBG) {
- log("updateVMPreferenceWidget: provider for the key \"" + key + "\" is null.");
- }
+ if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> null.");
+
mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
mVoicemailSettings.setEnabled(false);
mVoicemailSettings.setIntent(null);
-
mVoicemailNotificationVibrate.setEnabled(false);
} else {
- if (DBG) {
- log("updateVMPreferenceWidget: provider for the key \"" + key + "\".."
- + "name: " + provider.name
- + ", intent: " + provider.intent);
- }
+ if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> " + provider.toString());
+
final String providerName = provider.name;
mVoicemailProviders.setSummary(providerName);
mVoicemailSettings.setEnabled(true);
mVoicemailSettings.setIntent(provider.intent);
-
mVoicemailNotificationVibrate.setEnabled(true);
}
}
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index f925022..b176c27 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -36,14 +36,13 @@
private int mServiceClass;
private MyHandler mHandler = new MyHandler();
int reason;
- Phone phone;
+ private Phone mPhone;
CallForwardInfo callForwardInfo;
- TimeConsumingPreferenceListener tcpListener;
+ private TimeConsumingPreferenceListener mTcpListener;
public CallForwardEditPreference(Context context, AttributeSet attrs) {
super(context, attrs);
- phone = PhoneGlobals.getPhone();
mSummaryOnTemplate = this.getSummaryOn();
TypedArray a = context.obtainStyledAttributes(attrs,
@@ -61,16 +60,18 @@
this(context, null);
}
- void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
- tcpListener = listener;
+ void init(TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
+ mPhone = phone;
+ mTcpListener = listener;
+
if (!skipReading) {
- phone.getCallForwardingOption(reason,
+ mPhone.getCallForwardingOption(reason,
mHandler.obtainMessage(MyHandler.MESSAGE_GET_CF,
// unused in this case
CommandsInterface.CF_ACTION_DISABLE,
MyHandler.MESSAGE_GET_CF, null));
- if (tcpListener != null) {
- tcpListener.onStarted(this, true);
+ if (mTcpListener != null) {
+ mTcpListener.onStarted(this, true);
}
}
}
@@ -122,7 +123,7 @@
// the interface of Phone.setCallForwardingOption has error:
// should be action, reason...
- phone.setCallForwardingOption(action,
+ mPhone.setCallForwardingOption(action,
reason,
number,
time,
@@ -130,8 +131,8 @@
action,
MyHandler.MESSAGE_SET_CF));
- if (tcpListener != null) {
- tcpListener.onStarted(this, false);
+ if (mTcpListener != null) {
+ mTcpListener.onStarted(this, false);
}
}
}
@@ -183,28 +184,24 @@
private void handleGetCFResponse(Message msg) {
if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: done");
- if (msg.arg2 == MESSAGE_SET_CF) {
- tcpListener.onFinished(CallForwardEditPreference.this, false);
- } else {
- tcpListener.onFinished(CallForwardEditPreference.this, true);
- }
+ mTcpListener.onFinished(CallForwardEditPreference.this, msg.arg2 != MESSAGE_SET_CF);
AsyncResult ar = (AsyncResult) msg.obj;
callForwardInfo = null;
if (ar.exception != null) {
if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: ar.exception=" + ar.exception);
- tcpListener.onException(CallForwardEditPreference.this,
+ mTcpListener.onException(CallForwardEditPreference.this,
(CommandException) ar.exception);
} else {
if (ar.userObj instanceof Throwable) {
- tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
+ mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
}
CallForwardInfo cfInfoArray[] = (CallForwardInfo[]) ar.result;
if (cfInfoArray.length == 0) {
if (DBG) Log.d(LOG_TAG, "handleGetCFResponse: cfInfoArray.length==0");
setEnabled(false);
- tcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
+ mTcpListener.onError(CallForwardEditPreference.this, RESPONSE_ERROR);
} else {
for (int i = 0, length = cfInfoArray.length; i < length; i++) {
if (DBG) Log.d(LOG_TAG, "handleGetCFResponse, cfInfoArray[" + i + "]="
@@ -258,7 +255,7 @@
// setEnabled(false);
}
if (DBG) Log.d(LOG_TAG, "handleSetCFResponse: re get");
- phone.getCallForwardingOption(reason,
+ mPhone.getCallForwardingOption(reason,
obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
}
}
diff --git a/src/com/android/phone/CallWaitingCheckBoxPreference.java b/src/com/android/phone/CallWaitingCheckBoxPreference.java
index a2f5c70..ce2a420 100644
--- a/src/com/android/phone/CallWaitingCheckBoxPreference.java
+++ b/src/com/android/phone/CallWaitingCheckBoxPreference.java
@@ -20,13 +20,11 @@
private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
private final MyHandler mHandler = new MyHandler();
- private final Phone mPhone;
+ private Phone mPhone;
private TimeConsumingPreferenceListener mTcpListener;
public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
-
- mPhone = PhoneGlobals.getPhone();
}
public CallWaitingCheckBoxPreference(Context context, AttributeSet attrs) {
@@ -37,7 +35,9 @@
this(context, null);
}
- /* package */ void init(TimeConsumingPreferenceListener listener, boolean skipReading) {
+ /* package */ void init(
+ TimeConsumingPreferenceListener listener, boolean skipReading, Phone phone) {
+ mPhone = phone;
mTcpListener = listener;
if (!skipReading) {
diff --git a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
index cd400f9..0540547 100644
--- a/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
+++ b/src/com/android/phone/GsmUmtsAdditionalCallOptions.java
@@ -8,10 +8,11 @@
import android.util.Log;
import android.view.MenuItem;
+import com.android.internal.telephony.Phone;
+
import java.util.ArrayList;
-public class GsmUmtsAdditionalCallOptions extends
- TimeConsumingPreferenceActivity {
+public class GsmUmtsAdditionalCallOptions extends TimeConsumingPreferenceActivity {
private static final String LOG_TAG = "GsmUmtsAdditionalCallOptions";
private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
@@ -22,7 +23,8 @@
private CallWaitingCheckBoxPreference mCWButton;
private final ArrayList<Preference> mPreferences = new ArrayList<Preference>();
- private int mInitIndex= 0;
+ private int mInitIndex = 0;
+ private Phone mPhone;
@Override
protected void onCreate(Bundle icicle) {
@@ -30,6 +32,11 @@
addPreferencesFromResource(R.xml.gsm_umts_additional_options);
+ SubscriptionInfoHelper subscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
+ subscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResources(), R.string.additional_gsm_call_settings_with_label);
+ mPhone = subscriptionInfoHelper.getPhone();
+
PreferenceScreen prefSet = getPreferenceScreen();
mCLIRButton = (CLIRListPreference) prefSet.findPreference(BUTTON_CLIR_KEY);
mCWButton = (CallWaitingCheckBoxPreference) prefSet.findPreference(BUTTON_CW_KEY);
@@ -39,19 +46,19 @@
if (icicle == null) {
if (DBG) Log.d(LOG_TAG, "start to init ");
- mCLIRButton.init(this, false);
+ mCLIRButton.init(this, false, mPhone);
} else {
if (DBG) Log.d(LOG_TAG, "restore stored states");
mInitIndex = mPreferences.size();
- mCLIRButton.init(this, true);
- mCWButton.init(this, true);
+ mCLIRButton.init(this, true, mPhone);
+ mCWButton.init(this, true, mPhone);
int[] clirArray = icicle.getIntArray(mCLIRButton.getKey());
if (clirArray != null) {
if (DBG) Log.d(LOG_TAG, "onCreate: clirArray[0]="
+ clirArray[0] + ", clirArray[1]=" + clirArray[1]);
mCLIRButton.handleGetCLIRResult(clirArray);
} else {
- mCLIRButton.init(this, false);
+ mCLIRButton.init(this, false, mPhone);
}
}
@@ -77,7 +84,7 @@
mInitIndex++;
Preference pref = mPreferences.get(mInitIndex);
if (pref instanceof CallWaitingCheckBoxPreference) {
- ((CallWaitingCheckBoxPreference) pref).init(this, false);
+ ((CallWaitingCheckBoxPreference) pref).init(this, false, mPhone);
}
}
super.onFinished(preference, reading);
diff --git a/src/com/android/phone/GsmUmtsCallForwardOptions.java b/src/com/android/phone/GsmUmtsCallForwardOptions.java
index 8ecb1bf..3c4bebe 100644
--- a/src/com/android/phone/GsmUmtsCallForwardOptions.java
+++ b/src/com/android/phone/GsmUmtsCallForwardOptions.java
@@ -2,6 +2,7 @@
import com.android.internal.telephony.CallForwardInfo;
import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
import android.app.ActionBar;
import android.content.Intent;
@@ -9,7 +10,6 @@
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.util.Log;
import android.view.MenuItem;
@@ -20,7 +20,9 @@
private static final String LOG_TAG = "GsmUmtsCallForwardOptions";
private final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
- private static final String NUM_PROJECTION[] = {Phone.NUMBER};
+ private static final String NUM_PROJECTION[] = {
+ android.provider.ContactsContract.CommonDataKinds.Phone.NUMBER
+ };
private static final String BUTTON_CFU_KEY = "button_cfu_key";
private static final String BUTTON_CFB_KEY = "button_cfb_key";
@@ -42,6 +44,7 @@
private boolean mFirstResume;
private Bundle mIcicle;
+ private Phone mPhone;
@Override
protected void onCreate(Bundle icicle) {
@@ -49,9 +52,14 @@
addPreferencesFromResource(R.xml.callforward_options);
+ SubscriptionInfoHelper subscriptionInfoHelper = new SubscriptionInfoHelper(getIntent());
+ subscriptionInfoHelper.setActionBarTitle(
+ getActionBar(), getResources(), R.string.call_forwarding_settings_with_label);
+ mPhone = subscriptionInfoHelper.getPhone();
+
PreferenceScreen prefSet = getPreferenceScreen();
- mButtonCFU = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFU_KEY);
- mButtonCFB = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFB_KEY);
+ mButtonCFU = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFU_KEY);
+ mButtonCFB = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFB_KEY);
mButtonCFNRy = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRY_KEY);
mButtonCFNRc = (CallForwardEditPreference) prefSet.findPreference(BUTTON_CFNRC_KEY);
@@ -86,7 +94,7 @@
if (mFirstResume) {
if (mIcicle == null) {
if (DBG) Log.d(LOG_TAG, "start to init ");
- mPreferences.get(mInitIndex).init(this, false);
+ mPreferences.get(mInitIndex).init(this, false, mPhone);
} else {
mInitIndex = mPreferences.size();
@@ -97,11 +105,11 @@
cf.number = bundle.getString(KEY_NUMBER);
cf.status = bundle.getInt(KEY_STATUS);
pref.handleCallForwardResult(cf);
- pref.init(this, true);
+ pref.init(this, true, mPhone);
}
}
mFirstResume = false;
- mIcicle=null;
+ mIcicle = null;
}
}
@@ -124,7 +132,7 @@
public void onFinished(Preference preference, boolean reading) {
if (mInitIndex < mPreferences.size()-1 && !isFinishing()) {
mInitIndex++;
- mPreferences.get(mInitIndex).init(this, false);
+ mPreferences.get(mInitIndex).init(this, false, mPhone);
}
super.onFinished(preference, reading);
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index d618b5c..3c385f9 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -76,6 +76,10 @@
private static final String BUTTON_ENABLED_NETWORKS_KEY = "enabled_networks_key";
private static final String BUTTON_4G_LTE_KEY = "enhanced_4g_lte";
private static final String BUTTON_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
+ private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
+ private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
+ private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
+ private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE;
@@ -693,8 +697,13 @@
R.string.preferred_network_mode_lte_cdma_evdo_summary);
break;
case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
- mButtonPreferredNetworkMode.setSummary(
- R.string.preferred_network_mode_global_summary);
+ if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+ mButtonPreferredNetworkMode.setSummary(
+ R.string.preferred_network_mode_global_summary);
+ } else {
+ mButtonPreferredNetworkMode.setSummary(
+ R.string.preferred_network_mode_lte_summary);
+ }
break;
case Phone.NT_MODE_GLOBAL:
mButtonPreferredNetworkMode.setSummary(
@@ -737,9 +746,11 @@
}
break;
case Phone.NT_MODE_LTE_GSM_WCDMA:
- if(isWorldMode()) {
+ if (isWorldMode()) {
mButtonEnabledNetworks.setSummary(
R.string.preferred_network_mode_lte_gsm_umts_summary);
+ controlCdmaOptions(false);
+ controlGsmOptions(true);
break;
}
case Phone.NT_MODE_LTE_ONLY:
@@ -756,9 +767,11 @@
}
break;
case Phone.NT_MODE_LTE_CDMA_AND_EVDO:
- if(isWorldMode()) {
+ if (isWorldMode()) {
mButtonEnabledNetworks.setSummary(
R.string.preferred_network_mode_lte_cdma_summary);
+ controlCdmaOptions(true);
+ controlGsmOptions(false);
} else {
mButtonEnabledNetworks.setValue(
Integer.toString(Phone.NT_MODE_LTE_CDMA_AND_EVDO));
@@ -778,9 +791,18 @@
mButtonEnabledNetworks.setSummary(R.string.network_1x);
break;
case Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
+ if (isWorldMode()) {
+ controlCdmaOptions(true);
+ controlGsmOptions(false);
+ }
mButtonEnabledNetworks.setValue(
Integer.toString(Phone.NT_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
- mButtonEnabledNetworks.setSummary(R.string.network_global);
+ if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+ mButtonEnabledNetworks.setSummary(R.string.network_global);
+ } else {
+ mButtonEnabledNetworks.setSummary((mShow4GForLTE == true)
+ ? R.string.network_4G : R.string.network_lte);
+ }
break;
default:
String errMsg = "Invalid Network Mode (" + NetworkMode + "). Ignore.";
@@ -860,4 +882,46 @@
return worldModeOn;
}
+
+ private void controlGsmOptions(boolean enable) {
+ PreferenceScreen prefSet = getPreferenceScreen();
+ if (prefSet == null) {
+ return;
+ }
+
+ if (enable && mGsmUmtsOptions == null) {
+ mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet);
+ }
+ PreferenceScreen apnExpand =
+ (PreferenceScreen) prefSet.findPreference(BUTTON_APN_EXPAND_KEY);
+ PreferenceScreen operatorSelectionExpand =
+ (PreferenceScreen) prefSet.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+ PreferenceScreen carrierSettings =
+ (PreferenceScreen) prefSet.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
+ if (apnExpand != null) {
+ apnExpand.setEnabled(enable);
+ }
+ if (operatorSelectionExpand != null) {
+ operatorSelectionExpand.setEnabled(enable);
+ }
+ if (carrierSettings != null) {
+ prefSet.removePreference(carrierSettings);
+ }
+ }
+
+ private void controlCdmaOptions(boolean enable) {
+ PreferenceScreen prefSet = getPreferenceScreen();
+ if (prefSet == null) {
+ return;
+ }
+ if (enable && mCdmaOptions == null) {
+ mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
+ }
+ CdmaSystemSelectListPreference systemSelect =
+ (CdmaSystemSelectListPreference)prefSet.findPreference
+ (BUTTON_CDMA_SYSTEM_SELECT_KEY);
+ if (systemSelect != null) {
+ systemSelect.setEnabled(enable);
+ }
+ }
}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 5489c47..e06684c 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -392,7 +392,11 @@
List<UserInfo> users = mUserManager.getUsers(true);
for (int i = 0; i < users.size(); i++) {
- UserHandle userHandle = users.get(i).getUserHandle();
+ final UserInfo user = users.get(i);
+ if (user.isManagedProfile()) {
+ continue;
+ }
+ UserHandle userHandle = user.getUserHandle();
builder.setContentIntent(userHandle.isOwner() ? contentIntent : null);
mNotificationManager.notifyAsUser(
null /* tag */, CALL_FORWARD_NOTIFICATION, builder.build(), userHandle);
@@ -425,7 +429,11 @@
List<UserInfo> users = mUserManager.getUsers(true);
for (int i = 0; i < users.size(); i++) {
- UserHandle userHandle = users.get(i).getUserHandle();
+ final UserInfo user = users.get(i);
+ if (user.isManagedProfile()) {
+ continue;
+ }
+ UserHandle userHandle = user.getUserHandle();
builder.setContentIntent(userHandle.isOwner() ? contentIntent : null);
final Notification notif =
new Notification.BigTextStyle(builder).bigText(contentText).build();
@@ -468,7 +476,11 @@
List<UserInfo> users = mUserManager.getUsers(true);
for (int i = 0; i < users.size(); i++) {
- UserHandle userHandle = users.get(i).getUserHandle();
+ final UserInfo user = users.get(i);
+ if (user.isManagedProfile()) {
+ continue;
+ }
+ UserHandle userHandle = user.getUserHandle();
builder.setContentIntent(userHandle.isOwner() ? contentIntent : null);
mNotificationManager.notifyAsUser(
null /* tag */,
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 62eb272..e957924 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -162,6 +162,7 @@
// True if we are beginning a call, but the phone state has not changed yet
private boolean mBeginningCall;
+ private boolean mDataDisconnectedDueToRoaming = false;
// Last phone state seen by updatePhoneState()
private PhoneConstants.State mLastPhoneState = PhoneConstants.State.IDLE;
@@ -800,9 +801,11 @@
&& "DISCONNECTED".equals(intent.getStringExtra(PhoneConstants.STATE_KEY))
&& Phone.REASON_ROAMING_ON.equals(
intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY));
- mHandler.sendEmptyMessage(disconnectedDueToRoaming
- ? EVENT_DATA_ROAMING_DISCONNECTED
- : EVENT_DATA_ROAMING_OK);
+ if (mDataDisconnectedDueToRoaming != disconnectedDueToRoaming) {
+ mDataDisconnectedDueToRoaming = disconnectedDueToRoaming;
+ mHandler.sendEmptyMessage(disconnectedDueToRoaming
+ ? EVENT_DATA_ROAMING_DISCONNECTED : EVENT_DATA_ROAMING_OK);
+ }
} else if ((action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) &&
(mPUKEntryActivity != null)) {
// if an attempt to un-PUK-lock the device was made, while we're
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 6f436fd..5226e0d 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -18,7 +18,6 @@
import android.util.Log;
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;
@@ -31,10 +30,6 @@
Preference.OnPreferenceClickListener,
AccountSelectionPreference.AccountSelectionListener {
- private static final Intent CONNECTION_SERVICE_CONFIGURE_INTENT =
- new Intent(TelecomManager.ACTION_CONNECTION_SERVICE_CONFIGURE)
- .addCategory(Intent.CATEGORY_DEFAULT);
-
private static final String ACCOUNTS_LIST_CATEGORY_KEY =
"phone_accounts_accounts_list_category_key";
@@ -184,10 +179,20 @@
@Override
public boolean onPreferenceClick(Preference pref) {
if (pref == mConfigureCallAssistant) {
- try {
- startActivity(CONNECTION_SERVICE_CONFIGURE_INTENT);
- } catch (ActivityNotFoundException e) {
- Log.d(LOG_TAG, "Could not resolve telecom connection service configure intent.");
+ String packageName = null;
+ PhoneAccountHandle handle = mTelecomManager.getSimCallManager();
+ if (handle != null) {
+ packageName = handle.getComponentName().getPackageName();
+ }
+ if (packageName != null) {
+ Intent intent = new Intent(TelecomManager.ACTION_CONNECTION_SERVICE_CONFIGURE)
+ .addCategory(Intent.CATEGORY_DEFAULT)
+ .setPackage(packageName);
+ try {
+ startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.d(LOG_TAG, "Could not resolve call assistant configure intent: " + intent);
+ }
}
return true;
}
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index 3242e64..c52a824 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -163,6 +163,15 @@
return capabilities;
}
+ @Override
+ public void performConference(TelephonyConnection otherConnection) {
+ if (isImsConnection()) {
+ super.performConference(otherConnection);
+ } else {
+ Log.w(this, "Non-IMS CDMA Connection attempted to call performConference.");
+ }
+ }
+
void forceAsDialing(boolean isDialing) {
if (isDialing) {
setDialing();
diff --git a/src/com/android/services/telephony/GsmConnection.java b/src/com/android/services/telephony/GsmConnection.java
index da03fa1..d2e68c6 100644
--- a/src/com/android/services/telephony/GsmConnection.java
+++ b/src/com/android/services/telephony/GsmConnection.java
@@ -46,23 +46,6 @@
}
@Override
- public void performConference(TelephonyConnection otherConnection) {
- Log.d(this, "performConference - %s", this);
- if (getPhone() != null) {
- try {
- // We dont use the "other" connection because there is no concept of that in the
- // implementation of calls inside telephony. Basically, you can "conference" and it
- // will conference with the background call. We know that otherConnection is the
- // background call because it would never have called setConferenceableConnections()
- // otherwise.
- getPhone().conference();
- } catch (CallStateException e) {
- Log.e(this, e, "Failed to conference call.");
- }
- }
- }
-
- @Override
protected int buildCallCapabilities() {
int capabilities = super.buildCallCapabilities();
capabilities |= PhoneCapabilities.MUTE;
diff --git a/src/com/android/services/telephony/TelephonyConference.java b/src/com/android/services/telephony/TelephonyConference.java
index b5e264c..fc009bc 100644
--- a/src/com/android/services/telephony/TelephonyConference.java
+++ b/src/com/android/services/telephony/TelephonyConference.java
@@ -33,6 +33,12 @@
*/
public class TelephonyConference extends Conference {
+ /**
+ * When {@code true}, indicates that conference participant information from an IMS conference
+ * event package has been received.
+ */
+ private boolean mParticipantsReceived = false;
+
public TelephonyConference(PhoneAccountHandle phoneAccount) {
super(phoneAccount);
setCapabilities(
@@ -129,6 +135,23 @@
}
@Override
+ public void onConnectionAdded(Connection connection) {
+ // If the conference was an IMS connection currently or before, disable MANAGE_CONFERENCE
+ // as the default behavior. If there is a conference event package, this may be overridden.
+ // If a conference event package was received, do not attempt to remove manage conference.
+ if (connection instanceof TelephonyConnection &&
+ ((TelephonyConnection) connection).wasImsConnection() &&
+ !mParticipantsReceived) {
+ int capabilities = getCapabilities();
+ if (PhoneCapabilities.can(capabilities, PhoneCapabilities.MANAGE_CONFERENCE)) {
+ int newCapabilities =
+ PhoneCapabilities.remove(capabilities, PhoneCapabilities.MANAGE_CONFERENCE);
+ setCapabilities(newCapabilities);
+ }
+ }
+ }
+
+ @Override
public Connection getPrimaryConnection() {
// Default to the first connection.
Connection primaryConnection = getConnections().get(0);
@@ -176,4 +199,17 @@
}
return (TelephonyConnection) connections.get(0);
}
+
+ /**
+ * Flags the conference to indicate that a conference event package has been received and there
+ * is now participant data present which would permit conference management.
+ */
+ public void setParticipantsReceived() {
+ if (!mParticipantsReceived) {
+ int capabilities = getCapabilities();
+ capabilities |= PhoneCapabilities.MANAGE_CONFERENCE;
+ setCapabilities(capabilities);
+ }
+ mParticipantsReceived = true;
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConferenceController.java b/src/com/android/services/telephony/TelephonyConferenceController.java
index 43385fd..55c8338 100644
--- a/src/com/android/services/telephony/TelephonyConferenceController.java
+++ b/src/com/android/services/telephony/TelephonyConferenceController.java
@@ -61,23 +61,22 @@
}
/**
- * Handles notifications from an connection that a participant in a conference has changed
+ * Handles notifications from an connection that participant(s) in a conference have changed
* state.
*
* @param c The connection.
- * @param participant The participant information.
+ * @param participants The participant information.
*/
@Override
- public void onConferenceParticipantChanged(Connection c,
- ConferenceParticipant participant) {
+ public void onConferenceParticipantsChanged(Connection c,
+ List<ConferenceParticipant> participants) {
if (c == null) {
return;
}
+ Log.v(this, "onConferenceParticipantsChanged: %d participants", participants.size());
TelephonyConnection telephonyConnection = (TelephonyConnection) c;
-
- Log.v(this, "onConferenceParticipantChanged: %s", participant);
- handleConferenceParticipantUpdate(telephonyConnection, participant);
+ handleConferenceParticipantsUpdate(telephonyConnection, participants);
}
};
@@ -118,8 +117,8 @@
}
private void recalculate() {
- recalculateConferenceable();
recalculateConference();
+ recalculateConferenceable();
}
private boolean isFullConference(Conference conference) {
@@ -184,6 +183,7 @@
nonConferencedConnections.add(c);
}
}
+ Log.v(this, "conference conferenceable: %s", nonConferencedConnections);
mTelephonyConference.setConferenceableConnections(nonConferencedConnections);
}
@@ -219,6 +219,8 @@
Log.d(this, "Recalculate conference calls %s %s.",
mTelephonyConference, conferencedConnections);
+ boolean wasParticipantsAdded = false;
+
// 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.
@@ -240,7 +242,8 @@
List<Connection> existingConnections = mTelephonyConference.getConnections();
// Remove any that no longer exist
for (Connection connection : existingConnections) {
- if (!conferencedConnections.contains(connection)) {
+ if (connection instanceof TelephonyConnection &&
+ !conferencedConnections.contains(connection)) {
mTelephonyConference.removeConnection(connection);
}
}
@@ -256,8 +259,9 @@
for (Connection conferenceParticipant :
mConferenceParticipantConnections.values()) {
- if (conferenceParticipant.getState() == Connection.STATE_ACTIVE) {
+ if (conferenceParticipant.getState() == Connection.STATE_NEW) {
if (!existingConnections.contains(conferenceParticipant)) {
+ wasParticipantsAdded = true;
mTelephonyConference.addConnection(conferenceParticipant);
}
}
@@ -273,12 +277,19 @@
// Add the conference participants
for (Connection conferenceParticipant :
mConferenceParticipantConnections.values()) {
+ wasParticipantsAdded = true;
mTelephonyConference.addConnection(conferenceParticipant);
}
mConnectionService.addConference(mTelephonyConference);
}
+ // If we added conference participants (e.g. via an IMS conference event package),
+ // notify the conference so that the MANAGE_CONFERENCE capability can be added.
+ if (wasParticipantsAdded) {
+ mTelephonyConference.setParticipantsReceived();
+ }
+
// Set the conference state to the same state as its child connections.
Connection conferencedConnection = mTelephonyConference.getPrimaryConnection();
switch (conferencedConnection.getState()) {
@@ -310,21 +321,40 @@
}
/**
- * Handles state changes for a conference participant.
+ * Handles state changes for conference participant(s).
*
* @param parent The connection which was notified of the conference participant.
- * @param participant The conference participant.
+ * @param participants The conference participant information.
*/
- private void handleConferenceParticipantUpdate(
- TelephonyConnection parent, ConferenceParticipant participant) {
+ private void handleConferenceParticipantsUpdate(
+ TelephonyConnection parent, List<ConferenceParticipant> participants) {
- Uri endpoint = participant.getEndpoint();
- if (!mConferenceParticipantConnections.containsKey(endpoint)) {
- createConferenceParticipantConnection(parent, participant);
- } else {
- ConferenceParticipantConnection connection =
- mConferenceParticipantConnections.get(endpoint);
- connection.updateState(participant.getState());
+ boolean recalculateConference = false;
+ ArrayList<ConferenceParticipant> newParticipants = new ArrayList<>(participants.size());
+
+ for (ConferenceParticipant participant : participants) {
+ Uri endpoint = participant.getEndpoint();
+ if (!mConferenceParticipantConnections.containsKey(endpoint)) {
+ createConferenceParticipantConnection(parent, participant);
+ newParticipants.add(participant);
+ recalculateConference = true;
+ } else {
+ ConferenceParticipantConnection connection =
+ mConferenceParticipantConnections.get(endpoint);
+ connection.updateState(participant.getState());
+ }
+ }
+
+ if (recalculateConference) {
+ // Recalculate to add new connections to the conference.
+ recalculateConference();
+
+ // Now that conference is established, set the state for all participants.
+ for (ConferenceParticipant newParticipant : newParticipants) {
+ ConferenceParticipantConnection connection =
+ mConferenceParticipantConnections.get(newParticipant.getEndpoint());
+ connection.updateState(newParticipant.getState());
+ }
}
}
@@ -346,13 +376,9 @@
ConferenceParticipantConnection connection = new ConferenceParticipantConnection(
parent, participant);
connection.addConnectionListener(mConnectionListener);
- connection.updateState(Connection.STATE_HOLDING);
mConferenceParticipantConnections.put(participant.getEndpoint(), connection);
PhoneAccountHandle phoneAccountHandle =
- TelecomAccountRegistry.makePstnPhoneAccountHandle(parent.getPhone());
+ 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 b9f9375..056f62f 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -34,7 +34,11 @@
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import java.lang.Override;
+import java.util.Collections;
+import java.util.List;
import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Base class for CDMA and GSM connections.
@@ -78,6 +82,15 @@
}
};
+ /**
+ * A listener/callback mechanism that is specific communication from TelephonyConnections
+ * to TelephonyConnectionService (for now). It is more specific that Connection.Listener
+ * because it is only exposed in Telephony.
+ */
+ public abstract static class TelephonyConnectionListener {
+ public void onOriginalConnectionConfigured(TelephonyConnection c) {}
+ }
+
private final PostDialListener mPostDialListener = new PostDialListener() {
@Override
public void onPostDialWait() {
@@ -143,14 +156,14 @@
}
/**
- * Handles a change in the state of a conference participant, as reported by the
+ * Handles a change in the state of conference participant(s), as reported by the
* {@link com.android.internal.telephony.Connection}.
*
- * @param participant The participant which changed.
+ * @param participants The participant(s) which changed.
*/
@Override
- public void onConferenceParticipantChanged(ConferenceParticipant participant) {
- updateConferenceParticipant(participant);
+ public void onConferenceParticipantsChanged(List<ConferenceParticipant> participants) {
+ updateConferenceParticipants(participants);
}
};
@@ -186,6 +199,12 @@
*/
private int mAudioQuality;
+ /**
+ * Listeners to our TelephonyConnection specific callbacks
+ */
+ private final Set<TelephonyConnectionListener> mTelephonyListeners = Collections.newSetFromMap(
+ new ConcurrentHashMap<TelephonyConnectionListener, Boolean>(8, 0.9f, 1));
+
protected TelephonyConnection(com.android.internal.telephony.Connection originalConnection) {
if (originalConnection != null) {
setOriginalConnection(originalConnection);
@@ -289,25 +308,6 @@
}
}
- @Override
- public void onConferenceChanged() {
- Conference conference = getConference();
- if (conference == null) {
- return;
- }
-
- // If the conference was an IMS connection currently or before, disable MANAGE_CONFERENCE
- // as the default behavior. If there is a conference event package, this may be overridden.
- if (mWasImsConnection) {
- int capabilities = conference.getCapabilities();
- if (PhoneCapabilities.can(capabilities, PhoneCapabilities.MANAGE_CONFERENCE)) {
- int newCapabilities =
- PhoneCapabilities.remove(capabilities, PhoneCapabilities.MANAGE_CONFERENCE);
- conference.setCapabilities(newCapabilities);
- }
- }
- }
-
public void performHold() {
Log.v(this, "performHold");
// TODO: Can dialing calls be put on hold as well since they take up the
@@ -373,7 +373,21 @@
}
}
- public void performConference(TelephonyConnection otherConnection) {}
+ public void performConference(TelephonyConnection otherConnection) {
+ Log.d(this, "performConference - %s", this);
+ if (getPhone() != null) {
+ try {
+ // We dont use the "other" connection because there is no concept of that in the
+ // implementation of calls inside telephony. Basically, you can "conference" and it
+ // will conference with the background call. We know that otherConnection is the
+ // background call because it would never have called setConferenceableConnections()
+ // otherwise.
+ getPhone().conference();
+ } catch (CallStateException e) {
+ Log.e(this, e, "Failed to conference call.");
+ }
+ }
+ }
/**
* Builds call capabilities common to all TelephonyConnections. Namely, apply IMS-based
@@ -455,6 +469,7 @@
mWasImsConnection = true;
}
+ fireOnOriginalConnectionConfigured();
updateAddress();
}
@@ -778,6 +793,15 @@
return getOriginalConnection() instanceof ImsPhoneConnection;
}
+ /**
+ * Whether the original connection was ever an IMS connection, either before or now.
+ * @return {@code True} if the original connection was ever an IMS connection, {@code false}
+ * otherwise.
+ */
+ public boolean wasImsConnection() {
+ return mWasImsConnection;
+ }
+
private static Uri getAddressFromNumber(String number) {
// Address can be null for blocked calls.
if (number == null) {
@@ -809,4 +833,42 @@
int newCapabilities = capabilities & ~capability;
return newCapabilities;
}
+
+ /**
+ * Register a listener for {@link TelephonyConnection} specific triggers.
+ * @param l The instance of the listener to add
+ * @return The connection being listened to
+ */
+ public final TelephonyConnection addTelephonyConnectionListener(TelephonyConnectionListener l) {
+ mTelephonyListeners.add(l);
+ // If we already have an original connection, let's call back immediately.
+ // This would be the case for incoming calls.
+ if (mOriginalConnection != null) {
+ fireOnOriginalConnectionConfigured();
+ }
+ return this;
+ }
+
+ /**
+ * Remove a listener for {@link TelephonyConnection} specific triggers.
+ * @param l The instance of the listener to remove
+ * @return The connection being listened to
+ */
+ public final TelephonyConnection removeTelephonyConnectionListener(
+ TelephonyConnectionListener l) {
+ if (l != null) {
+ mTelephonyListeners.remove(l);
+ }
+ return this;
+ }
+
+ /**
+ * Fire a callback to the various listeners for when the original connection is
+ * set in this {@link TelephonyConnection}
+ */
+ private final void fireOnOriginalConnectionConfigured() {
+ for (TelephonyConnectionListener l : mTelephonyListeners) {
+ l.onOriginalConnectionConfigured(this);
+ }
+ }
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 91f164b..8ef9ae8 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -56,6 +56,17 @@
private EmergencyCallHelper mEmergencyCallHelper;
private EmergencyTonePlayer mEmergencyTonePlayer;
+ /**
+ * A listener to actionable events specific to the TelephonyConnection.
+ */
+ private final TelephonyConnection.TelephonyConnectionListener mTelephonyConnectionListener =
+ new TelephonyConnection.TelephonyConnectionListener() {
+ @Override
+ public void onOriginalConnectionConfigured(TelephonyConnection c) {
+ addConnectionToConferenceController(c);
+ }
+ };
+
@Override
public void onCreate() {
super.onCreate();
@@ -345,24 +356,20 @@
Phone phone,
com.android.internal.telephony.Connection originalConnection,
boolean isOutgoing) {
+ TelephonyConnection returnConnection = null;
int phoneType = phone.getPhoneType();
if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
- GsmConnection connection = new GsmConnection(originalConnection);
- mTelephonyConferenceController.add(connection);
- return connection;
+ returnConnection = new GsmConnection(originalConnection);
} else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
boolean allowMute = allowMute(phone);
- CdmaConnection connection = new CdmaConnection(
+ returnConnection = new CdmaConnection(
originalConnection, mEmergencyTonePlayer, allowMute, isOutgoing);
- if (connection.isImsConnection()) {
- mTelephonyConferenceController.add(connection);
- } else {
- mCdmaConferenceController.add(connection);
- }
- return connection;
- } else {
- return null;
}
+ if (returnConnection != null) {
+ // Listen to Telephony specific callbacks from the connection
+ returnConnection.addTelephonyConnectionListener(mTelephonyConnectionListener);
+ }
+ return returnConnection;
}
private boolean isOriginalConnectionKnown(
@@ -418,4 +425,40 @@
return true;
}
+
+ @Override
+ public void removeConnection(Connection connection) {
+ super.removeConnection(connection);
+ if (connection instanceof TelephonyConnection) {
+ TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
+ telephonyConnection.removeTelephonyConnectionListener(mTelephonyConnectionListener);
+ }
+ }
+
+ /**
+ * When a {@link TelephonyConnection} has its underlying original connection configured,
+ * we need to add it to the correct conference controller.
+ *
+ * @param connection The connection to be added to the controller
+ */
+ public void addConnectionToConferenceController(TelephonyConnection connection) {
+ // TODO: Do we need to handle the case of the original connection changing
+ // and triggering this callback multiple times for the same connection?
+ // If that is the case, we might want to remove this connection from all
+ // conference controllers first before re-adding it.
+ if (connection.isImsConnection()) {
+ Log.d(this, "Adding IMS connection to conference controller: " + connection);
+ mTelephonyConferenceController.add(connection);
+ } else {
+ int phoneType = connection.getCall().getPhone().getPhoneType();
+ if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
+ Log.d(this, "Adding GSM connection to conference controller: " + connection);
+ mTelephonyConferenceController.add(connection);
+ } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA &&
+ connection instanceof CdmaConnection) {
+ Log.d(this, "Adding CDMA connection to conference controller: " + connection);
+ mCdmaConferenceController.add((CdmaConnection)connection);
+ }
+ }
+ }
}