Fully connect CallsManager with InCallController for outgoing calls.
Change-Id: Ic28fc5ea1e4a76be32fc7bd2d29f9690da959c96
diff --git a/src/com/android/telecomm/Call.java b/src/com/android/telecomm/Call.java
index 9f9a692..905fa6a 100644
--- a/src/com/android/telecomm/Call.java
+++ b/src/com/android/telecomm/Call.java
@@ -16,9 +16,11 @@
package com.android.telecomm;
+import android.os.RemoteException;
import android.telecomm.CallInfo;
import android.telecomm.CallState;
import android.telecomm.ICallService;
+import android.util.Log;
import java.util.Date;
@@ -28,6 +30,7 @@
* connected etc).
*/
final class Call {
+ private static final String TAG = Call.class.getSimpleName();
/**
* Unique identifier for the call as a UUID string.
@@ -129,6 +132,22 @@
setCallService(null);
}
+ /*
+ * Attempts to disconnect the call through the call service.
+ */
+ void disconnect() {
+ if (mCallService == null) {
+ Log.w(TAG, "disconnect() request on a call without a call service.");
+ } else {
+ try {
+ Log.i(TAG, "Send disconnect to call service for call with id " + mId);
+ mCallService.disconnect(mId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Disconnect attempt failed.", e);
+ }
+ }
+ }
+
/**
* @return An object containing read-only information about this call.
*/
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 332eb0a..2a621aa 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -117,7 +117,23 @@
Preconditions.checkState(call.getState() == CallState.DIALING);
addCall(call);
- // TODO(santoscordon): Notify in-call UI.
+
+ mInCallController.addCall(call.toCallInfo());
+ }
+
+ /*
+ * Sends all the live calls to the in-call app if any exist. If there are no live calls, then
+ * tells the in-call controller to unbind since it is not needed.
+ */
+ void updateInCall() {
+ if (mCalls.isEmpty()) {
+ mInCallController.unbind();
+ return;
+ }
+
+ for (Call call : mCalls.values()) {
+ mInCallController.addCall(call.toCallInfo());
+ }
}
/**
@@ -150,7 +166,13 @@
* @param callId The ID of the call.
*/
void disconnectCall(String callId) {
- // TODO(santoscordon): fill in and check that the call is in the active state.
+ Call call = mCalls.get(callId);
+ if (call == null) {
+ Log.e(TAG, "Unknown call (" + callId + ") asked to disconnect");
+ } else {
+ call.disconnect();
+ }
+
}
void markCallAsRinging(String callId) {
@@ -165,9 +187,21 @@
setCallState(callId, CallState.ACTIVE);
}
+ /**
+ * 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.
+ *
+ * @param callId The ID of the call.
+ */
void markCallAsDisconnected(String callId) {
setCallState(callId, CallState.DISCONNECTED);
mCalls.remove(callId);
+
+ // Notify the in-call UI
+ mInCallController.markCallAsDisconnected(callId);
+ if (mCalls.isEmpty()) {
+ mInCallController.unbind();
+ }
}
/**
diff --git a/src/com/android/telecomm/InCallController.java b/src/com/android/telecomm/InCallController.java
index f597030..dedc21c 100644
--- a/src/com/android/telecomm/InCallController.java
+++ b/src/com/android/telecomm/InCallController.java
@@ -22,6 +22,7 @@
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
+import android.telecomm.CallInfo;
import android.telecomm.IInCallService;
import android.util.Log;
@@ -64,7 +65,7 @@
/**
* Class name of the component within in-call app which implements {@link IInCallService}.
*/
- private static final String IN_CALL_SERVICE_CLASS_NAME = "com.android.incall.InCallService";
+ private static final String IN_CALL_SERVICE_CLASS_NAME = "com.android.incallui.InCallService";
/** Maintains a binding connection to the in-call app. */
private final InCallServiceConnection mConnection = new InCallServiceConnection();
@@ -88,42 +89,95 @@
}
/**
- * Binds to the in-call app if not already connected by binding directly to the saved
- * component name of the {@link IInCallService} implementation.
+ * Indicates to the in-call app that a new call has been created and an appropriate
+ * user-interface should be built and shown to notify the user. Information about the call
+ * including its current state is passed in through the callInfo object.
*
- * @param context The application context.
+ * @param callInfo Details about the new call.
*/
- void connect(Context context) {
- ThreadUtil.checkOnMainThread();
- if (mInCallService == null) {
- ComponentName component =
- new ComponentName(IN_CALL_PACKAGE_NAME, IN_CALL_SERVICE_CLASS_NAME);
-
- Intent serviceIntent = new Intent(IInCallService.class.getName());
- serviceIntent.setComponent(component);
-
- if (!context.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
- Log.e(TAG, "Could not connect to the in-call app (" + component + ")");
-
- // TODO(santoscordon): Implement retry or fall-back-to-default logic.
+ void addCall(CallInfo callInfo) {
+ try {
+ if (mInCallService == null) {
+ bind();
+ } else {
+ // TODO(santoscordon): Protect against logging phone number.
+ Log.i(TAG, "Adding call: " + callInfo);
+ mInCallService.addCall(callInfo);
}
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception attempting to addCall.", e);
+ }
+ }
+
+ /**
+ * Indicates to the in-call app that a call has moved to the active state.
+ *
+ * @param callId The identifier of the call that became active.
+ */
+ void markCallAsActive(String callId) {
+ try {
+ if (mInCallService != null) {
+ Log.i(TAG, "Mark call as ACTIVE: " + callId);
+ mInCallService.setActive(callId);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception attempting to markCallAsActive.", e);
+ }
+ }
+
+ /**
+ * Indicates to the in-call app that a call has been disconnected and the user should be
+ * notified.
+ *
+ * @param callId The identifier of the call that was disconnected.
+ */
+ void markCallAsDisconnected(String callId) {
+ try {
+ if (mInCallService != null) {
+ Log.i(TAG, "Mark call as DISCONNECTED: " + callId);
+ mInCallService.setDisconnected(callId);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception attempting to markCallAsDisconnected.", e);
}
}
/**
* Unbinds an existing bound connection to the in-call app.
- *
- * @param context The application context.
*/
- void disconnect(Context context) {
+ void unbind() {
ThreadUtil.checkOnMainThread();
if (mInCallService != null) {
- context.unbindService(mConnection);
+ Log.i(TAG, "Unbinding from InCallService");
+ TelecommApp.getInstance().unbindService(mConnection);
mInCallService = null;
}
}
/**
+ * Binds to the in-call app if not already connected by binding directly to the saved
+ * component name of the {@link IInCallService} implementation.
+ */
+ private void bind() {
+ ThreadUtil.checkOnMainThread();
+ if (mInCallService == null) {
+ ComponentName component =
+ new ComponentName(IN_CALL_PACKAGE_NAME, IN_CALL_SERVICE_CLASS_NAME);
+ Log.i(TAG, "Attempting to bind to InCallService: " + component);
+
+ Intent serviceIntent = new Intent(IInCallService.class.getName());
+ serviceIntent.setComponent(component);
+
+ Context context = TelecommApp.getInstance();
+ if (!context.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
+ Log.e(TAG, "Could not connect to the in-call app (" + component + ")");
+
+ // TODO(santoscordon): Implement retry or fall-back-to-default logic.
+ }
+ }
+ }
+
+ /**
* Persists the {@link IInCallService} instance and starts the communication between
* CallsManager and in-call app by sending the first update to in-call app. This method is
* called after a successful binding connection is established.
@@ -141,7 +195,11 @@
mInCallService = null;
}
- update();
+ // Upon successful connection, send the state of the world to the in-call app.
+ if (mInCallService != null) {
+ mCallsManager.updateInCall();
+ }
+
}
/**
@@ -151,11 +209,4 @@
ThreadUtil.checkOnMainThread();
mInCallService = null;
}
-
- /**
- * Gathers the list of current calls from CallsManager and sends them to the in-call app.
- */
- private void update() {
- // TODO(santoscordon): mInCallService.sendCalls(CallsManager.getCallList());
- }
}
diff --git a/src/com/android/telecomm/TelecommApp.java b/src/com/android/telecomm/TelecommApp.java
new file mode 100644
index 0000000..e0a3bf6
--- /dev/null
+++ b/src/com/android/telecomm/TelecommApp.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.app.Application;
+
+/**
+ * Top-level Application class for Telecomm.
+ */
+public final class TelecommApp extends Application {
+
+ // Singleton instance of TelecommApp.
+ private static TelecommApp sInstance;
+
+ /** {@inheritDoc} */
+ @Override public void onCreate() {
+ super.onCreate();
+ sInstance = this;
+ }
+
+ public static TelecommApp getInstance() {
+ if (null == sInstance) {
+ throw new IllegalStateException("No TelecommApp running.");
+ }
+ return sInstance;
+ }
+}