Add hold support to Telecomm service
Bug: 13169202
Change-Id: Ic2c1989de41c91d237841581e6fa531cb71d4eed
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 0b60c4a..7eb4a6f 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -271,6 +271,28 @@
}
/**
+ * Puts the call on hold if it is currently active.
+ */
+ void hold() {
+ Preconditions.checkNotNull(mCallService);
+
+ if (mState == CallState.ACTIVE) {
+ mCallService.hold(mId);
+ }
+ }
+
+ /**
+ * Releases the call from hold if it is currently active.
+ */
+ void unhold() {
+ Preconditions.checkNotNull(mCallService);
+
+ if (mState == CallState.ON_HOLD) {
+ mCallService.unhold(mId);
+ }
+ }
+
+ /**
* @return An object containing read-only information about this call.
*/
CallInfo toCallInfo() {
diff --git a/src/com/android/telecomm/CallServiceAdapter.java b/src/com/android/telecomm/CallServiceAdapter.java
index 1e830d5..e30d338 100644
--- a/src/com/android/telecomm/CallServiceAdapter.java
+++ b/src/com/android/telecomm/CallServiceAdapter.java
@@ -172,6 +172,16 @@
});
}
+ /** {@inheritDoc} */
+ @Override public void setOnHold(final String callId) {
+ checkValidCallId(callId);
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ mCallsManager.markCallAsOnHold(callId);
+ }
+ });
+ }
+
/**
* Adds the specified call ID to the list of pending outgoing call IDs.
* TODO(gilad): Consider passing the call processor (instead of the ID) both here and in the
diff --git a/src/com/android/telecomm/CallServiceWrapper.java b/src/com/android/telecomm/CallServiceWrapper.java
index 807f427..5585fc7 100644
--- a/src/com/android/telecomm/CallServiceWrapper.java
+++ b/src/com/android/telecomm/CallServiceWrapper.java
@@ -146,6 +146,28 @@
}
}
+ /** See {@link ICallService#hold}. */
+ public void hold(String callId) {
+ if (isServiceValid("hold")) {
+ try {
+ mServiceInterface.hold(callId);
+ } catch (RemoteException e) {
+ Log.e(this, e, "Failed to put on hold for call %s", callId);
+ }
+ }
+ }
+
+ /** See {@link ICallService#unhold}. */
+ public void unhold(String callId) {
+ if (isServiceValid("unhold")) {
+ try {
+ mServiceInterface.unhold(callId);
+ } catch (RemoteException e) {
+ Log.e(this, e, "Failed to remove from hold for call %s", callId);
+ }
+ }
+ }
+
/**
* Starts retrieval of details for an incoming call. Details are returned through the
* call-service adapter using the specified call ID. Upon failure, the specified error callback
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 4b4de71..2f1b764 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -258,6 +258,40 @@
audioManager.abandonAudioFocusForCall();
}
+ /**
+ * Instructs Telecomm to put the specified call on hold. Intended to be invoked by the
+ * in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered by
+ * the user hitting the hold button during an active call.
+ *
+ * @param callId The ID of the call.
+ */
+ void holdCall(String callId) {
+ Call call = mCalls.get(callId);
+ if (call == null) {
+ Log.w(this, "Unknown call (%s) asked to be put on hold", callId);
+ } else {
+ Log.d(this, "Putting call on hold: (%s)", callId);
+ call.hold();
+ }
+ }
+
+ /**
+ * Instructs Telecomm to release the specified call from hold. Intended to be invoked by
+ * the in-call app through {@link InCallAdapter} for an ongoing call. This is usually triggered
+ * by the user hitting the hold button during a held call.
+ *
+ * @param callId The ID of the call
+ */
+ void unholdCall(String callId) {
+ Call call = mCalls.get(callId);
+ if (call == null) {
+ Log.w(this, "Unknown call (%s) asked to be removed from hold", callId);
+ } else {
+ Log.d(this, "Removing call from hold: (%s)", callId);
+ call.unhold();
+ }
+ }
+
void markCallAsRinging(String callId) {
setCallState(callId, CallState.RINGING);
}
@@ -282,6 +316,13 @@
audioManager.setSpeakerphoneOn(false);
}
+ void markCallAsOnHold(String callId) {
+ setCallState(callId, CallState.ON_HOLD);
+
+ // Notify the in-call UI
+ mInCallController.markCallAsOnHold(callId);
+ }
+
/**
* Marks the specified call as DISCONNECTED and notifies the in-call app. If this was the last
* live call, then also disconnect from the in-call controller.
@@ -382,6 +423,7 @@
switch (call.getState()) {
case DIALING:
case ACTIVE:
+ case ON_HOLD:
callState = TelephonyManager.EXTRA_STATE_OFFHOOK;
break;
diff --git a/src/com/android/telecomm/InCallAdapter.java b/src/com/android/telecomm/InCallAdapter.java
index 7232abf..37dc3b9 100644
--- a/src/com/android/telecomm/InCallAdapter.java
+++ b/src/com/android/telecomm/InCallAdapter.java
@@ -68,4 +68,24 @@
}
});
}
+
+ /** {@inheritDoc} */
+ @Override
+ public void holdCall(final String callId) {
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ mCallsManager.holdCall(callId);
+ }
+ });
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void unholdCall(final String callId) {
+ mHandler.post(new Runnable() {
+ @Override public void run() {
+ mCallsManager.unholdCall(callId);
+ }
+ });
+ }
}
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index 4da9190..4f863c5 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -141,6 +141,17 @@
}
}
+ void markCallAsOnHold(String callId) {
+ try {
+ if (mInCallService != null) {
+ Log.i(this, "Mark call as HOLD: %s", callId);
+ mInCallService.setOnHold(callId);
+ }
+ } catch (RemoteException e) {
+ Log.e(this, e, "Exception attempting to markCallAsHeld.");
+ }
+ }
+
/**
* Unbinds an existing bound connection to the in-call app.
*/