Merge "Fix incorrect PreferenceScreen key for SIP account settings" into lmp-dev
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/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 5d00163..26e31b0 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -1674,7 +1674,7 @@
IccIoResult response =
(IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO,
- new IccAPDUArgument(fileID, command, -1, p1, p2, p3, filePath));
+ new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath));
if (DBG) {
log("Exchange SIM_IO [R]" + response);
diff --git a/src/com/android/services/telephony/CdmaConferenceController.java b/src/com/android/services/telephony/CdmaConferenceController.java
index ab126ca..d0cf6de 100644
--- a/src/com/android/services/telephony/CdmaConferenceController.java
+++ b/src/com/android/services/telephony/CdmaConferenceController.java
@@ -89,15 +89,27 @@
void add(final CdmaConnection connection) {
if (!mCdmaConnections.isEmpty() && connection.isOutgoing()) {
- connection.forceAsDialing(true);
// There already exists a connection, so this will probably result in a conference once
- // it is added. For connections which are added while another connection exists, we
- // mark them as "dialing" for set amount of time to give the user time to see their
- // new call as "Dialing" before it turns into a conference call.
+ // it is added. For outgoing connections which are added while another connection
+ // exists, we mark them as "dialing" for a set amount of time to give the user time to
+ // see their new call as "Dialing" before it turns into a conference call.
+ // During that time, we also mark the other calls as "held" or else it can cause issues
+ // due to having an ACTIVE and a DIALING call simultaneously.
+ connection.forceAsDialing(true);
+ final List<CdmaConnection> connectionsToReset =
+ new ArrayList<>(mCdmaConnections.size());
+ for (CdmaConnection current : mCdmaConnections) {
+ if (current.setHoldingForConference()) {
+ connectionsToReset.add(current);
+ }
+ }
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
connection.forceAsDialing(false);
+ for (CdmaConnection current : connectionsToReset) {
+ current.resetStateForConference();
+ }
addInternal(connection);
}
}, ADD_OUTGOING_CONNECTION_DELAY_MILLIS);
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..654150c 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,29 @@
}
}
+ private void handleNewUnknownConnection(AsyncResult asyncResult) {
+ Log.i(this, "handleNewUnknownConnection");
+ 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 9394b94..f7c6510 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -41,6 +41,7 @@
private static final int MSG_PRECISE_CALL_STATE_CHANGED = 1;
private static final int MSG_RINGBACK_TONE = 2;
private static final int MSG_HANDOVER_STATE_CHANGED = 3;
+ private static final int MSG_DISCONNECT = 4;
private final Handler mHandler = new Handler() {
@Override
@@ -68,6 +69,9 @@
}
setRingbackRequested((Boolean) ((AsyncResult) msg.obj).result);
break;
+ case MSG_DISCONNECT:
+ updateState();
+ break;
}
}
};
@@ -364,6 +368,7 @@
getPhone().unregisterForPreciseCallStateChanged(mHandler);
getPhone().unregisterForRingbackTone(mHandler);
getPhone().unregisterForHandoverStateChanged(mHandler);
+ getPhone().unregisterForDisconnect(mHandler);
}
mOriginalConnection = originalConnection;
getPhone().registerForPreciseCallStateChanged(
@@ -371,6 +376,7 @@
getPhone().registerForHandoverStateChanged(
mHandler, MSG_HANDOVER_STATE_CHANGED, null);
getPhone().registerForRingbackTone(mHandler, MSG_RINGBACK_TONE, null);
+ getPhone().registerForDisconnect(mHandler, MSG_DISCONNECT, null);
mOriginalConnection.addPostDialListener(mPostDialListener);
mOriginalConnection.addListener(mOriginalConnectionListener);
@@ -381,7 +387,7 @@
setVideoProvider(mOriginalConnection.getVideoProvider());
setAudioQuality(mOriginalConnection.getAudioQuality());
- updateAddress();
+ updateState();
}
protected void hangup(int telephonyDisconnectCode) {
@@ -655,6 +661,22 @@
return mAudioQuality;
}
+ void resetStateForConference() {
+ if (getState() == Connection.STATE_HOLDING) {
+ if (mOriginalConnection.getState() == Call.State.ACTIVE) {
+ setActive();
+ }
+ }
+ }
+
+ boolean setHoldingForConference() {
+ if (getState() == Connection.STATE_ACTIVE) {
+ setOnHold();
+ return true;
+ }
+ return false;
+ }
+
private static Uri getAddressFromNumber(String number) {
// Address can be null for blocked calls.
if (number == null) {
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index cb7894c..e3b78d4 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;
/**
@@ -238,6 +240,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();
+ }
+
+ Connection connection =
+ createConnectionFor(phone, unknownConnection,
+ !unknownConnection.isIncoming() /* isOutgoing */);
+
+ if (connection == null) {
+ connection = Connection.createCanceledConnection();
+ return Connection.createCanceledConnection();
+ } else {
+ return connection;
+ }
+ }
+
+ @Override
public void onConference(Connection connection1, Connection connection2) {
if (connection1 instanceof TelephonyConnection &&
connection2 instanceof TelephonyConnection) {