diff options
Diffstat (limited to 'telecomm')
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"; +} |