Merge "Add color to PhoneAccount objects (3/3)" into lmp-sprout-dev
diff --git a/res/values-mcc311-mnc220/config.xml b/res/values-mcc311-mnc220/config.xml
index 7c269e0..22701f0 100644
--- a/res/values-mcc311-mnc220/config.xml
+++ b/res/values-mcc311-mnc220/config.xml
@@ -19,4 +19,6 @@
<resources>
<!-- Flag indicating if dtmf tone type is enabled -->
<bool name="dtmf_type_enabled">true</bool>
+ <!-- CDMA activation goes through OTASP. -->
+ <bool name="config_use_otasp_for_provisioning">true</bool>
</resources>
diff --git a/res/values-mcc311-mnc580/config.xml b/res/values-mcc311-mnc580/config.xml
index 7c269e0..22701f0 100644
--- a/res/values-mcc311-mnc580/config.xml
+++ b/res/values-mcc311-mnc580/config.xml
@@ -19,4 +19,6 @@
<resources>
<!-- Flag indicating if dtmf tone type is enabled -->
<bool name="dtmf_type_enabled">true</bool>
+ <!-- CDMA activation goes through OTASP. -->
+ <bool name="config_use_otasp_for_provisioning">true</bool>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 3daf89a..cd82234 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -127,8 +127,13 @@
<!-- Class name for the default main Dialer activity [DO NOT TRANSLATE] -->
<string name="dialer_default_class" translatable="false">com.android.dialer.DialtactsActivity</string>
- <!-- CDMA activation goes through HFA [DO NOT TRANSLATE] -->
- <bool name="config_use_hfa_for_provisioning" translatable="false">false</bool>
+ <!-- CDMA activation goes through HFA -->
+ <bool name="config_use_hfa_for_provisioning">false</bool>
+
+ <!-- CDMA activation goes through OTASP.
+ TODO: This should be combined with config_use_hfa_for_provisioning and implemented
+ as an enum (NONE, HFA, OTASP). -->
+ <bool name="config_use_otasp_for_provisioning">false</bool>
<!-- Display carrier settings menu if true -->
<bool name="config_carrier_settings_enable">false</bool>
@@ -141,4 +146,7 @@
<!-- Show APN Settings for some CDMA carriers -->
<bool name="config_show_apn_setting_cdma">false</bool>
+
+ <!-- Allows the telephony HFA logic to run even if we're not in setup wizard. -->
+ <bool name="config_allow_hfa_outside_of_setup_wizard">true</bool>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 382d39f..498b632 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -275,6 +275,8 @@
<style name="SimImportTheme" parent="@android:style/Theme.Material.Light">
<item name="android:actionBarStyle">@style/TelephonyActionBarStyle</item>
<item name="android:colorPrimaryDark">@color/dialer_theme_color_dark</item>
+ <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
+ <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
</style>
<style name="OutgoingCallBroadcasterTheme" parent="@android:style/Theme.Holo.NoActionBar">
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index b85cb7e..c38df5c 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -485,7 +485,10 @@
mAudioManager.setParameter(HAC_KEY, hac != 0 ? HAC_VAL_ON : HAC_VAL_OFF);
return true;
} else if (preference == mVoicemailSettings) {
- mVoicemailSettings.getDialog().getActionBar().setDisplayHomeAsUpEnabled(false);
+ 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) {
@@ -511,7 +514,10 @@
return false;
}
} else if (preference == mVoicemailSettingsScreen) {
- mVoicemailSettingsScreen.getDialog().getActionBar().setDisplayHomeAsUpEnabled(false);
+ final Dialog dialog = mVoicemailSettingsScreen.getDialog();
+ if (dialog != null) {
+ dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
+ }
return false;
}
return false;
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index be1e3b2..f22913c 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -142,8 +142,6 @@
callStateMonitor.addListener(this);
- createSignalInfoToneGenerator();
-
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
adapter.getProfileProxy(mApplication.getApplicationContext(),
@@ -944,7 +942,7 @@
@Override
public void run() {
log("SignalInfoTonePlayer.run(toneId = " + mToneId + ")...");
-
+ createSignalInfoToneGenerator();
if (mSignalInfoToneGenerator != null) {
//First stop any ongoing SignalInfo tone
mSignalInfoToneGenerator.stopTone();
diff --git a/src/com/android/phone/EmergencyDialer.java b/src/com/android/phone/EmergencyDialer.java
index e29d4c8..a8de874 100644
--- a/src/com/android/phone/EmergencyDialer.java
+++ b/src/com/android/phone/EmergencyDialer.java
@@ -38,6 +38,7 @@
import android.text.method.DialerKeyListener;
import android.util.Log;
import android.view.KeyEvent;
+import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -606,6 +607,16 @@
}
}
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ final int itemId = item.getItemId();
+ if (itemId == android.R.id.home) {
+ onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
/**
* Update the enabledness of the "Dial" and "Backspace" buttons if applicable.
*/
diff --git a/src/com/android/phone/HfaLogic.java b/src/com/android/phone/HfaLogic.java
index e4a3205..b064b18 100644
--- a/src/com/android/phone/HfaLogic.java
+++ b/src/com/android/phone/HfaLogic.java
@@ -71,7 +71,8 @@
private PendingIntent mResponseIntent;
private Context mContext;
- private static final int DEFAULT_RETRY_COUNT = 1;
+ // No retry at the moment. Increase later if necessary.
+ private static final int DEFAULT_RETRY_COUNT = 0;
private int mRetryCount;
public interface HfaLogicCallback {
diff --git a/src/com/android/phone/InCallScreenShowActivation.java b/src/com/android/phone/InCallScreenShowActivation.java
index fd202db..34710a1 100644
--- a/src/com/android/phone/InCallScreenShowActivation.java
+++ b/src/com/android/phone/InCallScreenShowActivation.java
@@ -73,74 +73,81 @@
boolean usesHfa = getResources().getBoolean(R.bool.config_use_hfa_for_provisioning);
if (usesHfa) {
- Log.d(LOG_TAG, "Starting Hfa from ACTION_PERFORM_CDMA_PROVISIONING");
+ Log.i(LOG_TAG, "Starting Hfa from ACTION_PERFORM_CDMA_PROVISIONING");
startHfa();
finish();
return;
}
- // On voice-capable devices, we perform CDMA provisioning in
- // "interactive" mode by directly launching the InCallScreen.
- // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
- // TODO: Renable interactive mode for device provisioning.
- boolean interactiveMode = false;
- Log.d(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
- + interactiveMode + ")...");
+ boolean usesOtasp = getResources().getBoolean(R.bool.config_use_otasp_for_provisioning);
+ if (usesOtasp) {
+ // On voice-capable devices, we perform CDMA provisioning in
+ // "interactive" mode by directly launching the InCallScreen.
+ // boolean interactiveMode = PhoneGlobals.sVoiceCapable;
+ // TODO: Renable interactive mode for device provisioning.
+ boolean interactiveMode = false;
+ Log.i(LOG_TAG, "ACTION_PERFORM_CDMA_PROVISIONING (interactiveMode = "
+ + interactiveMode + ")...");
- // Testing: this intent extra allows test apps manually
- // enable/disable "interactive mode", regardless of whether
- // the current device is voice-capable. This is allowed only
- // in userdebug or eng builds.
- if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
- && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
- interactiveMode =
- intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
- Log.d(LOG_TAG, "===> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
- }
-
- // We allow the caller to pass a PendingIntent (as the
- // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
- // which we'll later use to notify them when the OTASP call
- // fails or succeeds.
- //
- // Stash that away here, and we'll fire it off later in
- // OtaUtils.sendOtaspResult().
- app.cdmaOtaScreenState.otaspResultCodePendingIntent =
- (PendingIntent) intent.getParcelableExtra(
- OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
-
- if (interactiveMode) {
- // On voice-capable devices, launch an OTASP call and arrange
- // for the in-call UI to come up. (The InCallScreen will
- // notice that an OTASP call is active, and display the
- // special OTASP UI instead of the usual in-call controls.)
-
- if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
- OtaUtils.startInteractiveOtasp(this);
-
- // The result we set here is actually irrelevant, since the
- // InCallScreen's "interactive" OTASP sequence never actually
- // finish()es; it ends by directly launching the Home
- // activity. So our caller won't actually ever get an
- // onActivityResult() call in this case.
- setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
- } else {
- // On data-only devices, manually launch the OTASP call
- // *without* displaying any UI. (Our caller, presumably
- // SetupWizardActivity, is responsible for displaying some
- // sort of progress UI.)
-
- if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
- int callStatus = OtaUtils.startNonInteractiveOtasp(this);
-
- if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
- if (DBG) Log.d(LOG_TAG, " ==> successful result from startNonInteractiveOtasp(): "
- + callStatus);
- setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
- } else {
- Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " + callStatus);
- setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
+ // Testing: this intent extra allows test apps manually
+ // enable/disable "interactive mode", regardless of whether
+ // the current device is voice-capable. This is allowed only
+ // in userdebug or eng builds.
+ if (intent.hasExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE)
+ && (SystemProperties.getInt("ro.debuggable", 0) == 1)) {
+ interactiveMode =
+ intent.getBooleanExtra(OtaUtils.EXTRA_OVERRIDE_INTERACTIVE_MODE, false);
+ Log.d(LOG_TAG, "==> MANUALLY OVERRIDING interactiveMode to " + interactiveMode);
}
+
+ // We allow the caller to pass a PendingIntent (as the
+ // EXTRA_NONINTERACTIVE_OTASP_RESULT_PENDING_INTENT extra)
+ // which we'll later use to notify them when the OTASP call
+ // fails or succeeds.
+ //
+ // Stash that away here, and we'll fire it off later in
+ // OtaUtils.sendOtaspResult().
+ app.cdmaOtaScreenState.otaspResultCodePendingIntent =
+ (PendingIntent) intent.getParcelableExtra(
+ OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
+
+ if (interactiveMode) {
+ // On voice-capable devices, launch an OTASP call and arrange
+ // for the in-call UI to come up. (The InCallScreen will
+ // notice that an OTASP call is active, and display the
+ // special OTASP UI instead of the usual in-call controls.)
+
+ if (DBG) Log.d(LOG_TAG, "==> Starting interactive CDMA provisioning...");
+ OtaUtils.startInteractiveOtasp(this);
+
+ // The result we set here is actually irrelevant, since the
+ // InCallScreen's "interactive" OTASP sequence never actually
+ // finish()es; it ends by directly launching the Home
+ // activity. So our caller won't actually ever get an
+ // onActivityResult() call in this case.
+ setResult(OtaUtils.RESULT_INTERACTIVE_OTASP_STARTED);
+ } else {
+ // On data-only devices, manually launch the OTASP call
+ // *without* displaying any UI. (Our caller, presumably
+ // SetupWizardActivity, is responsible for displaying some
+ // sort of progress UI.)
+
+ if (DBG) Log.d(LOG_TAG, "==> Starting non-interactive CDMA provisioning...");
+ int callStatus = OtaUtils.startNonInteractiveOtasp(this);
+
+ if (callStatus == PhoneUtils.CALL_STATUS_DIALED) {
+ if (DBG) Log.d(LOG_TAG,
+ " ==> successful result from startNonInteractiveOtasp(): " +
+ callStatus);
+ setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_STARTED);
+ } else {
+ Log.w(LOG_TAG, "Failure code from startNonInteractiveOtasp(): " +
+ callStatus);
+ setResult(OtaUtils.RESULT_NONINTERACTIVE_OTASP_FAILED);
+ }
+ }
+ } else {
+ Log.i(LOG_TAG, "Skipping activation.");
}
} else {
Log.e(LOG_TAG, "Unexpected intent action: " + intent);
@@ -180,28 +187,34 @@
* Starts the HFA provisioning process by bringing up the HFA Activity.
*/
private void startHfa() {
- final Intent intent = new Intent();
+ boolean isWizardRunning = isWizardRunning(this);
+ // We always run our HFA logic if we're in setup wizard, but if we're outside of setup
+ // wizard then we have to check a config to see if we should still run HFA.
+ if (isWizardRunning ||
+ getResources().getBoolean(R.bool.config_allow_hfa_outside_of_setup_wizard)) {
- final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
- OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
+ final Intent intent = new Intent();
- final boolean showUi = !isWizardRunning(this);
+ final PendingIntent otaResponseIntent = getIntent().getParcelableExtra(
+ OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ final boolean showUi = !isWizardRunning;
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (otaResponseIntent != null) {
- intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
+ if (otaResponseIntent != null) {
+ intent.putExtra(OtaUtils.EXTRA_OTASP_RESULT_CODE_PENDING_INTENT, otaResponseIntent);
+ }
+
+ Log.v(LOG_TAG, "Starting hfa activation activity");
+ if (showUi) {
+ intent.setClassName(this, HfaActivity.class.getName());
+ startActivity(intent);
+ } else {
+ intent.setClassName(this, HfaService.class.getName());
+ startService(intent);
+ }
+
}
-
- Log.v(LOG_TAG, "Starting hfa activation activity");
- if (showUi) {
- intent.setClassName(this, HfaActivity.class.getName());
- startActivity(intent);
- } else {
- intent.setClassName(this, HfaService.class.getName());
- startService(intent);
- }
-
setResult(RESULT_OK);
}
}
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 4dd8ee2..31337ee 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -434,12 +434,10 @@
PhoneUtils.setAudioMode(mCM);
}
- if (TelephonyCapabilities.supportsOtasp(phone)) {
- cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
- cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
- cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
- cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
- }
+ cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
+ cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
+ cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
+ cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
// XXX pre-load the SimProvider so that it's ready
resolver.getType(Uri.parse("content://icc/adn"));
@@ -759,21 +757,7 @@
cdmaPhoneCallState = new CdmaPhoneCallState();
cdmaPhoneCallState.CdmaPhoneCallStateInit();
}
- if (TelephonyCapabilities.supportsOtasp(phone)) {
- //create instances of CDMA OTA data classes
- if (cdmaOtaProvisionData == null) {
- cdmaOtaProvisionData = new OtaUtils.CdmaOtaProvisionData();
- }
- if (cdmaOtaConfigData == null) {
- cdmaOtaConfigData = new OtaUtils.CdmaOtaConfigData();
- }
- if (cdmaOtaScreenState == null) {
- cdmaOtaScreenState = new OtaUtils.CdmaOtaScreenState();
- }
- if (cdmaOtaInCallScreenUiState == null) {
- cdmaOtaInCallScreenUiState = new OtaUtils.CdmaOtaInCallScreenUiState();
- }
- } else {
+ if (!TelephonyCapabilities.supportsOtasp(phone)) {
//Clean up OTA data in GSM/UMTS. It is valid only for CDMA
clearOtaState();
}
diff --git a/src/com/android/phone/SimContacts.java b/src/com/android/phone/SimContacts.java
index a069e41..8192795 100644
--- a/src/com/android/phone/SimContacts.java
+++ b/src/com/android/phone/SimContacts.java
@@ -39,6 +39,7 @@
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.telecom.PhoneAccount;
+import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
@@ -242,8 +243,13 @@
@Override
protected Uri resolveIntent() {
- Intent intent = getIntent();
- intent.setData(Uri.parse("content://icc/adn"));
+ final Intent intent = getIntent();
+ if (intent.hasExtra("subscription_id")) {
+ final long subId = intent.getLongExtra("subscription_id", -1);
+ intent.setData(Uri.parse("content://icc/adn/subId/" + subId));
+ } else {
+ intent.setData(Uri.parse("content://icc/adn"));
+ }
if (Intent.ACTION_PICK.equals(intent.getAction())) {
// "index" is 1-based
mInitialSelection = intent.getIntExtra("index", 0) - 1;
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 2a14f0b..c48812c 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -37,7 +37,8 @@
private static final String SELECT_CALL_ASSISTANT_PREF_KEY =
"wifi_calling_call_assistant_preference";
- private static final String SIP_SETTINGS_CATEGORY_PREF_KEY = "phone_accounts_sip_settings_key";
+ private static final String SIP_SETTINGS_CATEGORY_PREF_KEY =
+ "phone_accounts_sip_settings_category_key";
private static final String USE_SIP_PREF_KEY = "use_sip_calling_options_key";
private static final String SIP_RECEIVE_CALLS_PREF_KEY = "sip_receive_calls_key";
@@ -104,8 +105,17 @@
? R.array.sip_call_options_wifi_only_entries
: R.array.sip_call_options_entries);
mUseSipCalling.setOnPreferenceChangeListener(this);
- mUseSipCalling.setValueIndex(
- mUseSipCalling.findIndexOfValue(mSipSharedPreferences.getSipCallOption()));
+
+ int optionsValueIndex =
+ mUseSipCalling.findIndexOfValue(mSipSharedPreferences.getSipCallOption());
+ if (optionsValueIndex == -1) {
+ // If the option is invalid (eg. deprecated value), default to SIP_ADDRESS_ONLY.
+ mSipSharedPreferences.setSipCallOption(
+ getResources().getString(R.string.sip_address_only));
+ optionsValueIndex =
+ mUseSipCalling.findIndexOfValue(mSipSharedPreferences.getSipCallOption());
+ }
+ mUseSipCalling.setValueIndex(optionsValueIndex);
mUseSipCalling.setSummary(mUseSipCalling.getEntry());
mSipReceiveCallsPreference = (CheckBoxPreference)
diff --git a/src/com/android/services/telephony/CdmaConnection.java b/src/com/android/services/telephony/CdmaConnection.java
index 5d470ab..1915fe0 100644
--- a/src/com/android/services/telephony/CdmaConnection.java
+++ b/src/com/android/services/telephony/CdmaConnection.java
@@ -79,7 +79,6 @@
EmergencyTonePlayer emergencyTonePlayer,
boolean allowMute,
boolean isOutgoing) {
-
super(connection);
mEmergencyTonePlayer = emergencyTonePlayer;
mAllowMute = allowMute;
diff --git a/src/com/android/services/telephony/GsmConferenceController.java b/src/com/android/services/telephony/GsmConferenceController.java
index ecac404..b6aaaf9 100644
--- a/src/com/android/services/telephony/GsmConferenceController.java
+++ b/src/com/android/services/telephony/GsmConferenceController.java
@@ -33,6 +33,8 @@
* call functionality.
*/
final class GsmConferenceController {
+ private static final int GSM_CONFERENCE_MAX_SIZE = 5;
+
private final Connection.Listener mConnectionListener = new Connection.Listener() {
@Override
public void onStateChanged(Connection c, int state) {
@@ -80,6 +82,15 @@
recalculateConference();
}
+ private boolean isFullConference(Conference conference) {
+ return conference.getConnections().size() >= GSM_CONFERENCE_MAX_SIZE;
+ }
+
+ private boolean participatesInFullConference(Connection connection) {
+ return connection.getConference() != null &&
+ isFullConference(connection.getConference());
+ }
+
/**
* Calculates the conference-capable state of all GSM connections in this connection service.
*/
@@ -91,25 +102,22 @@
// Loop through and collect all calls which are active or holding
for (GsmConnection connection : mGsmConnections) {
- com.android.internal.telephony.Connection radioConnection =
- connection.getOriginalConnection();
- Log.d(this, "recalc - %s %s",
- radioConnection == null ? null : radioConnection.getState(), connection);
+ Log.d(this, "recalc - %s %s", connection.getState(), connection);
- if (radioConnection != null) {
- switch(radioConnection.getState()) {
- case ACTIVE:
+ if (!participatesInFullConference(connection)) {
+ switch (connection.getState()) {
+ case Connection.STATE_ACTIVE:
activeConnections.add(connection);
- break;
- case HOLDING:
+ continue;
+ case Connection.STATE_HOLDING:
backgroundConnections.add(connection);
- break;
+ continue;
default:
- connection.setConferenceableConnections(
- Collections.<Connection>emptyList());
break;
}
}
+
+ connection.setConferenceableConnections(Collections.<Connection>emptyList());
}
Log.v(this, "active: %d, holding: %d",
@@ -128,7 +136,7 @@
}
// Set the conference as conferenceable with all the connections
- if (mGsmConference != null) {
+ if (mGsmConference != null && !isFullConference(mGsmConference)) {
List<Connection> nonConferencedConnections = new ArrayList<>(mGsmConnections.size());
for (GsmConnection c : mGsmConnections) {
if (c.getConference() == null) {
diff --git a/src/com/android/services/telephony/PstnIncomingCallNotifier.java b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
index 0c8f8bc..f4c8a22 100644
--- a/src/com/android/services/telephony/PstnIncomingCallNotifier.java
+++ b/src/com/android/services/telephony/PstnIncomingCallNotifier.java
@@ -17,7 +17,6 @@
package com.android.services.telephony;
import android.content.BroadcastReceiver;
-
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -27,6 +26,7 @@
import android.os.Handler;
import android.os.Message;
import android.os.UserHandle;
+import android.telecom.CallState;
import android.telecom.PhoneAccount;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
@@ -39,6 +39,7 @@
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
+
import com.google.common.base.Preconditions;
import java.util.Objects;
@@ -51,6 +52,7 @@
/** New ringing connection event code. */
private static final int EVENT_NEW_RINGING_CONNECTION = 100;
private static final int EVENT_CDMA_CALL_WAITING = 101;
+ private static final int EVENT_UNKNOWN_CONNECTION = 102;
/** The phone proxy object to listen to. */
private final PhoneProxy mPhoneProxy;
@@ -76,6 +78,9 @@
case EVENT_CDMA_CALL_WAITING:
handleCdmaCallWaiting((AsyncResult) msg.obj);
break;
+ case EVENT_UNKNOWN_CONNECTION:
+ handleNewUnknownConnection((AsyncResult) msg.obj);
+ break;
default:
break;
}
@@ -142,6 +147,8 @@
mHandler, EVENT_NEW_RINGING_CONNECTION, null);
mPhoneBase.registerForCallWaiting(
mHandler, EVENT_CDMA_CALL_WAITING, null);
+ mPhoneBase.registerForUnknownConnection(mHandler, EVENT_UNKNOWN_CONNECTION,
+ null);
}
}
}
@@ -151,6 +158,7 @@
Log.i(this, "Unregistering: %s", mPhoneBase);
mPhoneBase.unregisterForNewRingingConnection(mHandler);
mPhoneBase.unregisterForCallWaiting(mHandler);
+ mPhoneBase.unregisterForUnknownConnection(mHandler);
}
}
@@ -187,6 +195,33 @@
}
}
+ private void handleNewUnknownConnection(AsyncResult asyncResult) {
+ Log.i(this, "handleNewUnknownConnection");
+ if (!(asyncResult.result instanceof Connection)) {
+ Log.w(this, "handleNewUnknownConnection called with non-Connection object");
+ return;
+ }
+ Connection connection = (Connection) asyncResult.result;
+ if (connection != null) {
+ Call call = connection.getCall();
+ if (call != null && call.getState().isAlive()) {
+ addNewUnknownCall(connection);
+ }
+ }
+ }
+
+ private void addNewUnknownCall(Connection connection) {
+ Bundle extras = null;
+ if (connection.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED &&
+ !TextUtils.isEmpty(connection.getAddress())) {
+ extras = new Bundle();
+ Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, connection.getAddress(), null);
+ extras.putParcelable(TelecomManager.EXTRA_UNKNOWN_CALL_HANDLE, uri);
+ }
+ TelecomManager.from(mPhoneProxy.getContext()).addNewUnknownCall(
+ TelecomAccountRegistry.makePstnPhoneAccountHandle(mPhoneProxy), extras);
+ }
+
/**
* Sends the incoming call intent to telecom.
*/
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 9e7589c..1cc6ad6 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -485,7 +485,7 @@
return true;
}
- protected void updateState() {
+ void updateState() {
if (mOriginalConnection == null) {
return;
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index cb7894c..73a57d3 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -40,6 +40,8 @@
import com.android.internal.telephony.cdma.CDMAPhone;
import com.android.phone.MMIDialogActivity;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
/**
@@ -82,6 +84,13 @@
// TODO: We don't check for SecurityException here (requires
// CALL_PRIVILEGED permission).
final Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
+ if (phone == null) {
+ Log.d(this, "onCreateOutgoingConnection, phone is null");
+ return Connection.createFailedConnection(
+ DisconnectCauseUtil.toTelecomDisconnectCause(
+ android.telephony.DisconnectCause.OUTGOING_FAILURE,
+ "Phone is null"));
+ }
number = phone.getVoiceMailNumber();
if (TextUtils.isEmpty(number)) {
Log.d(this, "onCreateOutgoingConnection, no voicemail number set.");
@@ -238,6 +247,57 @@
}
@Override
+ public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+ ConnectionRequest request) {
+ Log.i(this, "onCreateUnknownConnection, request: " + request);
+
+ Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
+ if (phone == null) {
+ return Connection.createFailedConnection(
+ DisconnectCauseUtil.toTelecomDisconnectCause(
+ android.telephony.DisconnectCause.ERROR_UNSPECIFIED));
+ }
+
+ final List<com.android.internal.telephony.Connection> allConnections = new ArrayList<>();
+ final Call ringingCall = phone.getRingingCall();
+ if (ringingCall.hasConnections()) {
+ allConnections.addAll(ringingCall.getConnections());
+ }
+ final Call foregroundCall = phone.getForegroundCall();
+ if (foregroundCall.hasConnections()) {
+ allConnections.addAll(foregroundCall.getConnections());
+ }
+ final Call backgroundCall = phone.getBackgroundCall();
+ if (backgroundCall.hasConnections()) {
+ allConnections.addAll(phone.getBackgroundCall().getConnections());
+ }
+
+ com.android.internal.telephony.Connection unknownConnection = null;
+ for (com.android.internal.telephony.Connection telephonyConnection : allConnections) {
+ if (!isOriginalConnectionKnown(telephonyConnection)) {
+ unknownConnection = telephonyConnection;
+ break;
+ }
+ }
+
+ if (unknownConnection == null) {
+ Log.i(this, "onCreateUnknownConnection, did not find previously unknown connection.");
+ return Connection.createCanceledConnection();
+ }
+
+ TelephonyConnection connection =
+ createConnectionFor(phone, unknownConnection,
+ !unknownConnection.isIncoming() /* isOutgoing */);
+
+ if (connection == null) {
+ return Connection.createCanceledConnection();
+ } else {
+ connection.updateState();
+ return connection;
+ }
+ }
+
+ @Override
public void onConference(Connection connection1, Connection connection2) {
if (connection1 instanceof TelephonyConnection &&
connection2 instanceof TelephonyConnection) {