summaryrefslogtreecommitdiffstats
path: root/telecomm
diff options
context:
space:
mode:
Diffstat (limited to 'telecomm')
-rw-r--r--telecomm/java/android/telecomm/CallInfo.aidl19
-rw-r--r--telecomm/java/android/telecomm/CallInfo.java127
-rw-r--r--telecomm/java/android/telecomm/CallService.java239
-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/CallServiceProvider.java109
-rw-r--r--telecomm/java/android/telecomm/CallServiceSelector.java204
-rw-r--r--telecomm/java/android/telecomm/CallState.java72
-rw-r--r--telecomm/java/android/telecomm/ICallService.aidl110
-rw-r--r--telecomm/java/android/telecomm/ICallServiceAdapter.aidl95
-rw-r--r--telecomm/java/android/telecomm/ICallServiceLookupResponse.aidl35
-rw-r--r--telecomm/java/android/telecomm/ICallServiceProvider.aidl45
-rw-r--r--telecomm/java/android/telecomm/ICallServiceSelectionResponse.aidl37
-rw-r--r--telecomm/java/android/telecomm/ICallServiceSelector.aidl89
-rw-r--r--telecomm/java/android/telecomm/ICallSwitchabilityResponse.aidl35
-rw-r--r--telecomm/java/android/telecomm/IInCallAdapter.aidl55
-rw-r--r--telecomm/java/android/telecomm/IInCallService.aidl68
-rw-r--r--telecomm/java/android/telecomm/README2
-rw-r--r--telecomm/java/android/telecomm/TelecommConstants.java55
19 files changed, 1624 insertions, 0 deletions
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..b818e6d
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallInfo.java
@@ -0,0 +1,127 @@
+/*
+ * 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.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 String mHandle;
+
+ // 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.
+
+ /**
+ * 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.
+ */
+ public CallInfo(String id, CallState state, String handle) {
+ mId = id;
+ mState = state;
+ mHandle = handle;
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public CallState getState() {
+ return mState;
+ }
+
+ public String getHandle() {
+ return mHandle;
+ }
+
+ //
+ // 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());
+ String handle = source.readString();
+
+ return new CallInfo(id, state, handle);
+ }
+
+ @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());
+ destination.writeString(mHandle);
+ }
+}
diff --git a/telecomm/java/android/telecomm/CallService.java b/telecomm/java/android/telecomm/CallService.java
new file mode 100644
index 0000000..8767ffa
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallService.java
@@ -0,0 +1,239 @@
+/*
+ * 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;
+
+/**
+ * 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 ICallServiceAdapter} 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 {
+
+ /**
+ * 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:
+ setCallServiceAdapter((ICallServiceAdapter) msg.obj);
+ break;
+ case MSG_IS_COMPATIBLE_WITH:
+ isCompatibleWith((CallInfo) msg.obj);
+ break;
+ case MSG_CALL:
+ call((CallInfo) msg.obj);
+ break;
+ case MSG_DISCONNECT:
+ disconnect((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;
+ 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 disconnect(String callId) {
+ mMessageHandler.obtainMessage(MSG_DISCONNECT, 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();
+ }
+ }
+
+ // 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_SET_CALL_SERVICE_ADAPTER = 1,
+ MSG_IS_COMPATIBLE_WITH = 2,
+ MSG_CALL = 3,
+ MSG_DISCONNECT = 4,
+ MSG_SET_INCOMING_CALL_ID = 5,
+ MSG_ANSWER = 6,
+ MSG_REJECT = 7;
+
+ /**
+ * 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 ICallServiceAdapter for adding new calls and communicating state
+ * changes of existing calls.
+ * TODO(santoscordon): Should we not reference ICallServiceAdapter directly from here? Should we
+ * wrap that in a wrapper like we do for CallService/ICallService?
+ *
+ * @param callServiceAdapter Adapter object for communicating call to CallsManager
+ */
+ public abstract void setCallServiceAdapter(ICallServiceAdapter callServiceAdapter);
+
+ /**
+ * Determines if the CallService can place the specified call. Response is sent via
+ * {@link ICallServiceAdapter#setCompatibleWith}. When responding, the correct call ID must be
+ * specified.
+ *
+ * @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 ICallServiceAdapter#handleSuccessfulOutgoingCall(String)}
+ * if it can successfully make the call.
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ public abstract void call(CallInfo callInfo);
+
+ /**
+ * Disconnects the specified call.
+ *
+ * @param callId The ID of the call to disconnect.
+ */
+ public abstract void disconnect(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 ICallServiceAdapter#handleIncomingCall}.
+ * 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);
+}
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/CallServiceProvider.java b/telecomm/java/android/telecomm/CallServiceProvider.java
new file mode 100644
index 0000000..64294d8
--- /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 android.telecomm.ICallServiceProvider;
+import android.telecomm.ICallServiceLookupResponse;
+
+/**
+ * Base implementation of {@link ICallServiceProvider} 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
+ * {@link ICallServiceProvider} 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:
+ lookupCallServices((ICallServiceLookupResponse) msg.obj);
+ break;
+ default:
+ 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 ICallService}s implemented by
+ * this provider.
+ *
+ * @param response The response object through which the list of call services is sent.
+ */
+ public abstract void lookupCallServices(ICallServiceLookupResponse response);
+}
diff --git a/telecomm/java/android/telecomm/CallServiceSelector.java b/telecomm/java/android/telecomm/CallServiceSelector.java
new file mode 100644
index 0000000..6937bdf
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallServiceSelector.java
@@ -0,0 +1,204 @@
+/*
+ * 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 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 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..d4a45f9
--- /dev/null
+++ b/telecomm/java/android/telecomm/CallState.java
@@ -0,0 +1,72 @@
+/*
+ * 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 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.
+ */
+ ABORTED;
+}
diff --git a/telecomm/java/android/telecomm/ICallService.aidl b/telecomm/java/android/telecomm/ICallService.aidl
new file mode 100644
index 0000000..382bdd5
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallService.aidl
@@ -0,0 +1,110 @@
+/*
+ * 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.os.Bundle;
+import android.telecomm.CallInfo;
+import android.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.
+ */
+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 a 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.
+ *
+ * @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.
+ * 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);
+
+ /**
+ * Disconnects the call identified by callId.
+ *
+ * @param callId The identifier of the call to disconnect.
+ */
+ void disconnect(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);
+}
diff --git a/telecomm/java/android/telecomm/ICallServiceAdapter.aidl b/telecomm/java/android/telecomm/ICallServiceAdapter.aidl
new file mode 100644
index 0000000..2e03d39
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallServiceAdapter.aidl
@@ -0,0 +1,95 @@
+/*
+ * 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.telecomm.CallInfo;
+
+/**
+ * Provides methods for ICallService implementations to interact with the system phone app.
+ * TODO(santoscordon): Need final public-facing comments in this file.
+ */
+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}.
+ * TODO(santoscordon): rename to setIsCompatibleWith().
+ *
+ * @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 setCompatibleWith(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.
+ * TODO(santoscordon): Consider renaming from handle* to notify*.
+ *
+ * @param callInfo The details of the relevant call.
+ */
+ void handleIncomingCall(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);
+}
diff --git a/telecomm/java/android/telecomm/ICallServiceLookupResponse.aidl b/telecomm/java/android/telecomm/ICallServiceLookupResponse.aidl
new file mode 100644
index 0000000..2f27257
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallServiceLookupResponse.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.IBinder;
+import android.telecomm.CallServiceDescriptor;
+import java.util.List;
+
+/**
+ * Used by {@link ICallServiceProvider} to return a list of {@link CallServiceDescriptor}s.
+ */
+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/android/telecomm/ICallServiceProvider.aidl b/telecomm/java/android/telecomm/ICallServiceProvider.aidl
new file mode 100644
index 0000000..8b0a736
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallServiceProvider.aidl
@@ -0,0 +1,45 @@
+/*
+ * 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.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.
+ */
+oneway interface ICallServiceProvider {
+
+ /**
+ * Initiates the process to retrieve the list of {@link ICallService}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/android/telecomm/ICallServiceSelectionResponse.aidl b/telecomm/java/android/telecomm/ICallServiceSelectionResponse.aidl
new file mode 100644
index 0000000..51efb8e
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallServiceSelectionResponse.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.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.
+ */
+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/android/telecomm/ICallServiceSelector.aidl b/telecomm/java/android/telecomm/ICallServiceSelector.aidl
new file mode 100644
index 0000000..8ca4c0c
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallServiceSelector.aidl
@@ -0,0 +1,89 @@
+/*
+ * 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.telecomm.CallInfo;
+import android.telecomm.CallServiceDescriptor;
+import android.telecomm.ICallService;
+import android.telecomm.ICallServiceSelectionResponse;
+import android.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).
+ */
+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/android/telecomm/ICallSwitchabilityResponse.aidl b/telecomm/java/android/telecomm/ICallSwitchabilityResponse.aidl
new file mode 100644
index 0000000..afb4122
--- /dev/null
+++ b/telecomm/java/android/telecomm/ICallSwitchabilityResponse.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+/**
+ * Used by {@link ICallServiceSelector}s to return whether or not the relevant
+ * call is switchable.
+ */
+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/android/telecomm/IInCallAdapter.aidl b/telecomm/java/android/telecomm/IInCallAdapter.aidl
new file mode 100644
index 0000000..9fb7d4d
--- /dev/null
+++ b/telecomm/java/android/telecomm/IInCallAdapter.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+/**
+ * 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.
+ */
+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);
+}
diff --git a/telecomm/java/android/telecomm/IInCallService.aidl b/telecomm/java/android/telecomm/IInCallService.aidl
new file mode 100644
index 0000000..bc3a6b6
--- /dev/null
+++ b/telecomm/java/android/telecomm/IInCallService.aidl
@@ -0,0 +1,68 @@
+/*
+ * 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.telecomm.CallInfo;
+import android.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 decide implement this interface?
+ */
+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 active state.
+ * TODO(santoscordon): link javadoc to "active" constant once CallState is defined.
+ *
+ * @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 disconnected and the user should be
+ * notified.
+ * TODO(santoscordon): link javadoc to "disconnected" constant once CallState is defined.
+ * 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);
+}
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..564f0cb
--- /dev/null
+++ b/telecomm/java/android/telecomm/TelecommConstants.java
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+/**
+ * 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";
+
+ /**
+ * 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";
+}