Merge changes from topic 'mwd-merge-042415'
* changes:
Merge commit '3d8d22e' into merge2
Merge commit 'c5fca4f' into merge2
Merge commit 'e084cf0' into merge2
Merge commit '554f349' into merge2
Merge commit '9c5c993' into merge2
diff --git a/src/com/android/phone/TimeConsumingPreferenceActivity.java b/src/com/android/phone/TimeConsumingPreferenceActivity.java
index bab9469..08a5a95 100644
--- a/src/com/android/phone/TimeConsumingPreferenceActivity.java
+++ b/src/com/android/phone/TimeConsumingPreferenceActivity.java
@@ -179,6 +179,8 @@
public void onException(Preference preference, CommandException exception) {
if (exception.getCommandError() == CommandException.Error.FDN_CHECK_FAILURE) {
onError(preference, FDN_CHECK_FAILURE);
+ } else if (exception.getCommandError() == CommandException.Error.RADIO_NOT_AVAILABLE) {
+ onError(preference, RADIO_OFF_ERROR);
} else {
preference.setEnabled(false);
onError(preference, EXCEPTION_ERROR);
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 455e034..e7a02ec 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -16,22 +16,26 @@
package com.android.services.telephony;
+import android.content.ComponentName;
+import android.content.Context;
import android.net.Uri;
+import android.telecom.Conference.Listener;
import android.telecom.Conference;
import android.telecom.ConferenceParticipant;
+import android.telecom.Connection.VideoProvider;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
import android.telecom.Log;
import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
import android.telecom.VideoProfile;
-import android.telecom.Conference.Listener;
-import android.telecom.Connection.VideoProvider;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
import com.android.phone.PhoneUtils;
+import com.android.phone.R;
import java.util.ArrayList;
import java.util.HashSet;
@@ -171,6 +175,12 @@
int capabilites = ImsConference.this.getConnectionCapabilities();
setConnectionCapabilities(applyVideoCapabilities(capabilites, connectionCapabilities));
}
+
+ @Override
+ public void onStatusHintsChanged(Connection c, StatusHints statusHints) {
+ Log.v(this, "onStatusHintsChanged");
+ updateStatusHints();
+ }
};
/**
@@ -409,6 +419,26 @@
}
/**
+ * Determines if this conference is hosted on the current device or the peer device.
+ *
+ * @return {@code true} if this conference is hosted on the current device, {@code false} if it
+ * is hosted on the peer device.
+ */
+ public boolean isConferenceHost() {
+ if (mConferenceHost == null) {
+ return false;
+ }
+ com.android.internal.telephony.Connection originalConnection =
+ mConferenceHost.getOriginalConnection();
+ if (!(originalConnection instanceof ImsPhoneConnection)) {
+ return false;
+ }
+
+ ImsPhoneConnection imsPhoneConnection = (ImsPhoneConnection) originalConnection;
+ return imsPhoneConnection.isMultiparty() && imsPhoneConnection.isConferenceHost();
+ }
+
+ /**
* Updates the manage conference capability of the conference. Where there are one or more
* conference event package participants, the conference management is permitted. Where there
* are no conference event package participants, conference management is not permitted.
@@ -444,6 +474,7 @@
mConferenceHost.addConnectionListener(mConferenceHostListener);
mConferenceHost.addTelephonyConnectionListener(mTelephonyConnectionListener);
setState(mConferenceHost.getState());
+ updateStatusHints();
}
/**
@@ -605,6 +636,8 @@
setDisconnected(new DisconnectCause(DisconnectCause.OTHER));
destroy();
}
+
+ updateStatusHints();
}
/**
@@ -642,6 +675,27 @@
}
}
+ private void updateStatusHints() {
+ if (mConferenceHost == null) {
+ setStatusHints(null);
+ return;
+ }
+
+ if (mConferenceHost.isWifi()) {
+ Phone phone = mConferenceHost.getPhone();
+ if (phone != null) {
+ Context context = phone.getContext();
+ setStatusHints(new StatusHints(
+ new ComponentName(context, TelephonyConnectionService.class),
+ context.getString(R.string.status_hint_label_wifi_call),
+ R.drawable.ic_signal_wifi_4_bar_24dp,
+ null /* extras */));
+ }
+ } else {
+ setStatusHints(null);
+ }
+ }
+
/**
* Builds a string representation of the {@link ImsConference}.
*
diff --git a/src/com/android/services/telephony/ImsConferenceController.java b/src/com/android/services/telephony/ImsConferenceController.java
index 249d639..b266b81 100644
--- a/src/com/android/services/telephony/ImsConferenceController.java
+++ b/src/com/android/services/telephony/ImsConferenceController.java
@@ -16,6 +16,8 @@
package com.android.services.telephony;
+import com.android.internal.telephony.imsphone.ImsPhoneConnection;
+
import android.net.Uri;
import android.telecom.Conference;
import android.telecom.Connection;
@@ -155,6 +157,15 @@
Log.d(this, "recalc - %s %s", connection.getState(), connection);
}
+ // If this connection is a member of a conference hosted on another device, it is not
+ // conferenceable with any other connections.
+ if (isMemberOfPeerConference(connection)) {
+ if (Log.VERBOSE) {
+ Log.v(this, "Skipping connection in peer conference: %s", connection);
+ }
+ continue;
+ }
+
switch (connection.getState()) {
case Connection.STATE_ACTIVE:
activeConnections.add(connection);
@@ -168,11 +179,18 @@
connection.setConferenceableConnections(Collections.<Connection>emptyList());
}
- for (Conference conference : mImsConferences) {
+ for (ImsConference conference : mImsConferences) {
if (Log.DEBUG) {
Log.d(this, "recalc - %s %s", conference.getState(), conference);
}
+ if (!conference.isConferenceHost()) {
+ if (Log.VERBOSE) {
+ Log.v(this, "skipping conference (not hosted on this device): %s", conference);
+ }
+ continue;
+ }
+
switch (conference.getState()) {
case Connection.STATE_ACTIVE:
activeConnections.add(conference);
@@ -209,6 +227,16 @@
// Set the conference as conferenceable with all the connections
for (ImsConference conference : mImsConferences) {
+ // If this conference is not being hosted on the current device, we cannot conference it
+ // with any other connections.
+ if (!conference.isConferenceHost()) {
+ if (Log.VERBOSE) {
+ Log.v(this, "skipping conference (not hosted on this device): %s",
+ conference);
+ }
+ continue;
+ }
+
List<Connection> nonConferencedConnections =
new ArrayList<>(mTelephonyConnections.size());
for (Connection c : mTelephonyConnections) {
@@ -224,6 +252,27 @@
}
/**
+ * Determines if a connection is a member of a conference hosted on another device.
+ *
+ * @param connection The connection.
+ * @return {@code true} if the connection is a member of a conference hosted on another device.
+ */
+ private boolean isMemberOfPeerConference(Connection connection) {
+ if (!(connection instanceof TelephonyConnection)) {
+ return false;
+ }
+ TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
+ com.android.internal.telephony.Connection originalConnection =
+ telephonyConnection.getOriginalConnection();
+ if (!(originalConnection instanceof ImsPhoneConnection)) {
+ return false;
+ }
+
+ ImsPhoneConnection imsPhoneConnection = (ImsPhoneConnection) originalConnection;
+ return imsPhoneConnection.isMultiparty() && !imsPhoneConnection.isConferenceHost();
+ }
+
+ /**
* Starts a new ImsConference for a connection which just entered a multiparty state.
*/
private void recalculateConference() {
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 0c3974a..3beabf4 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -816,6 +816,13 @@
}
/**
+ * Whether the call is using wifi.
+ */
+ boolean isWifi() {
+ return mIsWifi;
+ }
+
+ /**
* Sets the current call audio quality. Used during rebuild of the capabilities
* to set or unset the {@link Connection#CAPABILITY_HIGH_DEF_AUDIO} capability.
*