Capability and UI support for merge/swap/addcall
Change-Id: I0d2a9b855028ba2e82e4ffd627389000e3cc1891
diff --git a/common/src/com/android/services/telephony/common/Call.java b/common/src/com/android/services/telephony/common/Call.java
index 0b4abb7..088a06d 100644
--- a/common/src/com/android/services/telephony/common/Call.java
+++ b/common/src/com/android/services/telephony/common/Call.java
@@ -47,11 +47,15 @@
/**
* Defines a set of capabilities that a call can have as a bit mask.
+ * TODO: Should some of these be capabilities of the Phone instead of the call?
*/
public static class Capabilities {
- public static final int HOLD = 0x00000001; /* has ability to hold the call */
+ public static final int HOLD = 0x00000001; /* has ability to hold the call */
+ public static final int MERGE_CALLS = 0x00000002; /* has ability to merge calls */
+ public static final int SWAP_CALLS = 0x00000004; /* swap with a background call */
+ public static final int ADD_CALL = 0x00000008; /* add another call to this one */
- public static final int ALL = HOLD;
+ public static final int ALL = HOLD | MERGE_CALLS | SWAP_CALLS | ADD_CALL;
}
/**
@@ -271,6 +275,8 @@
buffer.append(STATE_MAP.get(mState));
buffer.append(", disconnect_cause: ");
buffer.append(getDisconnectCause().toString());
+ buffer.append(", capabilities: ");
+ buffer.append(Integer.toHexString(getCapabilities()));
return buffer.toString();
}
}
diff --git a/common/src/com/android/services/telephony/common/ICallCommandService.aidl b/common/src/com/android/services/telephony/common/ICallCommandService.aidl
index defeeef..5969575 100644
--- a/common/src/com/android/services/telephony/common/ICallCommandService.aidl
+++ b/common/src/com/android/services/telephony/common/ICallCommandService.aidl
@@ -45,6 +45,23 @@
void hold(int callId, boolean hold);
/**
+ * Merge foreground and background calls.
+ */
+ void merge();
+
+ /**
+ * Swap foreground and background calls.
+ */
+ void swap();
+
+ /**
+ * Add another call.
+ * TODO(klp): Should this go through the service at all?
+ * It could just as easily call dialer directly.
+ */
+ void addCall();
+
+ /**
* Mute the phone.
*/
void mute(boolean onOff);
diff --git a/src/com/android/phone/CallCommandService.java b/src/com/android/phone/CallCommandService.java
index e5adb52..01b4dd8 100644
--- a/src/com/android/phone/CallCommandService.java
+++ b/src/com/android/phone/CallCommandService.java
@@ -16,11 +16,14 @@
package com.android.phone;
+import android.bluetooth.IBluetoothHeadsetPhone;
import android.content.Context;
+import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;
import com.android.internal.telephony.CallManager;
+import com.android.internal.telephony.PhoneConstants;
import com.android.phone.CallModeler.CallResult;
import com.android.services.telephony.common.AudioMode;
import com.android.services.telephony.common.Call;
@@ -129,10 +132,52 @@
}
@Override
+ public void merge() {
+ if (PhoneUtils.okToMergeCalls(mCallManager)) {
+ PhoneUtils.mergeCalls(mCallManager);
+ }
+ }
+
+ @Override
+ public void addCall() {
+ // start new call checks okToAddCall() already
+ PhoneUtils.startNewCall(mCallManager);
+ }
+
+
+ @Override
+ public void swap() {
+ if (!PhoneUtils.okToSwapCalls(mCallManager)) {
+ // TODO: throw an error instead?
+ return;
+ }
+
+ // Swap the fg and bg calls.
+ // In the future we may provides some way for user to choose among
+ // multiple background calls, for now, always act on the first background calll.
+ PhoneUtils.switchHoldingAndActive(mCallManager.getFirstActiveBgCall());
+
+ final PhoneGlobals mApp = PhoneGlobals.getInstance();
+
+ // If we have a valid BluetoothPhoneService then since CDMA network or
+ // Telephony FW does not send us information on which caller got swapped
+ // we need to update the second call active state in BluetoothPhoneService internally
+ if (mCallManager.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+ final IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService();
+ if (btPhone != null) {
+ try {
+ btPhone.cdmaSwapSecondCallState();
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ }
+ }
+
+ @Override
public void mute(boolean onOff) {
try {
- //PhoneUtils.setMute(onOff);
- mAudioRouter.setAudioMode(onOff ? AudioMode.BLUETOOTH : AudioMode.EARPIECE);
+ PhoneUtils.setMute(onOff);
} catch (Exception e) {
Log.e(TAG, "Error during mute().", e);
}
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index dcd11f7..154b155 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -29,6 +29,7 @@
import com.android.internal.telephony.CallManager;
import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyCapabilities;
import com.android.services.telephony.common.Call;
@@ -264,7 +265,10 @@
changed = true;
}
- final int newCapabilities = getCapabilitiesFor(connection);
+ /**
+ * !!! Uses values from connection and call collected above so this part must be last !!!
+ */
+ final int newCapabilities = getCapabilitiesFor(connection, call);
if (call.getCapabilities() != newCapabilities) {
call.setCapabilities(newCapabilities);
changed = true;
@@ -276,14 +280,44 @@
/**
* Returns a mask of capabilities for the connection such as merge, hold, etc.
*/
- private int getCapabilitiesFor(Connection connection) {
+ private int getCapabilitiesFor(Connection connection, Call call) {
+ final boolean callIsActive = (call.getState() == Call.State.ACTIVE);
+ final Phone phone = connection.getCall().getPhone();
+
+ final boolean canHold = TelephonyCapabilities.supportsAnswerAndHold(phone);
+ boolean canAddCall = false;
+ boolean canMergeCall = false;
+ boolean canSwapCall = false;
+
+ // only applies to active calls
+ if (callIsActive) {
+ canAddCall = PhoneUtils.okToAddCall(mCallManager);
+ canMergeCall = PhoneUtils.okToMergeCalls(mCallManager);
+ canSwapCall = PhoneUtils.okToSwapCalls(mCallManager);
+ }
+
+ // special rules section!
+ // CDMA always has Add
+ if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+ canAddCall = true;
+ } else {
+ // if neither merge nor add is on...then allow add
+ canAddCall |= !(canAddCall || canMergeCall);
+ }
+
int retval = 0x0;
-
- final boolean hold = TelephonyCapabilities.supportsAnswerAndHold(connection.getCall().getPhone());
-
- if (hold) {
+ if (canHold) {
retval |= Capabilities.HOLD;
}
+ if (canAddCall) {
+ retval |= Capabilities.ADD_CALL;
+ }
+ if (canMergeCall) {
+ retval |= Capabilities.MERGE_CALLS;
+ }
+ if (canSwapCall) {
+ retval |= Capabilities.SWAP_CALLS;
+ }
return retval;
}
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 8f52f29..c672353 100644
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -3507,26 +3507,6 @@
// to lose any previous digits from the current call; see the TODO
// comment on DTMFTwelvKeyDialer.clearDigits() for more info.)
mDialer.clearDigits();
-
- // Swap the fg and bg calls.
- // In the future we may provides some way for user to choose among
- // multiple background calls, for now, always act on the first background calll.
- PhoneUtils.switchHoldingAndActive(mCM.getFirstActiveBgCall());
-
- // If we have a valid BluetoothPhoneService then since CDMA network or
- // Telephony FW does not send us information on which caller got swapped
- // we need to update the second call active state in BluetoothPhoneService internally
- if (mCM.getBgPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
- IBluetoothHeadsetPhone btPhone = mApp.getBluetoothPhoneService();
- if (btPhone != null) {
- try {
- btPhone.cdmaSwapSecondCallState();
- } catch (RemoteException e) {
- Log.e(LOG_TAG, Log.getStackTraceString(new Throwable()));
- }
- }
- }
-
}
/**