summaryrefslogtreecommitdiffstats
path: root/telecomm/java
diff options
context:
space:
mode:
Diffstat (limited to 'telecomm/java')
-rw-r--r--telecomm/java/android/telecomm/CallAudioState.aidl19
-rw-r--r--telecomm/java/android/telecomm/CallAudioState.java160
-rw-r--r--telecomm/java/android/telecomm/CallInfo.aidl19
-rw-r--r--telecomm/java/android/telecomm/CallInfo.java168
-rw-r--r--telecomm/java/android/telecomm/CallService.java316
-rw-r--r--telecomm/java/android/telecomm/CallServiceAdapter.java157
-rw-r--r--telecomm/java/android/telecomm/CallServiceDescriptor.aidl19
-rw-r--r--telecomm/java/android/telecomm/CallServiceDescriptor.java209
-rw-r--r--telecomm/java/android/telecomm/CallServiceLookupResponse.java51
-rw-r--r--telecomm/java/android/telecomm/CallServiceProvider.java109
-rw-r--r--telecomm/java/android/telecomm/CallServiceSelector.java207
-rw-r--r--telecomm/java/android/telecomm/CallState.java81
-rw-r--r--telecomm/java/android/telecomm/GatewayInfo.aidl19
-rw-r--r--telecomm/java/android/telecomm/GatewayInfo.java106
-rw-r--r--telecomm/java/android/telecomm/InCallAdapter.java129
-rw-r--r--telecomm/java/android/telecomm/InCallService.java173
-rw-r--r--telecomm/java/android/telecomm/README2
-rw-r--r--telecomm/java/android/telecomm/TelecommConstants.java77
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallService.aidl148
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl101
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallServiceLookupResponse.aidl36
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallServiceProvider.aidl48
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallServiceSelectionResponse.aidl38
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallServiceSelector.aidl91
-rw-r--r--telecomm/java/com/android/internal/telecomm/ICallSwitchabilityResponse.aidl36
-rw-r--r--telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl86
-rw-r--r--telecomm/java/com/android/internal/telecomm/IInCallService.aidl85
27 files changed, 2690 insertions, 0 deletions
diff --git a/telecomm/java/android/telecomm/CallAudioState.aidl b/telecomm/java/android/telecomm/CallAudioState.aidl
new file mode 100644
index 0000000..ae64567
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallAudioState.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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 android.telecomm;
+
+parcelable CallAudioState;
diff --git a/telecomm/java/android/telecomm/CallAudioState.java b/telecomm/java/android/telecomm/CallAudioState.java
new file mode 100644
index 0000000..d9a0090
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallAudioState.java
@@ -0,0 +1,160 @@
+/*
+ * 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 android.telecomm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * Encapsulates all audio states during a call.
+ */
+public final class CallAudioState implements Parcelable {
+ /** Direct the audio stream through the device's earpiece. */
+ public static int ROUTE_EARPIECE = 0x00000001;
+
+ /** Direct the audio stream through Bluetooth. */
+ public static int ROUTE_BLUETOOTH = 0x00000002;
+
+ /** Direct the audio stream through a wired headset. */
+ public static int ROUTE_WIRED_HEADSET = 0x00000004;
+
+ /** Direct the audio stream through the device's spakerphone. */
+ public static int ROUTE_SPEAKER = 0x00000008;
+
+ /**
+ * Direct the audio stream through the device's earpiece or wired headset if one is
+ * connected.
+ */
+ public static int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET;
+
+ /** Bit mask of all possible audio routes. */
+ public static int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
+ ROUTE_SPEAKER;
+
+ /** True if the call is muted, false otherwise. */
+ public final boolean isMuted;
+
+ /** The route to use for the audio stream. */
+ public final int route;
+
+ /** Bit vector of all routes supported by this call. */
+ public final int supportedRouteMask;
+
+ /** @hide */
+ public CallAudioState(boolean isMuted, int route, int supportedRouteMask) {
+ this.isMuted = isMuted;
+ this.route = route;
+ this.supportedRouteMask = supportedRouteMask;
+ }
+
+ /** @hide */
+ public CallAudioState(CallAudioState state) {
+ isMuted = state.isMuted;
+ route = state.route;
+ supportedRouteMask = state.supportedRouteMask;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof CallAudioState)) {
+ return false;
+ }
+ CallAudioState state = (CallAudioState) obj;
+ return isMuted == state.isMuted && route == state.route &&
+ supportedRouteMask == state.supportedRouteMask;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(Locale.US,
+ "[CallAudioState isMuted: %b, route; %s, supportedRouteMask: %s]",
+ isMuted, audioRouteToString(route), audioRouteToString(supportedRouteMask));
+ }
+
+ /** @hide */
+ public static String audioRouteToString(int route) {
+ if (route == 0 || (route & ~ROUTE_ALL) != 0x0) {
+ return "UNKNOWN";
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) {
+ listAppend(buffer, "EARPIECE");
+ }
+ if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) {
+ listAppend(buffer, "BLUETOOTH");
+ }
+ if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) {
+ listAppend(buffer, "WIRED_HEADSET");
+ }
+ if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) {
+ listAppend(buffer, "SPEAKER");
+ }
+
+ return buffer.toString();
+ }
+
+ private static void listAppend(StringBuffer buffer, String str) {
+ if (buffer.length() > 0) {
+ buffer.append(", ");
+ }
+ buffer.append(str);
+ }
+
+ /**
+ * Responsible for creating CallAudioState objects for deserialized Parcels.
+ */
+ public static final Parcelable.Creator<CallAudioState> CREATOR =
+ new Parcelable.Creator<CallAudioState> () {
+
+ @Override
+ public CallAudioState createFromParcel(Parcel source) {
+ boolean isMuted = source.readByte() == 0 ? false : true;
+ int route = source.readInt();
+ int supportedRouteMask = source.readInt();
+ return new CallAudioState(isMuted, route, supportedRouteMask);
+ }
+
+ @Override
+ public CallAudioState[] newArray(int size) {
+ return new CallAudioState[size];
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes CallAudioState object into a serializeable Parcel.
+ */
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeByte((byte) (isMuted ? 1 : 0));
+ destination.writeInt(route);
+ destination.writeInt(supportedRouteMask);
+ }
+}
diff --git a/telecomm/java/android/telecomm/CallInfo.aidl b/telecomm/java/android/telecomm/CallInfo.aidl
new file mode 100644
index 0000000..bc5ef96
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2013, 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 android.telecomm;
+
+parcelable CallInfo;
diff --git a/telecomm/java/android/telecomm/CallInfo.java b/telecomm/java/android/telecomm/CallInfo.java
new file mode 100644
index 0000000..bb08c2a
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallInfo.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2013, 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 android.telecomm;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * A parcelable holder class of Call information data. This class is intended for transfering call
+ * information from Telecomm to call services and thus is read-only.
+ * TODO(santoscordon): Need final public-facing comments in this file.
+ */
+public final class CallInfo implements Parcelable {
+
+ /**
+ * Unique identifier for the call as a UUID string.
+ */
+ private final String mId;
+
+ /**
+ * The state of the call.
+ */
+ private final CallState mState;
+
+ /**
+ * Endpoint to which the call is connected.
+ * This could be the dialed value for outgoing calls or the caller id of incoming calls.
+ */
+ private final Uri mHandle;
+
+ /**
+ * Gateway information for the call.
+ */
+ private final GatewayInfo mGatewayInfo;
+
+ // There are 4 timestamps that are important to a call:
+ // 1) Created timestamp - The time at which the user explicitly chose to make the call.
+ // 2) Connected timestamp - The time at which a call service confirms that it has connected
+ // this call. This happens through a method-call to either newOutgoingCall or newIncomingCall
+ // on CallServiceAdapter. Generally this should coincide roughly to the user physically
+ // hearing/seeing a ring.
+ // TODO(santoscordon): Consider renaming Call-active to better match the others.
+ // 3) Call-active timestamp - The time at which the call switches to the active state. This
+ // happens when the user answers an incoming call or an outgoing call was answered by the
+ // other party.
+ // 4) Disconnected timestamp - The time at which the call was disconnected.
+
+ public CallInfo(String id, CallState state, Uri handle) {
+ this(id, state, handle, null);
+ }
+
+ /**
+ * Persists handle of the other party of this call.
+ *
+ * @param id The unique ID of the call.
+ * @param state The state of the call.
+ * @param handle The handle to the other party in this call.
+ * @param gatewayInfo Gateway information pertaining to this call.
+ *
+ * @hide
+ */
+ public CallInfo(String id, CallState state, Uri handle, GatewayInfo gatewayInfo) {
+ mId = id;
+ mState = state;
+ mHandle = handle;
+ mGatewayInfo = gatewayInfo;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public CallState getState() {
+ return mState;
+ }
+
+ public Uri getHandle() {
+ return mHandle;
+ }
+
+ /**
+ * @return The actual handle this call is associated with. This is used by call services to
+ * correctly indicate in their UI what handle the user is actually calling, and by other
+ * telecomm components that require the user-dialed handle to function.
+ */
+ public Uri getOriginalHandle() {
+ if (mGatewayInfo != null) {
+ return mGatewayInfo.getOriginalHandle();
+ }
+ return getHandle();
+ }
+
+ public GatewayInfo getGatewayInfo() {
+ return mGatewayInfo;
+ }
+
+ //
+ // Parceling related code below here.
+ //
+
+ /**
+ * Responsible for creating CallInfo objects for deserialized Parcels.
+ */
+ public static final Parcelable.Creator<CallInfo> CREATOR =
+ new Parcelable.Creator<CallInfo> () {
+
+ @Override
+ public CallInfo createFromParcel(Parcel source) {
+ String id = source.readString();
+ CallState state = CallState.valueOf(source.readString());
+ Uri handle = Uri.CREATOR.createFromParcel(source);
+ boolean gatewayInfoPresent = source.readByte() != 0;
+ GatewayInfo gatewayInfo = null;
+ if (gatewayInfoPresent) {
+ gatewayInfo = GatewayInfo.CREATOR.createFromParcel(source);
+ }
+
+ return new CallInfo(id, state, handle, gatewayInfo);
+ }
+
+ @Override
+ public CallInfo[] newArray(int size) {
+ return new CallInfo[size];
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes CallInfo object into a serializeable Parcel.
+ */
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeString(mId);
+ destination.writeString(mState.name());
+ mHandle.writeToParcel(destination, 0);
+ if (mGatewayInfo != null) {
+ destination.writeByte((byte) 1);
+ mGatewayInfo.writeToParcel(destination, 0);
+ } else {
+ destination.writeByte((byte) 0);
+ }
+ }
+}
diff --git a/telecomm/java/android/telecomm/CallService.java b/telecomm/java/android/telecomm/CallService.java
new file mode 100644
index 0000000..3b88be1
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallService.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2013 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 android.telecomm;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecomm.ICallService;
+import com.android.internal.telecomm.ICallServiceAdapter;
+
+/**
+ * Base implementation of CallService which can be used to provide calls for the system
+ * in-call UI. CallService is a one-way service from the framework's CallsManager to any app
+ * that would like to provide calls managed by the default system in-call user interface.
+ * When the service is bound by the framework, CallsManager will call setCallServiceAdapter
+ * which will provide CallService with an instance of {@link CallServiceAdapter} to be used
+ * for communicating back to CallsManager. Subsequently, more specific methods of the service
+ * will be called to perform various call actions including making an outgoing call and
+ * disconnected existing calls.
+ * TODO(santoscordon): Needs more about AndroidManifest.xml service registrations before
+ * we can unhide this API.
+ *
+ * Most public methods of this function are backed by a one-way AIDL interface which precludes
+ * synchronous responses. As a result, most responses are handled by (or have TODOs to handle)
+ * response objects instead of return values.
+ * TODO(santoscordon): Improve paragraph above once the final design is in place.
+ */
+public abstract class CallService extends Service {
+
+ private static final int MSG_SET_CALL_SERVICE_ADAPTER = 1;
+ private static final int MSG_IS_COMPATIBLE_WITH = 2;
+ private static final int MSG_CALL = 3;
+ private static final int MSG_ABORT = 4;
+ private static final int MSG_SET_INCOMING_CALL_ID = 5;
+ private static final int MSG_ANSWER = 6;
+ private static final int MSG_REJECT = 7;
+ private static final int MSG_DISCONNECT = 8;
+ private static final int MSG_HOLD = 9;
+ private static final int MSG_UNHOLD = 10;
+ private static final int MSG_ON_AUDIO_STATE_CHANGED = 11;
+
+ /**
+ * Default Handler used to consolidate binder method calls onto a single thread.
+ */
+ private final class CallServiceMessageHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SET_CALL_SERVICE_ADAPTER:
+ CallServiceAdapter adapter =
+ new CallServiceAdapter((ICallServiceAdapter) msg.obj);
+ setCallServiceAdapter(adapter);
+ break;
+ case MSG_IS_COMPATIBLE_WITH:
+ isCompatibleWith((CallInfo) msg.obj);
+ break;
+ case MSG_CALL:
+ call((CallInfo) msg.obj);
+ break;
+ case MSG_ABORT:
+ abort((String) msg.obj);
+ break;
+ case MSG_SET_INCOMING_CALL_ID: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ String callId = (String) args.arg1;
+ Bundle extras = (Bundle) args.arg2;
+ setIncomingCallId(callId, extras);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ case MSG_ANSWER:
+ answer((String) msg.obj);
+ break;
+ case MSG_REJECT:
+ reject((String) msg.obj);
+ break;
+ case MSG_DISCONNECT:
+ disconnect((String) msg.obj);
+ break;
+ case MSG_HOLD:
+ hold((String) msg.obj);
+ break;
+ case MSG_UNHOLD:
+ unhold((String) msg.obj);
+ break;
+ case MSG_ON_AUDIO_STATE_CHANGED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ String callId = (String) args.arg1;
+ CallAudioState audioState = (CallAudioState) args.arg2;
+ onAudioStateChanged(callId, audioState);
+ } finally {
+ args.recycle();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * Default ICallService implementation provided to CallsManager via {@link #onBind}.
+ */
+ private final class CallServiceBinder extends ICallService.Stub {
+ @Override
+ public void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter) {
+ mMessageHandler.obtainMessage(MSG_SET_CALL_SERVICE_ADAPTER, callServiceAdapter)
+ .sendToTarget();
+ }
+
+ @Override
+ public void isCompatibleWith(CallInfo callInfo) {
+ mMessageHandler.obtainMessage(MSG_IS_COMPATIBLE_WITH, callInfo).sendToTarget();
+ }
+
+ @Override
+ public void call(CallInfo callInfo) {
+ mMessageHandler.obtainMessage(MSG_CALL, callInfo).sendToTarget();
+ }
+
+ @Override
+ public void abort(String callId) {
+ mMessageHandler.obtainMessage(MSG_ABORT, callId).sendToTarget();
+ }
+
+ @Override
+ public void setIncomingCallId(String callId, Bundle extras) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = extras;
+ mMessageHandler.obtainMessage(MSG_SET_INCOMING_CALL_ID, args).sendToTarget();
+ }
+
+ @Override
+ public void answer(String callId) {
+ mMessageHandler.obtainMessage(MSG_ANSWER, callId).sendToTarget();
+ }
+
+ @Override
+ public void reject(String callId) {
+ mMessageHandler.obtainMessage(MSG_REJECT, callId).sendToTarget();
+ }
+
+ @Override
+ public void disconnect(String callId) {
+ mMessageHandler.obtainMessage(MSG_DISCONNECT, callId).sendToTarget();
+ }
+
+ @Override
+ public void hold(String callId) {
+ mMessageHandler.obtainMessage(MSG_HOLD, callId).sendToTarget();
+ }
+
+ @Override
+ public void unhold(String callId) {
+ mMessageHandler.obtainMessage(MSG_UNHOLD, callId).sendToTarget();
+ }
+
+ @Override
+ public void onAudioStateChanged(String callId, CallAudioState audioState) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callId;
+ args.arg2 = audioState;
+ mMessageHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget();
+ }
+ }
+
+ /**
+ * Message handler for consolidating binder callbacks onto a single thread.
+ * See {@link CallServiceMessageHandler}.
+ */
+ private final CallServiceMessageHandler mMessageHandler = new CallServiceMessageHandler();
+
+ /**
+ * Default binder implementation of {@link ICallService} interface.
+ */
+ private final CallServiceBinder mBinder = new CallServiceBinder();
+
+ /** {@inheritDoc} */
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return getBinder();
+ }
+
+ /**
+ * Returns binder object which can be used across IPC methods.
+ */
+ public final IBinder getBinder() {
+ return mBinder;
+ }
+
+ /**
+ * Sets an implementation of CallServiceAdapter for adding new calls and communicating state
+ * changes of existing calls.
+ *
+ * @param callServiceAdapter Adapter object for communicating call to CallsManager
+ */
+ public abstract void setCallServiceAdapter(CallServiceAdapter callServiceAdapter);
+
+ /**
+ * Determines if the CallService can place the specified call. Response is sent via
+ * {@link CallServiceAdapter#setIsCompatibleWith}. When responding, the correct call ID must be
+ * specified. Only used in the context of outgoing calls and call switching (handoff).
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ public abstract void isCompatibleWith(CallInfo callInfo);
+
+ /**
+ * Attempts to call the relevant party using the specified call's handle, be it a phone number,
+ * SIP address, or some other kind of user ID. Note that the set of handle types is
+ * dynamically extensible since call providers should be able to implement arbitrary
+ * handle-calling systems. See {@link #isCompatibleWith}. It is expected that the
+ * call service respond via {@link CallServiceAdapter#handleSuccessfulOutgoingCall(String)}
+ * if it can successfully make the call. Only used in the context of outgoing calls.
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ public abstract void call(CallInfo callInfo);
+
+ /**
+ * Aborts the outgoing call attempt. Invoked in the unlikely event that Telecomm decides to
+ * abort an attempt to place a call. Only ever be invoked after {@link #call} invocations.
+ * After this is invoked, Telecomm does not expect any more updates about the call and will
+ * actively ignore any such update. This is different from {@link #disconnect} where Telecomm
+ * expects confirmation via CallServiceAdapter.markCallAsDisconnected.
+ *
+ * @param callId The identifier of the call to abort.
+ */
+ public abstract void abort(String callId);
+
+ /**
+ * Receives a new call ID to use with an incoming call. Invoked by Telecomm after it is notified
+ * that this call service has a pending incoming call, see
+ * {@link TelecommConstants#ACTION_INCOMING_CALL}. The call service must first give Telecomm
+ * additional information about the call through {@link CallServiceAdapter#notifyIncomingCall}.
+ * Following that, the call service can update the call at will using the specified call ID.
+ *
+ * If a {@link Bundle} was passed (via {@link TelecommConstants#EXTRA_INCOMING_CALL_EXTRAS}) in
+ * with the {@link TelecommConstants#ACTION_INCOMING_CALL} intent, <code>extras</code> will be
+ * populated with this {@link Bundle}. Otherwise, an empty Bundle will be returned.
+ *
+ * @param callId The ID of the call.
+ * @param extras The optional extras which were passed in with the intent, or an empty Bundle.
+ */
+ public abstract void setIncomingCallId(String callId, Bundle extras);
+
+ /**
+ * Answers a ringing call identified by callId. Telecomm invokes this method as a result of the
+ * user hitting the "answer" button in the incoming call screen.
+ *
+ * @param callId The ID of the call.
+ */
+ public abstract void answer(String callId);
+
+ /**
+ * Rejects a ringing call identified by callId. Telecomm invokes this method as a result of the
+ * user hitting the "reject" button in the incoming call screen.
+ *
+ * @param callId The ID of the call.
+ */
+ public abstract void reject(String callId);
+
+ /**
+ * Disconnects the specified call.
+ *
+ * @param callId The ID of the call to disconnect.
+ */
+ public abstract void disconnect(String callId);
+
+ /**
+ * Puts the specified call on hold.
+ *
+ * @param callId The ID of the call to put on hold.
+ */
+ public abstract void hold(String callId);
+
+ /**
+ * Removes the specified call from hold.
+ *
+ * @param callId The ID of the call to unhold.
+ */
+ public abstract void unhold(String callId);
+
+ /**
+ * Called when the audio state changes.
+ *
+ * @param activeCallId The identifier of the call that was active during the state change.
+ * @param audioState The new {@link CallAudioState}.
+ */
+ public abstract void onAudioStateChanged(String activeCallId, CallAudioState audioState);
+}
diff --git a/telecomm/java/android/telecomm/CallServiceAdapter.java b/telecomm/java/android/telecomm/CallServiceAdapter.java
new file mode 100644
index 0000000..0527a6d
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceAdapter.java
@@ -0,0 +1,157 @@
+/*
+ * 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 android.telecomm;
+
+import android.os.RemoteException;
+
+import com.android.internal.telecomm.ICallServiceAdapter;
+
+/**
+ * Provides methods for ICallService implementations to interact with the system phone app.
+ * TODO(santoscordon): Need final public-facing comments in this file.
+ */
+public final class CallServiceAdapter {
+ private final ICallServiceAdapter mAdapter;
+
+ /**
+ * {@hide}
+ */
+ public CallServiceAdapter(ICallServiceAdapter adapter) {
+ mAdapter = adapter;
+ }
+
+ /**
+ * Receives confirmation of a call service's ability to place a call. This method is used in
+ * response to {@link CallService#isCompatibleWith}.
+ *
+ * @param callId The identifier of the call for which compatibility is being received. This ID
+ * should correspond to the ID given as part of the call information in
+ * {@link CallService#isCompatibleWith}.
+ * @param isCompatible True if the call service can place the call.
+ */
+ public void setIsCompatibleWith(String callId, boolean isCompatible) {
+ try {
+ mAdapter.setIsCompatibleWith(callId, isCompatible);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Provides Telecomm with the details of an incoming call. An invocation of this method must
+ * follow {@link CallService#setIncomingCallId} and use the call ID specified therein. Upon
+ * the invocation of this method, Telecomm will bring up the incoming-call interface where the
+ * user can elect to answer or reject a call.
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ public void notifyIncomingCall(CallInfo callInfo) {
+ try {
+ mAdapter.notifyIncomingCall(callInfo);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Tells Telecomm that an attempt to place the specified outgoing call succeeded.
+ * TODO(santoscordon): Consider adding a CallState parameter in case this outgoing call is
+ * somehow no longer in the DIALING state.
+ *
+ * @param callId The ID of the outgoing call.
+ */
+ public void handleSuccessfulOutgoingCall(String callId) {
+ try {
+ mAdapter.handleSuccessfulOutgoingCall(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Tells Telecomm that an attempt to place the specified outgoing call failed.
+ *
+ * @param callId The ID of the outgoing call.
+ * @param errorMessage The error associated with the failed call attempt.
+ */
+ public void handleFailedOutgoingCall(String callId, String errorMessage) {
+ try {
+ mAdapter.handleFailedOutgoingCall(callId, errorMessage);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets a call's state to active (e.g., an ongoing call where two parties can actively
+ * communicate).
+ *
+ * @param callId The unique ID of the call whose state is changing to active.
+ */
+ public void setActive(String callId) {
+ try {
+ mAdapter.setActive(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets a call's state to ringing (e.g., an inbound ringing call).
+ *
+ * @param callId The unique ID of the call whose state is changing to ringing.
+ */
+ public void setRinging(String callId) {
+ try {
+ mAdapter.setRinging(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets a call's state to dialing (e.g., dialing an outbound call).
+ *
+ * @param callId The unique ID of the call whose state is changing to dialing.
+ */
+ public void setDialing(String callId) {
+ try {
+ mAdapter.setDialing(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets a call's state to disconnected.
+ *
+ * @param callId The unique ID of the call whose state is changing to disconnected.
+ */
+ public void setDisconnected(String callId) {
+ try {
+ mAdapter.setDisconnected(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets a call's state to be on hold.
+ *
+ * @param callId - The unique ID of the call whose state is changing to be on hold.
+ */
+ public void setOnHold(String callId) {
+ try {
+ mAdapter.setOnHold(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+
+}
diff --git a/telecomm/java/android/telecomm/CallServiceDescriptor.aidl b/telecomm/java/android/telecomm/CallServiceDescriptor.aidl
new file mode 100644
index 0000000..f517c73
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceDescriptor.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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 android.telecomm;
+
+parcelable CallServiceDescriptor;
diff --git a/telecomm/java/android/telecomm/CallServiceDescriptor.java b/telecomm/java/android/telecomm/CallServiceDescriptor.java
new file mode 100644
index 0000000..40f6ab9
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceDescriptor.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 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 android.telecomm;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.UUID;
+
+/**
+ * An immutable object containing information about a given {@link CallService}. Instances are
+ * created using the enclosed {@link Builder}.
+ */
+public final class CallServiceDescriptor implements Parcelable {
+ private static final String TAG = CallServiceDescriptor.class.getSimpleName();
+
+ /**
+ * A placeholder value indicating an invalid network type.
+ * @hide
+ */
+ private static final int FLAG_INVALID = 0;
+
+ /**
+ * Indicates that the device must be connected to a Wi-Fi network in order for the backing
+ * {@link CallService} to be used.
+ */
+ public static final int FLAG_WIFI = 0x01;
+
+ /**
+ * Indicates that the device must be connected to a cellular PSTN network in order for the
+ * backing {@link CallService} to be used.
+ */
+ public static final int FLAG_PSTN = 0x02;
+
+ /**
+ * Indicates that the device must be connected to a cellular data network in order for the
+ * backing {@link CallService} to be used.
+ */
+ public static final int FLAG_MOBILE = 0x04;
+
+ /**
+ * Represents all of the defined FLAG_ constants so validity can be easily checked.
+ * @hide
+ */
+ public static final int FLAG_ALL = FLAG_WIFI | FLAG_PSTN | FLAG_MOBILE;
+
+ /**
+ * A unique ID used to identify a given instance.
+ */
+ private final String mCallServiceId;
+
+ /**
+ * The {@link ComponentName} of the {@link CallService} implementation which this is describing.
+ */
+ private final ComponentName mComponentName;
+
+ /**
+ * The type of connection that the {@link CallService} requires; will be one of the FLAG_*
+ * constants defined in this class.
+ */
+ private final int mNetworkType;
+
+ private CallServiceDescriptor(
+ String callServiceId,
+ ComponentName componentName,
+ int networkType) {
+
+ mCallServiceId = callServiceId;
+ mComponentName = componentName;
+ mNetworkType = networkType;
+ }
+
+ /**
+ * @return The ID used to identify this {@link CallService}.
+ */
+ public String getCallServiceId() {
+ return mCallServiceId;
+ }
+
+ /**
+ * @return The {@link ComponentName} of the {@link CallService}.
+ */
+ public ComponentName getServiceComponent() {
+ return mComponentName;
+ }
+
+ /**
+ * @return The network type required by the {@link CallService} to place a call.
+ */
+ public int getNetworkType() {
+ return mNetworkType;
+ }
+
+ /**
+ * @param context {@link Context} to use for the construction of the {@link Builder}.
+ * @return A new {@link Builder} instance.
+ */
+ public static Builder newBuilder(Context context) {
+ return new Builder(context);
+ }
+
+ /**
+ * Creates {@link CallServiceDescriptor} instances. Builders should be created with the
+ * {@link CallServiceDescriptor#newBuilder(Context)} method.
+ */
+ public static class Builder {
+ /** The {@link Context} to use to verify {@link ComponentName} ownership. */
+ private Context mContext;
+
+ /** The {@link ComponentName} pointing to the backing {@link CallService}. */
+ private ComponentName mComponentName;
+
+ /** The required network type that the {@link CallService} needs. */
+ private int mNetworkType = FLAG_INVALID;
+
+ private Builder(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Set which {@link CallService} this {@link CallServiceDescriptor} is describing.
+ *
+ * @param callServiceClass The {@link CallService} class
+ * @return This {@link Builder} for method chaining.
+ */
+ public Builder setCallService(Class<? extends CallService> callServiceClass) {
+ mComponentName = new ComponentName(mContext, callServiceClass);
+ return this;
+ }
+
+ /**
+ * Which network type the backing {@link CallService} requires. This must be one of the
+ * {@link CallServiceDescriptor}.TYPE_* fields.
+ *
+ * @param networkType Which network type the backing {@link CallService} requires.
+ * @return This {@link Builder} for method chaining.
+ */
+ public Builder setNetworkType(int networkType) {
+ mNetworkType = networkType;
+ return this;
+ }
+
+ /**
+ * @return A constructed {@link CallServiceDescriptor} object.
+ */
+ public CallServiceDescriptor build() {
+ // STOPSHIP: Verify validity of ComponentName (permissions, intents, etc)
+
+ // Make sure that they passed in a valid network flag combination
+ if (mNetworkType == FLAG_INVALID || ((mNetworkType & FLAG_ALL) == 0)) {
+
+ Log.wtf(TAG, "Invalid network type for " + mComponentName);
+ // Revert them back to TYPE_INVALID so it won't be considered.
+ mNetworkType = FLAG_INVALID;
+ }
+
+ // TODO: Should we use a sha1 of the ComponentName? Would prevent duplicates.
+ return new CallServiceDescriptor(
+ UUID.randomUUID().toString(), mComponentName, mNetworkType);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mCallServiceId);
+ dest.writeParcelable(mComponentName, 0);
+ dest.writeInt(mNetworkType);
+ }
+
+ public static final Creator<CallServiceDescriptor> CREATOR =
+ new Creator<CallServiceDescriptor>() {
+ @Override
+ public CallServiceDescriptor createFromParcel(Parcel source) {
+ String id = source.readString();
+ ComponentName componentName = source.readParcelable(
+ CallServiceDescriptor.class.getClassLoader());
+ int networkType = source.readInt();
+
+ return new CallServiceDescriptor(id, componentName, networkType);
+ }
+
+ @Override
+ public CallServiceDescriptor[] newArray(int size) {
+ return new CallServiceDescriptor[size];
+ }
+ };
+}
diff --git a/telecomm/java/android/telecomm/CallServiceLookupResponse.java b/telecomm/java/android/telecomm/CallServiceLookupResponse.java
new file mode 100644
index 0000000..dd35a24
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceLookupResponse.java
@@ -0,0 +1,51 @@
+/*
+ * 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 android.telecomm;
+
+import android.os.RemoteException;
+
+import com.android.internal.telecomm.ICallServiceLookupResponse;
+
+import java.util.List;
+
+/**
+ * Used by {@link CallServiceProvider} to return a list of {@link CallServiceDescriptor}s.
+ */
+public final class CallServiceLookupResponse {
+ private final ICallServiceLookupResponse mResponse;
+
+ /**
+ * {@hide}
+ */
+ public CallServiceLookupResponse(ICallServiceLookupResponse response) {
+ mResponse = response;
+ }
+
+ /**
+ * Passes the sorted list of preferred {@link CallServiceDescriptor}s back to Telecomm. Used
+ * in the context of attempting to place a pending outgoing call.
+ *
+ * @param callServiceDescriptors The set of call-service descriptors from
+ * {@link CallServiceProvider}.
+ */
+ public void setCallServiceDescriptors(List<CallServiceDescriptor> callServiceDescriptors) {
+ try {
+ mResponse.setCallServiceDescriptors(callServiceDescriptors);
+ } catch (RemoteException e) {
+ }
+ }
+}
diff --git a/telecomm/java/android/telecomm/CallServiceProvider.java b/telecomm/java/android/telecomm/CallServiceProvider.java
new file mode 100644
index 0000000..c50334a
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceProvider.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 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 android.telecomm;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+
+import com.android.internal.telecomm.ICallServiceLookupResponse;
+import com.android.internal.telecomm.ICallServiceProvider;
+
+/**
+ * Base implementation of a call service provider which extends {@link Service}. This class
+ * should be extended by an app that wants to supply phone calls to be handled and managed by
+ * the device's in-call interface. All method-calls from the framework to the call service provider
+ * are passed through to the main thread for before executing the overriden methods of
+ * CallServiceProvider.
+ *
+ * TODO(santoscordon): Improve paragraph above once the final design is in place. Needs more
+ * about how this can be used.
+ */
+public abstract class CallServiceProvider extends Service {
+
+ /**
+ * Default Handler used to consolidate binder method calls onto a single thread.
+ */
+ private final class CallServiceProviderMessageHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_LOOKUP_CALL_SERVICES:
+ CallServiceLookupResponse response =
+ new CallServiceLookupResponse((ICallServiceLookupResponse) msg.obj);
+ lookupCallServices(response);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Default ICallServiceProvider implementation provided to CallsManager via {@link #onBind}.
+ */
+ private final class CallServiceProviderWrapper extends ICallServiceProvider.Stub {
+ /** {@inheritDoc} */
+ @Override
+ public void lookupCallServices(ICallServiceLookupResponse callServiceLookupResponse) {
+ Message message = mMessageHandler.obtainMessage(
+ MSG_LOOKUP_CALL_SERVICES, callServiceLookupResponse);
+ message.sendToTarget();
+ }
+ }
+
+ // Only used internally by this class.
+ // Binder method calls on this service can occur on multiple threads. These messages are used
+ // in conjunction with {@link #mMessageHandler} to ensure that all callbacks are handled on a
+ // single thread. Keeping it on a single thread allows CallService implementations to avoid
+ // needing multi-threaded code in their own callback routines.
+ private static final int MSG_LOOKUP_CALL_SERVICES = 1;
+
+ /**
+ * Message handler for consolidating binder callbacks onto a single thread.
+ * See {@link CallServiceProviderMessageHandler}.
+ */
+ private final CallServiceProviderMessageHandler mMessageHandler;
+
+ /**
+ * Default binder implementation of {@link ICallServiceProvider} interface.
+ */
+ private final CallServiceProviderWrapper mBinder;
+
+ /**
+ * Protected constructor called only by subclasses creates the binder interface and
+ * single-threaded message handler.
+ */
+ protected CallServiceProvider() {
+ mMessageHandler = new CallServiceProviderMessageHandler();
+ mBinder = new CallServiceProviderWrapper();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /**
+ * Initiates the process to retrieve the list of {@link CallServiceDescriptor}s implemented by
+ * this provider.
+ *
+ * @param response The response object through which the list of call services is sent.
+ */
+ public abstract void lookupCallServices(CallServiceLookupResponse response);
+}
diff --git a/telecomm/java/android/telecomm/CallServiceSelector.java b/telecomm/java/android/telecomm/CallServiceSelector.java
new file mode 100644
index 0000000..44181d1
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceSelector.java
@@ -0,0 +1,207 @@
+/*
+ * 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 android.telecomm;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecomm.ICallServiceSelector;
+import com.android.internal.telecomm.ICallServiceSelectionResponse;
+import com.android.internal.telecomm.ICallSwitchabilityResponse;
+
+import java.util.List;
+
+/**
+ * Allows for the organization of {@link CallService}s for outbound calls. Given a call and list of
+ * {@link CallService} IDs, order the list in terms of priority and return it using
+ * {@link #select(CallInfo, List, CallServiceSelectionResponse)}. <br />
+ * <br />
+ * Also determine whether a call is switchable (can be moved between {@link CallService}s) or not
+ * using {@link #isSwitchable(CallInfo, CallSwitchabilityResponse)}.
+ */
+public abstract class CallServiceSelector extends Service {
+ private static final String TAG = CallServiceSelector.class.getSimpleName();
+
+ /**
+ * Used to tell {@link #mHandler} to move the call to
+ * {@link CallServiceSelector#isSwitchable(CallInfo, CallSwitchabilityResponse)} to the main
+ * thread.
+ */
+ private static final int MSG_IS_SWITCHABLE = 1;
+
+ /**
+ * Used to tell {@link #mHandler} to move the call to
+ * {@link #select(CallInfo, List, CallServiceSelectionResponse)} to the main thread.
+ */
+ private static final int MSG_SELECT_CALL_SERVICES = 2;
+
+ /**
+ * Listens for responses from the {@link CallServiceSelector} and passes them back through the
+ * Binder interface. This must be called from
+ * {@link CallServiceSelector#isSwitchable(CallInfo, CallSwitchabilityResponse)}.
+ */
+ public interface CallSwitchabilityResponse {
+ /**
+ * Mark a call as switchable (or not). This must be called by
+ * {@link CallServiceSelector#isSwitchable(CallInfo, CallSwitchabilityResponse)}.
+ *
+ * @param isSwitchable Whether the call was switchable or not.
+ */
+ void setSwitchable(boolean isSwitchable);
+ }
+
+ /**
+ * Listens for responses from the {@link CallServiceSelector} and passes them back through the
+ * Binder interface. This must be called from
+ * {@link CallServiceSelector#select(CallInfo, List, CallServiceSelectionResponse)}.
+ */
+ public interface CallServiceSelectionResponse {
+ /**
+ * Sets the prioritized {@link CallServiceDescriptor}s for the given {@link CallInfo}. This
+ * must be called by
+ * {@link CallServiceSelector#select(CallInfo, List, CallServiceSelectionResponse)}.
+ *
+ * @param callServices The prioritized {@link CallServiceDescriptor}s.
+ */
+ void setSelectedCallServices(List<CallServiceDescriptor> callServices);
+ }
+
+ /** Handler to move client-bound method calls to the main thread. */
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void handleMessage(Message msg) {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ try {
+ switch (msg.what) {
+ case MSG_IS_SWITCHABLE:
+ isSwitchable((CallInfo) args.arg1, (CallSwitchabilityResponse) args.arg2);
+ break;
+ case MSG_SELECT_CALL_SERVICES:
+ select((CallInfo) args.arg1, (List<CallServiceDescriptor>) args.arg2,
+ (CallServiceSelectionResponse) args.arg3);
+ break;
+ }
+ } finally {
+ if (args != null) {
+ args.recycle();
+ }
+ }
+ }
+ };
+
+ /** Manages the binder calls so that the implementor does not need to deal with it. */
+ private final class CallServiceSelectorBinder extends ICallServiceSelector.Stub
+ implements CallSwitchabilityResponse, CallServiceSelectionResponse {
+ private ICallSwitchabilityResponse mSwitchabilityResponse;
+ private ICallServiceSelectionResponse mSelectionResponse;
+
+ @Override
+ public void isSwitchable(CallInfo callInfo, ICallSwitchabilityResponse response)
+ throws RemoteException {
+ mSwitchabilityResponse = response;
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callInfo;
+ args.arg2 = this;
+ mHandler.obtainMessage(MSG_IS_SWITCHABLE, args).sendToTarget();
+ }
+
+ @Override
+ public void select(CallInfo callInfo, List<CallServiceDescriptor> descriptors,
+ ICallServiceSelectionResponse response) throws RemoteException {
+ mSelectionResponse = response;
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = callInfo;
+ args.arg2 = descriptors;
+ args.arg3 = this;
+ mHandler.obtainMessage(MSG_SELECT_CALL_SERVICES, args).sendToTarget();
+ }
+
+ @Override
+ public void setSwitchable(boolean isSwitchable) {
+ if (mSwitchabilityResponse != null) {
+ try {
+ mSwitchabilityResponse.setIsSwitchable(isSwitchable);
+ } catch (RemoteException e) {
+ Log.d(TAG, "Failed to set switchability", e);
+ }
+ } else {
+ Log.wtf(TAG, "Switchability response object not set");
+ }
+ }
+
+ @Override
+ public void setSelectedCallServices(List<CallServiceDescriptor> callServices) {
+ if (mSelectionResponse != null) {
+ try {
+ mSelectionResponse.setSelectedCallServiceDescriptors(callServices);
+ } catch (RemoteException e) {
+ Log.d(TAG, "Failed to set call services", e);
+ }
+ } else {
+ Log.wtf(TAG, "Selector response object not set");
+ }
+ }
+ }
+
+ private final CallServiceSelectorBinder mBinder;
+
+ protected CallServiceSelector() {
+ mBinder = new CallServiceSelectorBinder();
+ }
+
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /**
+ * Determines whether the given call is switchable. That is, whether the call can be moved to
+ * another {@link CallService} seamlessly. Once this is determined, the result is passed to the
+ * given {@link CallSwitchabilityResponse} listener.<br />
+ * <br />
+ * This method is called on the main thread and is not safe to block.
+ *
+ * @param callInfo The call being potentially switched between {@link CallService}s.
+ * @param response The {@link CallSwitchabilityResponse} listener to call back with the result.
+ */
+ protected abstract void isSwitchable(CallInfo callInfo, CallSwitchabilityResponse response);
+
+ /**
+ * Given a list of {@link CallServiceDescriptor}s, order them into a prioritized list and return
+ * them through the given {@link CallServiceSelectionResponse} listener.<br />
+ * <br />
+ * This method is called on the UI thread and is not safe to block.
+ *
+ * @param callInfo The call being placed using the {@link CallService}s.
+ * @param descriptors The descriptors of the available {@link CallService}s with which to place
+ * the call.
+ * @param response The {@link CallServiceSelectionResponse} listener to call back with the
+ * result.
+ */
+ protected abstract void select(
+ CallInfo callInfo,
+ List<CallServiceDescriptor> descriptors,
+ CallServiceSelectionResponse response);
+}
diff --git a/telecomm/java/android/telecomm/CallState.java b/telecomm/java/android/telecomm/CallState.java
new file mode 100644
index 0000000..3937b08
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallState.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 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 android.telecomm;
+
+/**
+ * Defines call-state constants of the different states in which a call can exist. Although states
+ * have the notion of normal transitions, due to the volatile nature of telephony systems, code
+ * that uses these states should be resilient to unexpected state changes outside of what is
+ * considered traditional.
+ */
+public enum CallState {
+ /**
+ * Indicates that a call is new and not connected. This is used as the default state internally
+ * within Telecomm and should not be used between Telecomm and call services. Call services are
+ * not expected to ever interact with NEW calls so we keep this value hidden as a Telecomm
+ * internal-only value.
+ * @hide
+ */
+ NEW,
+
+ /**
+ * Indicates that a call is outgoing and in the dialing state. A call transitions to this state
+ * once an outgoing call has begun (e.g., user presses the dial button in Dialer). Calls in this
+ * state usually transition to {@link #ACTIVE} if the call was answered or {@link #DISCONNECTED}
+ * if the call was disconnected somehow (e.g., failure or cancellation of the call by the user).
+ */
+ DIALING,
+
+ /**
+ * Indicates that a call is incoming and the user still has the option of answering, rejecting,
+ * or doing nothing with the call. This state is usually associated with some type of audible
+ * ringtone. Normal transitions are to {@link #ACTIVE} if answered or {@link #DISCONNECTED}
+ * otherwise.
+ */
+ RINGING,
+
+ /**
+ * Indicates that a call is currently connected to another party and a communication channel is
+ * open between them. The normal transition to this state is by the user answering a
+ * {@link #DIALING} call or a {@link #RINGING} call being answered by the other party.
+ */
+ ACTIVE,
+
+ /**
+ * Indicates that the call is currently on hold. In this state, the call is not terminated
+ * but no communication is allowed until the call is no longer on hold. The typical transition
+ * to this state is by the user putting an {@link #ACTIVE} call on hold by explicitly performing
+ * an action, such as clicking the hold button.
+ */
+ ON_HOLD,
+
+ /**
+ * Indicates that a call is currently disconnected. All states can transition to this state
+ * by the call service giving notice that the connection has been severed. When the user
+ * explicitly ends a call, it will not transition to this state until the call service confirms
+ * the disconnection or communication was lost to the call service currently responsible for
+ * this call (e.g., call service crashes).
+ */
+ DISCONNECTED,
+
+ /**
+ * Indicates that the call was attempted (mostly in the context of outgoing, at least at the
+ * time of writing) but cancelled before it was successfully connected.
+ * @hide
+ */
+ ABORTED;
+}
diff --git a/telecomm/java/android/telecomm/GatewayInfo.aidl b/telecomm/java/android/telecomm/GatewayInfo.aidl
new file mode 100644
index 0000000..d59e9b4
--- /dev/null
+++ b/telecomm/java/android/telecomm/GatewayInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 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 android.telecomm;
+
+parcelable GatewayInfo;
diff --git a/telecomm/java/android/telecomm/GatewayInfo.java b/telecomm/java/android/telecomm/GatewayInfo.java
new file mode 100644
index 0000000..b95e6b6
--- /dev/null
+++ b/telecomm/java/android/telecomm/GatewayInfo.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 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 android.telecomm;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * When calls are made, they may contain gateway information for services which route phone calls
+ * through their own service/numbers. The data consists of a number to call and the package name of
+ * the service. This data is used in two ways:
+ * <ol>
+ * <li> Call the appropriate routing number
+ * <li> Display information about how the call is being routed to the user
+ * </ol>
+ */
+public class GatewayInfo implements Parcelable {
+
+ private final String mGatewayProviderPackageName;
+ private final Uri mGatewayHandle;
+ private final Uri mOriginalHandle;
+
+ /** @hide */
+ public GatewayInfo(String packageName, Uri gatewayUri, Uri originalHandle) {
+ mGatewayProviderPackageName = packageName;
+ mGatewayHandle = gatewayUri;
+ mOriginalHandle = originalHandle;
+ }
+
+ /**
+ * Package name of the gateway provider service. used to place the call with.
+ */
+ public String getGatewayProviderPackageName() {
+ return mGatewayProviderPackageName;
+ }
+
+ /**
+ * Gateway provider handle to use when actually placing the call.
+ */
+ public Uri getGatewayHandle() {
+ return mGatewayHandle;
+ }
+
+ /**
+ * The actual call handle that the user is trying to connect to via the gateway.
+ */
+ public Uri getOriginalHandle() {
+ return mOriginalHandle;
+ }
+
+ public boolean isEmpty() {
+ return TextUtils.isEmpty(mGatewayProviderPackageName) || mGatewayHandle == null;
+ }
+
+ /** Implement the Parcelable interface */
+ public static final Parcelable.Creator<GatewayInfo> CREATOR =
+ new Parcelable.Creator<GatewayInfo> () {
+
+ @Override
+ public GatewayInfo createFromParcel(Parcel source) {
+ String gatewayPackageName = source.readString();
+ Uri gatewayUri = Uri.CREATOR.createFromParcel(source);
+ Uri originalHandle = Uri.CREATOR.createFromParcel(source);
+ return new GatewayInfo(gatewayPackageName, gatewayUri, originalHandle);
+ }
+
+ @Override
+ public GatewayInfo[] newArray(int size) {
+ return new GatewayInfo[size];
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeString(mGatewayProviderPackageName);
+ mGatewayHandle.writeToParcel(destination, 0);
+ mOriginalHandle.writeToParcel(destination, 0);
+ }
+}
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
new file mode 100644
index 0000000..0a8571a
--- /dev/null
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -0,0 +1,129 @@
+/*
+ * 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 android.telecomm;
+
+import android.os.RemoteException;
+
+import com.android.internal.telecomm.IInCallAdapter;
+
+/**
+ * Receives commands from {@link InCallService} implementations which should be executed by
+ * Telecomm. When Telecomm binds to a {@link InCallService}, an instance of this class is given to
+ * the in-call service through which it can manipulate live (active, dialing, ringing) calls. When
+ * the in-call service is notified of new calls ({@link InCallService#addCall}), it can use the
+ * given call IDs to execute commands such as {@link #answerCall} for incoming calls or
+ * {@link #disconnectCall} for active calls the user would like to end. Some commands are only
+ * appropriate for calls in certain states; please consult each method for such limitations.
+ * TODO(santoscordon): Needs more/better comments once the API is finalized.
+ * TODO(santoscordon): Specify the adapter will stop functioning when there are no more calls.
+ */
+public final class InCallAdapter {
+ private final IInCallAdapter mAdapter;
+
+ /**
+ * {@hide}
+ */
+ public InCallAdapter(IInCallAdapter adapter) {
+ mAdapter = adapter;
+ }
+
+ /**
+ * Instructs Telecomm to answer the specified call.
+ *
+ * @param callId The identifier of the call to answer.
+ */
+ public void answerCall(String callId) {
+ try {
+ mAdapter.answerCall(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Instructs Telecomm to reject the specified call.
+ * TODO(santoscordon): Add reject-with-text-message parameter when that feature
+ * is ported over.
+ *
+ * @param callId The identifier of the call to reject.
+ */
+ public void rejectCall(String callId) {
+ try {
+ mAdapter.rejectCall(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Instructs Telecomm to disconnect the specified call.
+ *
+ * @param callId The identifier of the call to disconnect.
+ */
+ public void disconnectCall(String callId) {
+ try {
+ mAdapter.disconnectCall(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Instructs Telecomm to put the specified call on hold.
+ *
+ * @param callId The identifier of the call to put on hold.
+ */
+ public void holdCall(String callId) {
+ try {
+ mAdapter.holdCall(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Instructs Telecomm to release the specified call from hold.
+ *
+ * @param callId The identifier of the call to release from hold.
+ */
+ public void unholdCall(String callId) {
+ try {
+ mAdapter.unholdCall(callId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Mute the microphone.
+ *
+ * @param shouldMute True if the microphone should be muted.
+ */
+ public void mute(boolean shouldMute) {
+ try {
+ mAdapter.mute(shouldMute);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
+ * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}.
+ *
+ * @param route The audio route to use.
+ */
+ public void setAudioRoute(int route) {
+ try {
+ mAdapter.setAudioRoute(route);
+ } catch (RemoteException e) {
+ }
+ }
+}
diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java
new file mode 100644
index 0000000..ef15a61
--- /dev/null
+++ b/telecomm/java/android/telecomm/InCallService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 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 android.telecomm;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+
+import com.android.internal.telecomm.IInCallAdapter;
+import com.android.internal.telecomm.IInCallService;
+
+/**
+ * This service is implemented by any app that wishes to provide the user-interface for managing
+ * phone calls. Telecomm binds to this service while there exists a live (active or incoming)
+ * call, and uses it to notify the in-call app of any live and and recently disconnected calls.
+ * TODO(santoscordon): Needs more/better description of lifecycle once the interface is better
+ * defined.
+ * TODO(santoscordon): What happens if two or more apps on a given device implement this interface?
+ */
+public abstract class InCallService extends Service {
+ private static final int MSG_SET_IN_CALL_ADAPTER = 1;
+ private static final int MSG_ADD_CALL = 2;
+ private static final int MSG_SET_ACTIVE = 3;
+ private static final int MSG_SET_DISCONNECTED = 4;
+ private static final int MSG_SET_HOLD = 5;
+ private static final int MSG_ON_AUDIO_STATE_CHANGED = 6;
+
+ /** Default Handler used to consolidate binder method calls onto a single thread. */
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SET_IN_CALL_ADAPTER:
+ InCallAdapter adapter = new InCallAdapter((IInCallAdapter) msg.obj);
+ setInCallAdapter(adapter);
+ break;
+ case MSG_ADD_CALL:
+ addCall((CallInfo) msg.obj);
+ break;
+ case MSG_SET_ACTIVE:
+ setActive((String) msg.obj);
+ break;
+ case MSG_SET_DISCONNECTED:
+ setDisconnected((String) msg.obj);
+ break;
+ case MSG_SET_HOLD:
+ setOnHold((String) msg.obj);
+ break;
+ case MSG_ON_AUDIO_STATE_CHANGED:
+ onAudioStateChanged((CallAudioState) msg.obj);
+ default:
+ break;
+ }
+ }
+ };
+
+ /** Manages the binder calls so that the implementor does not need to deal with it. */
+ private final class InCallServiceBinder extends IInCallService.Stub {
+ /** {@inheritDoc} */
+ @Override
+ public void setInCallAdapter(IInCallAdapter inCallAdapter) {
+ mHandler.obtainMessage(MSG_SET_IN_CALL_ADAPTER, inCallAdapter).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void addCall(CallInfo callInfo) {
+ mHandler.obtainMessage(MSG_ADD_CALL, callInfo).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setActive(String callId) {
+ mHandler.obtainMessage(MSG_SET_ACTIVE, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setDisconnected(String callId) {
+ mHandler.obtainMessage(MSG_SET_DISCONNECTED, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setOnHold(String callId) {
+ mHandler.obtainMessage(MSG_SET_HOLD, callId).sendToTarget();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void onAudioStateChanged(CallAudioState audioState) {
+ mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget();
+ }
+ }
+
+ private final InCallServiceBinder mBinder;
+
+ protected InCallService() {
+ mBinder = new InCallServiceBinder();
+ }
+
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /**
+ * Provides the in-call app an adapter object through which to send call-commands such as
+ * answering and rejecting incoming calls, disconnecting active calls, and putting calls in
+ * special states (mute, hold, etc).
+ *
+ * @param inCallAdapter Adapter through which an in-call app can send call-commands to Telecomm.
+ */
+ protected abstract void setInCallAdapter(InCallAdapter inCallAdapter);
+
+ /**
+ * 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 callInfo Information about the new call.
+ */
+ protected abstract void addCall(CallInfo callInfo);
+
+ /**
+ * Indicates to the in-call app that a call has moved to the {@link CallState#ACTIVE} state.
+ *
+ * @param callId The identifier of the call that became active.
+ */
+ protected abstract void setActive(String callId);
+
+ /**
+ * Indicates to the in-call app that a call has been moved to the
+ * {@link CallState#DISCONNECTED} and the user should be notified.
+ * TODO(santoscordon): Needs disconnect-cause either as a numberical constant, string or both
+ * depending on what is ultimately needed to support all scenarios.
+ *
+ * @param callId The identifier of the call that was disconnected.
+ */
+ protected abstract void setDisconnected(String callId);
+
+ /**
+ * Indicates to the in-call app that a call has been moved to the
+ * {@link android.telecomm.CallState#ON_HOLD} state and the user should be notified.
+ *
+ * @param callId The identifier of the call that was put on hold.
+ */
+ protected abstract void setOnHold(String callId);
+
+ /**
+ * Called when the audio state changes.
+ *
+ * @param audioState The new {@link CallAudioState}.
+ */
+ protected abstract void onAudioStateChanged(CallAudioState audioState);
+}
diff --git a/telecomm/java/android/telecomm/README b/telecomm/java/android/telecomm/README
new file mode 100644
index 0000000..defca73
--- /dev/null
+++ b/telecomm/java/android/telecomm/README
@@ -0,0 +1,2 @@
+Mostly AIDL files to interface between the rest of the system and code under
+/packages/services/Telecomm/src/com/android/telecomm. \ No newline at end of file
diff --git a/telecomm/java/android/telecomm/TelecommConstants.java b/telecomm/java/android/telecomm/TelecommConstants.java
new file mode 100644
index 0000000..4269424
--- /dev/null
+++ b/telecomm/java/android/telecomm/TelecommConstants.java
@@ -0,0 +1,77 @@
+/*
+ * 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 android.telecomm;
+
+import android.os.Bundle;
+import android.telephony.TelephonyManager;
+
+/**
+ * Defines constants for use with the Telecomm system.
+ */
+public final class TelecommConstants {
+ /**
+ * <p>Activity action: Starts the UI for handing an incoming call. This intent starts the
+ * in-call UI by notifying the Telecomm system that an incoming call exists for a specific call
+ * service (see {@link android.telecomm.CallService}). Telecomm reads the Intent extras to find
+ * and bind to the appropriate {@link android.telecomm.CallService} which Telecomm will
+ * ultimately use to control and get information about the call.</p>
+ *
+ * <p>Input: get*Extra field {@link #EXTRA_CALL_SERVICE_DESCRIPTOR} contains the component name
+ * of the {@link android.telecomm.CallService} that Telecomm should bind to. Telecomm will then
+ * ask the call service for more information about the call prior to showing any UI.
+ *
+ * TODO(santoscordon): Needs permissions.
+ * TODO(santoscordon): Consider moving this into a simple method call on a system service.
+ */
+ public static final String ACTION_INCOMING_CALL = "android.intent.action.INCOMING_CALL";
+
+ /**
+ * The service action used to bind to {@link CallServiceProvider} implementations.
+ */
+ public static final String ACTION_CALL_SERVICE_PROVIDER = CallServiceProvider.class.getName();
+
+ /**
+ * The service action used to bind to {@link CallService} implementations.
+ */
+ public static final String ACTION_CALL_SERVICE = CallService.class.getName();
+
+ /**
+ * The service action used to bind to {@link CallServiceSelector} implementations.
+ */
+ public static final String ACTION_CALL_SERVICE_SELECTOR = CallServiceSelector.class.getName();
+
+ /**
+ * Extra for {@link #ACTION_INCOMING_CALL} containing the {@link CallServiceDescriptor} that
+ * describes the call service to use for the incoming call.
+ */
+ public static final String EXTRA_CALL_SERVICE_DESCRIPTOR =
+ "android.intent.extra.CALL_SERVICE_DESCRIPTOR";
+
+ /**
+ * Optional extra for {@link #ACTION_INCOMING_CALL} containing a {@link Bundle} which contains
+ * metadata about the call. This {@link Bundle} will be returned to the {@link CallService} as
+ * part of {@link CallService#setIncomingCallId(String,Bundle)}.
+ */
+ public static final String EXTRA_INCOMING_CALL_EXTRAS =
+ "android.intent.extra.INCOMING_CALL_EXTRAS";
+
+ /**
+ * Optional extra for {@link TelephonyManager#ACTION_PHONE_STATE_CHANGED} containing the unique
+ * ID of the call.
+ */
+ public static final String EXTRA_CALL_ID = "android.telecomm.extra.CALL_ID";
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallService.aidl b/telecomm/java/com/android/internal/telecomm/ICallService.aidl
new file mode 100644
index 0000000..3455efd
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallService.aidl
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2013 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.internal.telecomm;
+
+import android.os.Bundle;
+import android.telecomm.CallAudioState;
+import android.telecomm.CallInfo;
+
+import com.android.internal.telecomm.ICallServiceAdapter;
+
+/**
+ * Service interface for services which would like to provide calls to be
+ * managed by the system in-call UI.
+ *
+ * This interface provides methods that the android framework can use to deliver commands
+ * for calls provided by this call service including making new calls and disconnecting
+ * existing ones. A binding to ICallService implementations exists for two conditions:
+ * 1) There exists one or more live calls for that call service,
+ * 2) Prior to an outbound call to test if this call service is compatible with the outgoing call.
+ *
+ * TODO(santoscordon): Need final public-facing comments in this file.
+ * {@hide}
+ */
+oneway interface ICallService {
+
+ /**
+ * Sets an implementation of ICallServiceAdapter which the call service can use to add new calls
+ * and communicate state changes of existing calls. This is the first method that is called
+ * after the framework binds to the call service.
+ *
+ * @param callServiceAdapter Interface to CallsManager for adding and updating calls.
+ */
+ void setCallServiceAdapter(in ICallServiceAdapter callServiceAdapter);
+
+ /**
+ * Determines if the ICallService can place the specified call. Response is sent via
+ * {@link ICallServiceAdapter#setCompatibleWith}. When responding, the correct call ID must be
+ * specified. It is expected that the call service respond within 500 milliseconds. Any response
+ * that takes longer than 500 milliseconds will be treated as being incompatible.
+ * TODO(santoscordon): 500 ms was arbitrarily chosen and must be confirmed before this
+ * API is made public. Only used in the context of outgoing calls and call switching (handoff).
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ void isCompatibleWith(in CallInfo callInfo);
+
+ /**
+ * Attempts to call the relevant party using the specified call's handle, be it a phone number,
+ * SIP address, or some other kind of user ID. Note that the set of handle types is
+ * dynamically extensible since call providers should be able to implement arbitrary
+ * handle-calling systems. See {@link #isCompatibleWith}. It is expected that the
+ * call service respond via {@link ICallServiceAdapter#handleSuccessfulOutgoingCall} if it can
+ * successfully make the call. Only used in the context of outgoing calls.
+ * TODO(santoscordon): Figure out how a call service can short-circuit a failure to the adapter.
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ void call(in CallInfo callInfo);
+
+ /**
+ * Aborts the outgoing call attempt. Invoked in the unlikely event that Telecomm decides to
+ * abort an attempt to place a call. Only ever be invoked after {@link #call} invocations.
+ * After this is invoked, Telecomm does not expect any more updates about the call and will
+ * actively ignore any such update. This is different from {@link #disconnect} where Telecomm
+ * expects confirmation via ICallServiceAdapter.markCallAsDisconnected.
+ *
+ * @param callId The identifier of the call to abort.
+ */
+ void abort(String callId);
+
+ /**
+ * Receives a new call ID to use with an incoming call. Invoked by Telecomm after it is notified
+ * that this call service has a pending incoming call, see
+ * {@link TelecommConstants#ACTION_INCOMING_CALL}. The call service must first give Telecomm
+ * additional information of the call through {@link ICallServiceAdapter#handleIncomingCall}.
+ * Following that, the call service can update the call at will using the specified call ID.
+ *
+ * As part of the {@link TelecommConstants#ACTION_INCOMING_CALL} Intent, a Bundle of extra
+ * data could be sent via {@link TelecommConstants#EXTRA_INCOMING_CALL_EXTRAS}, which is
+ * returned through this method. If no data was given, an empty Bundle will be returned.
+ *
+ * @param callId The ID of the call.
+ * @param extras The Bundle of extra information passed via
+ * {@link TelecommConstants#EXTRA_INCOMING_CALL_EXTRAS}.
+ */
+ void setIncomingCallId(String callId, in Bundle extras);
+
+ /**
+ * Answers a ringing call identified by callId. Telecomm invokes this method as a result of the
+ * user hitting the "answer" button in the incoming call screen.
+ *
+ * @param callId The ID of the call.
+ */
+ void answer(String callId);
+
+ /**
+ * Rejects a ringing call identified by callId. Telecomm invokes this method as a result of the
+ * user hitting the "reject" button in the incoming call screen.
+ *
+ * @param callId The ID of the call.
+ */
+ void reject(String callId);
+
+ /**
+ * Disconnects the call identified by callId. Used for outgoing and incoming calls.
+ *
+ * @param callId The identifier of the call to disconnect.
+ */
+ void disconnect(String callId);
+
+ /**
+ * Puts the call identified by callId on hold. Telecomm invokes this method when a call should
+ * be placed on hold per user request or because a different call was made active.
+ *
+ * @param callId The identifier of the call to put on hold.
+ */
+ void hold(String callId);
+
+ /**
+ * Removes the call identified by callId from hold. Telecomm invokes this method when a call
+ * should be removed on hold per user request or because a different call was put on hold.
+ *
+ * @param callId The identifier of the call to remove from hold.
+ */
+ void unhold(String callId);
+
+ /**
+ * Called when the audio state changes.
+ *
+ * @param activeCallId The identifier of the call that was active during the state change.
+ * @param audioState The new {@link CallAudioState}.
+ */
+ void onAudioStateChanged(String activeCallId, in CallAudioState audioState);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
new file mode 100644
index 0000000..e96defe
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceAdapter.aidl
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 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.internal.telecomm;
+
+import android.telecomm.CallInfo;
+
+/**
+ * Provides methods for ICallService implementations to interact with the system phone app.
+ * TODO(santoscordon): Need final public-facing comments in this file.
+ * {@hide}
+ */
+oneway interface ICallServiceAdapter {
+
+ /**
+ * Receives confirmation of a call service's ability to place a call. This method is used in
+ * response to {@link ICallService#isCompatibleWith}.
+ *
+ * @param callId The identifier of the call for which compatibility is being received. This ID
+ * should correspond to the ID given as part of the call information in
+ * {@link ICallService#isCompatibleWith}.
+ * @param isCompatible True if the call service can place the call.
+ */
+ void setIsCompatibleWith(String callId, boolean isCompatible);
+
+ /**
+ * Provides Telecomm with the details of an incoming call. An invocation of this method must
+ * follow {@link CallService#setIncomingCallId} and use the call ID specified therein. Upon
+ * the invocation of this method, Telecomm will bring up the incoming-call interface where the
+ * user can elect to answer or reject a call.
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ void notifyIncomingCall(in CallInfo callInfo);
+
+ /**
+ * Tells Telecomm that an attempt to place the specified outgoing call succeeded.
+ * TODO(santoscordon): Consider adding a CallState parameter in case this outgoing call is
+ * somehow no longer in the DIALING state.
+ *
+ * @param callId The ID of the outgoing call.
+ */
+ void handleSuccessfulOutgoingCall(String callId);
+
+ /**
+ * Tells Telecomm that an attempt to place the specified outgoing call failed.
+ *
+ * @param callId The ID of the outgoing call.
+ * @param errorMessage The error associated with the failed call attempt.
+ */
+ void handleFailedOutgoingCall(String callId, String errorMessage);
+
+ /**
+ * Sets a call's state to active (e.g., an ongoing call where two parties can actively
+ * communicate).
+ *
+ * @param callId The unique ID of the call whose state is changing to active.
+ */
+ void setActive(String callId);
+
+ /**
+ * Sets a call's state to ringing (e.g., an inbound ringing call).
+ *
+ * @param callId The unique ID of the call whose state is changing to ringing.
+ */
+ void setRinging(String callId);
+
+ /**
+ * Sets a call's state to dialing (e.g., dialing an outbound call).
+ *
+ * @param callId The unique ID of the call whose state is changing to dialing.
+ */
+ void setDialing(String callId);
+
+ /**
+ * Sets a call's state to disconnected.
+ *
+ * @param callId The unique ID of the call whose state is changing to disconnected.
+ */
+ void setDisconnected(String callId);
+
+ /**
+ * Sets a call's state to be on hold.
+ *
+ * @param callId The unique ID of the call whose state is changing to be on hold.
+ */
+ void setOnHold(String callId);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceLookupResponse.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceLookupResponse.aidl
new file mode 100644
index 0000000..97fa834
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceLookupResponse.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.internal.telecomm;
+
+import android.os.IBinder;
+import android.telecomm.CallServiceDescriptor;
+import java.util.List;
+
+/**
+ * Used by {@link ICallServiceProvider} to return a list of {@link CallServiceDescriptor}s.
+ * {@hide}
+ */
+oneway interface ICallServiceLookupResponse {
+ /**
+ * Passes the sorted list of preferred {@link CallServiceDescriptor}s back to Telecomm. Used
+ * in the context of attempting to place a pending outgoing call.
+ *
+ * @param callServiceDescriptors The set of call-service descriptors from
+ * {@link ICallServiceProvider}.
+ */
+ void setCallServiceDescriptors(in List<CallServiceDescriptor> callServiceDescriptors);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceProvider.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceProvider.aidl
new file mode 100644
index 0000000..39feddd
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceProvider.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 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.internal.telecomm;
+
+import android.telecomm.CallServiceDescriptor;
+
+import com.android.internal.telecomm.ICallServiceLookupResponse;
+
+/**
+ * Interface for applications interested in providing call-service implementations. Only used in
+ * outgoing-call scenarios where the best-candidate service to issue the call over may need to be
+ * decided dynamically (unlike incoming call scenario where the call-service is known).
+ *
+ * Intended usage at time of writing is: Call intent received by the CallsManager, which in turn
+ * gathers and binds all ICallServiceProvider implementations (using the framework). Once bound, the
+ * CallsManager invokes the lookupCallServices API of each bound provider and waits until
+ * either all providers reply (asynchronously) or some timeout is met. The resulted list is then
+ * processed by the CallsManager and its helpers (potentially requesting input from the user) to
+ * identify the best CallService. The user should obviously be notified upon zero candidates as
+ * well as all (one or more) candidates failing to issue the call.
+ * {@hide}
+ */
+oneway interface ICallServiceProvider {
+
+ /**
+ * Initiates the process to retrieve the list of {@link CallServiceDescriptor}s implemented by
+ * this provider.
+ * TODO(santoscordon): Needs comments on how to populate the list within
+ * ICallServiceLookupResponse and how to handle error conditions.
+ *
+ * @param response The response object through which the list of call services is sent.
+ */
+ void lookupCallServices(in ICallServiceLookupResponse response);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceSelectionResponse.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceSelectionResponse.aidl
new file mode 100644
index 0000000..8270aa5
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceSelectionResponse.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.internal.telecomm;
+
+import android.os.IBinder;
+import android.telecomm.CallServiceDescriptor;
+import java.util.List;
+
+/**
+ * Used by {@link ICallServiceSelector} to return the preferred list of {@link ICallService}
+ * implementations with which to connect the corresponding outgoing call.
+ * {@hide}
+ */
+oneway interface ICallServiceSelectionResponse {
+ /**
+ * Records the sorted set of call services that are preferred by the corresponding
+ * call-service selector.
+ *
+ * @param selectedCallServiceDescriptors The prioritized list of preferred call-service
+ * descriptors to use for completing the call.
+ */
+ void setSelectedCallServiceDescriptors(
+ in List<CallServiceDescriptor> selectedCallServiceDescriptors);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallServiceSelector.aidl b/telecomm/java/com/android/internal/telecomm/ICallServiceSelector.aidl
new file mode 100644
index 0000000..3b73d9b
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallServiceSelector.aidl
@@ -0,0 +1,91 @@
+/*
+ * 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.internal.telecomm;
+
+import android.telecomm.CallInfo;
+import android.telecomm.CallServiceDescriptor;
+
+import com.android.internal.telecomm.ICallService;
+import com.android.internal.telecomm.ICallServiceSelectionResponse;
+import com.android.internal.telecomm.ICallSwitchabilityResponse;
+
+import java.util.List;
+
+/**
+ * Interface for call-service selector implementations.
+ *
+ * Call-service selectors are ultimately responsible for deciding which of the available call
+ * service implementations should be used to place an outgoing call, as well as which service
+ * to switch the call to upon system-provided opportunities to switch call services.
+ *
+ * Outgoing call scenario:
+ *
+ * Telecomm maintains a prioritized list of call-service selectors. Upon attempting to issue
+ * outgoing calls, the switchboard iterates through these (starting with the highest-priority
+ * selector). It then invokes the "select" API below passing -- among other parameters -- the
+ * list of available call services, excluding fully-utilized services that temporarily aren't
+ * capable of accommodating additional calls. Once invoked, selectors return a sorted subset
+ * from the specified list, containing the preferred services through which to place the call.
+ * Upon empty selection the switchboard continues to the next selector. Otherwise, upon non-
+ * empty selection, the returned call services are attempted in the specified order. The flow
+ * is concluded either when the call is placed by one of the specified services (e.g. ringing)
+ * or upon failure to connect by the time the set of selectors is exhausted. Failed calls are
+ * essentially abandoned by this flow and then picked up by the switchboard's monitor.
+ *
+ * Note that attempted-yet-failed call services within one outgoing-call cycle may be omitted
+ * from the set passed to the next selector. As for selector priority, at the time of writing
+ * this is intended to be a blend of built-in priorities (e.g. to handle emergency calls) and
+ * user-specified preferences (via settings, e.g. electing to use a particular selector prior
+ * to attempting the system-default call-service selector).
+ *
+ * Call-services switching scenario (applying to both incoming and outgoing calls):
+ *
+ * The switchboard may invoke any active selector (a selector associated with one or more on-
+ * going calls) up to once per ongoing call at its discretion (e.g. periodically), once again
+ * passing the available call services to the "select" API. As in the outgoing-call scenario
+ * above, returning the empty list means "pass" -- basically indicating that the current call
+ * service for this call need not be switched at this time. In cases where switching isn't at
+ * all supported (either for a given call or globally across a given selector) , isSwitchable
+ * below can return false blindly to suppress all "select" calls beyond the initial one (that
+ * is used to establish outgoing calls).
+ * {@hide}
+ */
+oneway interface ICallServiceSelector {
+
+ /**
+ * Initiates the process to retrieve the sorted set of call services that are preferred by
+ * this call-service selector.
+ *
+ * @param callInfo The details of the relevant call.
+ * @param callServiceDescriptors The list of call-service descriptors to select from.
+ * @param response The response object through which the selected service IDs are passed back
+ * to Telecomm.
+ */
+ void select(
+ in CallInfo callInfo,
+ in List<CallServiceDescriptor> callServiceDescriptors,
+ in ICallServiceSelectionResponse response);
+
+ /**
+ * Determines if the specified ongoing call can/should be switched from the currently-used
+ * call service to another.
+ *
+ * @param callInfo The details of the relevant call.
+ * @param response The response object to be populated and returned to switchboard.
+ */
+ void isSwitchable(in CallInfo callInfo, in ICallSwitchabilityResponse response);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/ICallSwitchabilityResponse.aidl b/telecomm/java/com/android/internal/telecomm/ICallSwitchabilityResponse.aidl
new file mode 100644
index 0000000..9a7e9e5
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ICallSwitchabilityResponse.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.internal.telecomm;
+
+/**
+ * Used by {@link ICallServiceSelector}s to return whether or not the relevant
+ * call is switchable.
+ * {@hide}
+ */
+oneway interface ICallSwitchabilityResponse {
+ /**
+ * Records whether or not the corresponding call can potentially be switched to another
+ * call service.
+ *
+ * @param isSwitchable True if the associated call-service selector may be interested
+ * in switching call services. Setting isSwitchable to true should generally
+ * guarantee the "select" API of the associated selector to be invoked, hence
+ * allowing the selector to return either the empty list (meaning pass, don't
+ * switch) or the prioritized list of call-services to attempt switching to.
+ */
+ void setIsSwitchable(boolean isSwitchable);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
new file mode 100644
index 0000000..0fe3bfc
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -0,0 +1,86 @@
+/*
+ * 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.internal.telecomm;
+
+import android.telecomm.CallAudioState;
+
+/**
+ * Receives commands from {@link IInCallService} implementations which should be executed by
+ * Telecomm. When Telecomm binds to a {@link IInCallService}, an instance of this class is given to
+ * the in-call service through which it can manipulate live (active, dialing, ringing) calls. When
+ * the in-call service is notified of new calls ({@link IInCallService#addCall}), it can use the
+ * given call IDs to execute commands such as {@link #answerCall} for incoming calls or
+ * {@link #disconnectCall} for active calls the user would like to end. Some commands are only
+ * appropriate for calls in certain states; please consult each method for such limitations.
+ * TODO(santoscordon): Needs more/better comments once the API is finalized.
+ * TODO(santoscordon): Specify the adapter will stop functioning when there are no more calls.
+ * TODO(santoscordon): Once we have proper "CallState" constant definitions, consider rewording
+ * the javadoc to reference those states precisely.
+ * {@hide}
+ */
+oneway interface IInCallAdapter {
+ /**
+ * Instructs Telecomm to answer the specified call.
+ *
+ * @param callId The identifier of the call to answer.
+ */
+ void answerCall(String callId);
+
+ /**
+ * Instructs Telecomm to reject the specified call.
+ * TODO(santoscordon): Add reject-with-text-message parameter when that feature
+ * is ported over.
+ *
+ * @param callId The identifier of the call to reject.
+ */
+ void rejectCall(String callId);
+
+ /**
+ * Instructs Telecomm to disconnect the specified call.
+ *
+ * @param callId The identifier of the call to disconnect.
+ */
+ void disconnectCall(String callId);
+
+ /**
+ * Instructs Telecomm to put the specified call on hold.
+ *
+ * @param callId The identifier of the call to put on hold.
+ */
+ void holdCall(String callId);
+
+ /**
+ * Instructs Telecomm to release the specified call from hold.
+ *
+ * @param callId The identifier of the call to release from hold.
+ */
+ void unholdCall(String callId);
+
+ /**
+ * Mute the microphone.
+ *
+ * @param shouldMute True if the microphone should be muted.
+ */
+ void mute(boolean shouldMute);
+
+ /**
+ * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}.
+ *
+ * @param route The audio route to use.
+ */
+ void setAudioRoute(int route);
+}
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl
new file mode 100644
index 0000000..35498a3
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl
@@ -0,0 +1,85 @@
+/*
+ * 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.internal.telecomm;
+
+import android.telecomm.CallAudioState;
+import android.telecomm.CallInfo;
+
+import com.android.internal.telecomm.IInCallAdapter;
+
+/**
+ * This service is implemented by any app that wishes to provide the user-interface for managing
+ * phone calls. Telecomm binds to this service while there exists a live (active or incoming)
+ * call, and uses it to notify the in-call app of any live and and recently disconnected calls.
+ * TODO(santoscordon): Needs more/better description of lifecycle once the interface is better
+ * defined.
+ * TODO(santoscordon): What happens if two or more apps on a given device implement this interface?
+ * {@hide}
+ */
+oneway interface IInCallService {
+
+ /**
+ * Provides the in-call app an adapter object through which to send call-commands such as
+ * answering and rejecting incoming calls, disconnecting active calls, and putting calls in
+ * special states (mute, hold, etc).
+ *
+ * @param inCallAdapter Adapter through which an in-call app can send call-commands to Telecomm.
+ */
+ void setInCallAdapter(in IInCallAdapter inCallAdapter);
+
+ /**
+ * 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 callInfo Information about the new call.
+ */
+ void addCall(in CallInfo callInfo);
+
+ /**
+ * Indicates to the in-call app that a call has moved to the
+ * {@link android.telecomm.CallState#ACTIVE} state.
+ *
+ * @param callId The identifier of the call that became active.
+ */
+ void setActive(String callId);
+
+ /**
+ * Indicates to the in-call app that a call has been moved to the
+ * {@link android.telecomm.CallState#DISCONNECTED} and the user should be notified.
+ * TODO(santoscordon): Needs disconnect-cause either as a numberical constant, string or both
+ * depending on what is ultimately needed to support all scenarios.
+ *
+ * @param callId The identifier of the call that was disconnected.
+ */
+ void setDisconnected(String callId);
+
+ /**
+ * Indicates to the in-call app that a call has been moved to the
+ * {@link android.telecomm.CallState#HOLD} state and the user should be notified.
+ *
+ * @param callId The identifier of the call that was put on hold.
+ */
+ void setOnHold(String callId);
+
+ /**
+ * Called when the audio state changes.
+ *
+ * @param audioState The new {@link CallAudioState}.
+ */
+ void onAudioStateChanged(in CallAudioState audioState);
+}