diff options
author | Sailesh Nepal <sail@google.com> | 2014-03-19 10:15:37 -0700 |
---|---|---|
committer | Sailesh Nepal <sail@google.com> | 2014-03-23 18:20:53 -0700 |
commit | 4cff392a2b3702514e78c5419bf15de6e39c59af (patch) | |
tree | 743383d90a5fd77c09d50888a3ed7f92c5fe921d /telecomm | |
parent | 439e1f31a10775cd152ad6cf7cf0d1b9a536e49a (diff) | |
download | frameworks_base-4cff392a2b3702514e78c5419bf15de6e39c59af.zip frameworks_base-4cff392a2b3702514e78c5419bf15de6e39c59af.tar.gz frameworks_base-4cff392a2b3702514e78c5419bf15de6e39c59af.tar.bz2 |
Add audio mode APIs
Change-Id: Ia7e78b52b6b30f99a9ba066dae558a105dbebd96
Diffstat (limited to 'telecomm')
9 files changed, 294 insertions, 19 deletions
diff --git a/telecomm/java/android/telecomm/CallAudioState.aidl b/telecomm/java/android/telecomm/CallAudioState.aidl new file mode 100644 index 0000000..ae64567 --- /dev/null +++ b/telecomm/java/android/telecomm/CallAudioState.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telecomm; + +parcelable CallAudioState; diff --git a/telecomm/java/android/telecomm/CallAudioState.java b/telecomm/java/android/telecomm/CallAudioState.java new file mode 100644 index 0000000..d9a0090 --- /dev/null +++ b/telecomm/java/android/telecomm/CallAudioState.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telecomm; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Locale; + +/** + * Encapsulates all audio states during a call. + */ +public final class CallAudioState implements Parcelable { + /** Direct the audio stream through the device's earpiece. */ + public static int ROUTE_EARPIECE = 0x00000001; + + /** Direct the audio stream through Bluetooth. */ + public static int ROUTE_BLUETOOTH = 0x00000002; + + /** Direct the audio stream through a wired headset. */ + public static int ROUTE_WIRED_HEADSET = 0x00000004; + + /** Direct the audio stream through the device's spakerphone. */ + public static int ROUTE_SPEAKER = 0x00000008; + + /** + * Direct the audio stream through the device's earpiece or wired headset if one is + * connected. + */ + public static int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET; + + /** Bit mask of all possible audio routes. */ + public static int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET | + ROUTE_SPEAKER; + + /** True if the call is muted, false otherwise. */ + public final boolean isMuted; + + /** The route to use for the audio stream. */ + public final int route; + + /** Bit vector of all routes supported by this call. */ + public final int supportedRouteMask; + + /** @hide */ + public CallAudioState(boolean isMuted, int route, int supportedRouteMask) { + this.isMuted = isMuted; + this.route = route; + this.supportedRouteMask = supportedRouteMask; + } + + /** @hide */ + public CallAudioState(CallAudioState state) { + isMuted = state.isMuted; + route = state.route; + supportedRouteMask = state.supportedRouteMask; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof CallAudioState)) { + return false; + } + CallAudioState state = (CallAudioState) obj; + return isMuted == state.isMuted && route == state.route && + supportedRouteMask == state.supportedRouteMask; + } + + @Override + public String toString() { + return String.format(Locale.US, + "[CallAudioState isMuted: %b, route; %s, supportedRouteMask: %s]", + isMuted, audioRouteToString(route), audioRouteToString(supportedRouteMask)); + } + + /** @hide */ + public static String audioRouteToString(int route) { + if (route == 0 || (route & ~ROUTE_ALL) != 0x0) { + return "UNKNOWN"; + } + + StringBuffer buffer = new StringBuffer(); + if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) { + listAppend(buffer, "EARPIECE"); + } + if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) { + listAppend(buffer, "BLUETOOTH"); + } + if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) { + listAppend(buffer, "WIRED_HEADSET"); + } + if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) { + listAppend(buffer, "SPEAKER"); + } + + return buffer.toString(); + } + + private static void listAppend(StringBuffer buffer, String str) { + if (buffer.length() > 0) { + buffer.append(", "); + } + buffer.append(str); + } + + /** + * Responsible for creating CallAudioState objects for deserialized Parcels. + */ + public static final Parcelable.Creator<CallAudioState> CREATOR = + new Parcelable.Creator<CallAudioState> () { + + @Override + public CallAudioState createFromParcel(Parcel source) { + boolean isMuted = source.readByte() == 0 ? false : true; + int route = source.readInt(); + int supportedRouteMask = source.readInt(); + return new CallAudioState(isMuted, route, supportedRouteMask); + } + + @Override + public CallAudioState[] newArray(int size) { + return new CallAudioState[size]; + } + }; + + /** + * {@inheritDoc} + */ + @Override + public int describeContents() { + return 0; + } + + /** + * Writes CallAudioState object into a serializeable Parcel. + */ + @Override + public void writeToParcel(Parcel destination, int flags) { + destination.writeByte((byte) (isMuted ? 1 : 0)); + destination.writeInt(route); + destination.writeInt(supportedRouteMask); + } +} diff --git a/telecomm/java/android/telecomm/CallInfo.java b/telecomm/java/android/telecomm/CallInfo.java index b1413a6..718bc53 100644 --- a/telecomm/java/android/telecomm/CallInfo.java +++ b/telecomm/java/android/telecomm/CallInfo.java @@ -19,7 +19,6 @@ package android.telecomm; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -import android.os.Parcelable; import java.util.Date; import java.util.UUID; diff --git a/telecomm/java/android/telecomm/CallService.java b/telecomm/java/android/telecomm/CallService.java index 395bcc1..3b88be1 100644 --- a/telecomm/java/android/telecomm/CallService.java +++ b/telecomm/java/android/telecomm/CallService.java @@ -46,6 +46,18 @@ import com.android.internal.telecomm.ICallServiceAdapter; */ public abstract class CallService extends Service { + private static final int MSG_SET_CALL_SERVICE_ADAPTER = 1; + private static final int MSG_IS_COMPATIBLE_WITH = 2; + private static final int MSG_CALL = 3; + private static final int MSG_ABORT = 4; + private static final int MSG_SET_INCOMING_CALL_ID = 5; + private static final int MSG_ANSWER = 6; + private static final int MSG_REJECT = 7; + private static final int MSG_DISCONNECT = 8; + private static final int MSG_HOLD = 9; + private static final int MSG_UNHOLD = 10; + private static final int MSG_ON_AUDIO_STATE_CHANGED = 11; + /** * Default Handler used to consolidate binder method calls onto a single thread. */ @@ -67,7 +79,7 @@ public abstract class CallService extends Service { case MSG_ABORT: abort((String) msg.obj); break; - case MSG_SET_INCOMING_CALL_ID: + case MSG_SET_INCOMING_CALL_ID: { SomeArgs args = (SomeArgs) msg.obj; try { String callId = (String) args.arg1; @@ -77,6 +89,7 @@ public abstract class CallService extends Service { args.recycle(); } break; + } case MSG_ANSWER: answer((String) msg.obj); break; @@ -92,6 +105,17 @@ public abstract class CallService extends Service { case MSG_UNHOLD: unhold((String) msg.obj); break; + case MSG_ON_AUDIO_STATE_CHANGED: { + SomeArgs args = (SomeArgs) msg.obj; + try { + String callId = (String) args.arg1; + CallAudioState audioState = (CallAudioState) args.arg2; + onAudioStateChanged(callId, audioState); + } finally { + args.recycle(); + } + break; + } default: break; } @@ -155,24 +179,15 @@ public abstract class CallService extends Service { public void unhold(String callId) { mMessageHandler.obtainMessage(MSG_UNHOLD, 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_ABORT = 4, - MSG_SET_INCOMING_CALL_ID = 5, - MSG_ANSWER = 6, - MSG_REJECT = 7, - MSG_DISCONNECT = 8, - MSG_HOLD = 9, - MSG_UNHOLD = 10; + @Override + public void onAudioStateChanged(String callId, CallAudioState audioState) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = callId; + args.arg2 = audioState; + mMessageHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget(); + } + } /** * Message handler for consolidating binder callbacks onto a single thread. @@ -290,4 +305,12 @@ public abstract class CallService extends Service { * @param callId The ID of the call to unhold. */ public abstract void unhold(String callId); + + /** + * Called when the audio state changes. + * + * @param activeCallId The identifier of the call that was active during the state change. + * @param audioState The new {@link CallAudioState}. + */ + public abstract void onAudioStateChanged(String activeCallId, CallAudioState audioState); } diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java index 6649ef7..0a8571a 100644 --- a/telecomm/java/android/telecomm/InCallAdapter.java +++ b/telecomm/java/android/telecomm/InCallAdapter.java @@ -102,4 +102,28 @@ public final class InCallAdapter { } catch (RemoteException e) { } } + + /** + * Mute the microphone. + * + * @param shouldMute True if the microphone should be muted. + */ + public void mute(boolean shouldMute) { + try { + mAdapter.mute(shouldMute); + } catch (RemoteException e) { + } + } + + /** + * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}. + * + * @param route The audio route to use. + */ + public void setAudioRoute(int route) { + try { + mAdapter.setAudioRoute(route); + } catch (RemoteException e) { + } + } } diff --git a/telecomm/java/android/telecomm/InCallService.java b/telecomm/java/android/telecomm/InCallService.java index cd6a882..ef15a61 100644 --- a/telecomm/java/android/telecomm/InCallService.java +++ b/telecomm/java/android/telecomm/InCallService.java @@ -40,6 +40,7 @@ public abstract class InCallService extends Service { private static final int MSG_SET_ACTIVE = 3; private static final int MSG_SET_DISCONNECTED = 4; private static final int MSG_SET_HOLD = 5; + private static final int MSG_ON_AUDIO_STATE_CHANGED = 6; /** Default Handler used to consolidate binder method calls onto a single thread. */ private final Handler mHandler = new Handler(Looper.getMainLooper()) { @@ -61,6 +62,9 @@ public abstract class InCallService extends Service { break; case MSG_SET_HOLD: setOnHold((String) msg.obj); + break; + case MSG_ON_AUDIO_STATE_CHANGED: + onAudioStateChanged((CallAudioState) msg.obj); default: break; } @@ -98,6 +102,12 @@ public abstract class InCallService extends Service { public void setOnHold(String callId) { mHandler.obtainMessage(MSG_SET_HOLD, callId).sendToTarget(); } + + /** {@inheritDoc} */ + @Override + public void onAudioStateChanged(CallAudioState audioState) { + mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget(); + } } private final InCallServiceBinder mBinder; @@ -153,4 +163,11 @@ public abstract class InCallService extends Service { * @param callId The identifier of the call that was put on hold. */ protected abstract void setOnHold(String callId); + + /** + * Called when the audio state changes. + * + * @param audioState The new {@link CallAudioState}. + */ + protected abstract void onAudioStateChanged(CallAudioState audioState); } diff --git a/telecomm/java/com/android/internal/telecomm/ICallService.aidl b/telecomm/java/com/android/internal/telecomm/ICallService.aidl index d05a3e0..3455efd 100644 --- a/telecomm/java/com/android/internal/telecomm/ICallService.aidl +++ b/telecomm/java/com/android/internal/telecomm/ICallService.aidl @@ -17,6 +17,7 @@ package com.android.internal.telecomm; import android.os.Bundle; +import android.telecomm.CallAudioState; import android.telecomm.CallInfo; import com.android.internal.telecomm.ICallServiceAdapter; @@ -136,4 +137,12 @@ oneway interface ICallService { * @param callId The identifier of the call to remove from hold. */ void unhold(String callId); + + /** + * Called when the audio state changes. + * + * @param activeCallId The identifier of the call that was active during the state change. + * @param audioState The new {@link CallAudioState}. + */ + void onAudioStateChanged(String activeCallId, in CallAudioState audioState); } diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl index 6ae055d..0fe3bfc 100644 --- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl @@ -16,6 +16,8 @@ package com.android.internal.telecomm; +import android.telecomm.CallAudioState; + /** * Receives commands from {@link IInCallService} implementations which should be executed by * Telecomm. When Telecomm binds to a {@link IInCallService}, an instance of this class is given to @@ -67,4 +69,18 @@ oneway interface IInCallAdapter { * @param callId The identifier of the call to release from hold. */ void unholdCall(String callId); + + /** + * Mute the microphone. + * + * @param shouldMute True if the microphone should be muted. + */ + void mute(boolean shouldMute); + + /** + * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}. + * + * @param route The audio route to use. + */ + void setAudioRoute(int route); } diff --git a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl index b3bd0a6..35498a3 100644 --- a/telecomm/java/com/android/internal/telecomm/IInCallService.aidl +++ b/telecomm/java/com/android/internal/telecomm/IInCallService.aidl @@ -16,6 +16,7 @@ package com.android.internal.telecomm; +import android.telecomm.CallAudioState; import android.telecomm.CallInfo; import com.android.internal.telecomm.IInCallAdapter; @@ -74,4 +75,11 @@ oneway interface IInCallService { * @param callId The identifier of the call that was put on hold. */ void setOnHold(String callId); + + /** + * Called when the audio state changes. + * + * @param audioState The new {@link CallAudioState}. + */ + void onAudioStateChanged(in CallAudioState audioState); } |