Loading Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ LOCAL_SRC_FILES += \ location/java/android/location/INetInitiatedListener.aidl \ media/java/android/media/IAudioService.aidl \ media/java/android/media/IAudioFocusDispatcher.aidl \ media/java/android/media/IAudioRoutesObserver.aidl \ media/java/android/media/IMediaScannerListener.aidl \ media/java/android/media/IMediaScannerService.aidl \ media/java/android/media/IRemoteControlClient.aidl \ Loading media/java/android/media/AudioRoutesInfo.aidl 0 → 100644 +18 −0 Original line number Diff line number Diff line /* Copyright 2012, 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.media; parcelable AudioRoutesInfo; media/java/android/media/AudioRoutesInfo.java 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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.media; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; /** * Information available from AudioService about the current routes. * @hide */ public class AudioRoutesInfo implements Parcelable { static final int MAIN_SPEAKER = 0; static final int MAIN_HEADSET = 1<<0; static final int MAIN_HEADPHONES = 1<<1; static final int MAIN_DOCK_SPEAKERS = 1<<2; static final int MAIN_HDMI = 1<<3; CharSequence mBluetoothName; int mMainType = MAIN_SPEAKER; public AudioRoutesInfo() { } public AudioRoutesInfo(AudioRoutesInfo o) { mBluetoothName = o.mBluetoothName; mMainType = o.mMainType; } AudioRoutesInfo(Parcel src) { mBluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src); mMainType = src.readInt(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { TextUtils.writeToParcel(mBluetoothName, dest, flags); dest.writeInt(mMainType); } public static final Parcelable.Creator<AudioRoutesInfo> CREATOR = new Parcelable.Creator<AudioRoutesInfo>() { public AudioRoutesInfo createFromParcel(Parcel in) { return new AudioRoutesInfo(in); } public AudioRoutesInfo[] newArray(int size) { return new AudioRoutesInfo[size]; } }; } media/java/android/media/AudioService.java +80 −2 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; Loading @@ -62,6 +63,7 @@ import android.provider.Settings.System; import android.speech.RecognizerIntent; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.VolumePanel; Loading Loading @@ -135,10 +137,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private static final int MSG_RCDISPLAY_UPDATE = 13; private static final int MSG_SET_ALL_VOLUMES = 14; private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15; private static final int MSG_REPORT_NEW_ROUTES = 16; // messages handled under wakelock, can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16; private static final int MSG_SET_A2DP_CONNECTION_STATE = 17; private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 17; private static final int MSG_SET_A2DP_CONNECTION_STATE = 18; // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be Loading Loading @@ -397,6 +400,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private boolean mBluetoothA2dpEnabled; private final Object mBluetoothA2dpEnabledLock = new Object(); // Monitoring of audio routes. Protected by mCurAudioRoutes. final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo(); final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers = new RemoteCallbackList<IAudioRoutesObserver>(); /////////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////////// Loading Loading @@ -3011,6 +3019,26 @@ public class AudioService extends IAudioService.Stub implements OnFinished { onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1); mMediaEventWakeLock.release(); break; case MSG_REPORT_NEW_ROUTES: { int N = mRoutesObservers.beginBroadcast(); if (N > 0) { AudioRoutesInfo routes; synchronized (mCurAudioRoutes) { routes = new AudioRoutesInfo(mCurAudioRoutes); } while (N > 0) { N--; IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N); try { obs.dispatchAudioRoutesChanged(routes); } catch (RemoteException e) { } } } mRoutesObservers.finishBroadcast(); break; } } } } Loading Loading @@ -3127,6 +3155,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } else { makeA2dpDeviceUnavailableNow(address); } synchronized (mCurAudioRoutes) { if (mCurAudioRoutes.mBluetoothName != null) { mCurAudioRoutes.mBluetoothName = null; sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP, 0, 0, null, 0); } } } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) { if (btDevice.isBluetoothDock()) { // this could be a reconnection after a transient disconnection Loading @@ -3141,6 +3176,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } makeA2dpDeviceAvailable(address); synchronized (mCurAudioRoutes) { String name = btDevice.getAliasName(); if (!TextUtils.equals(mCurAudioRoutes.mBluetoothName, name)) { mCurAudioRoutes.mBluetoothName = name; sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP, 0, 0, null, 0); } } } } } Loading Loading @@ -3204,20 +3247,43 @@ public class AudioService extends IAudioService.Stub implements OnFinished { intent.putExtra("name", name); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); int connType = 0; if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) { connType = AudioRoutesInfo.MAIN_HEADSET; intent.setAction(Intent.ACTION_HEADSET_PLUG); intent.putExtra("microphone", 1); } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) { connType = AudioRoutesInfo.MAIN_HEADPHONES; intent.setAction(Intent.ACTION_HEADSET_PLUG); intent.putExtra("microphone", 0); } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) { connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS; intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG); } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) { connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS; intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG); } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) { connType = AudioRoutesInfo.MAIN_HDMI; intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG); } synchronized (mCurAudioRoutes) { if (connType != 0) { int newConn = mCurAudioRoutes.mMainType; if (state != 0) { newConn |= connType; } else { newConn &= ~connType; } if (newConn != mCurAudioRoutes.mMainType) { mCurAudioRoutes.mMainType = newConn; sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP, 0, 0, null, 0); } } } ActivityManagerNative.broadcastStickyIntent(intent, null); } Loading Loading @@ -4795,6 +4861,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished { return mRingtonePlayer; } @Override public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { synchronized (mCurAudioRoutes) { AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes); mRoutesObservers.register(observer); return routes; } } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); Loading @@ -4803,5 +4878,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished { dumpFocusStack(pw); dumpRCStack(pw); dumpStreamStates(pw); pw.println("\nAudio routes:"); pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType)); pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName); } } media/java/android/media/IAudioRoutesObserver.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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.media; import android.media.AudioRoutesInfo; /** * AIDL for the AudioService to report changes in available audio routes. * @hide */ oneway interface IAudioRoutesObserver { void dispatchAudioRoutesChanged(in AudioRoutesInfo newRoutes); } Loading
Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ LOCAL_SRC_FILES += \ location/java/android/location/INetInitiatedListener.aidl \ media/java/android/media/IAudioService.aidl \ media/java/android/media/IAudioFocusDispatcher.aidl \ media/java/android/media/IAudioRoutesObserver.aidl \ media/java/android/media/IMediaScannerListener.aidl \ media/java/android/media/IMediaScannerService.aidl \ media/java/android/media/IRemoteControlClient.aidl \ Loading
media/java/android/media/AudioRoutesInfo.aidl 0 → 100644 +18 −0 Original line number Diff line number Diff line /* Copyright 2012, 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.media; parcelable AudioRoutesInfo;
media/java/android/media/AudioRoutesInfo.java 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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.media; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; /** * Information available from AudioService about the current routes. * @hide */ public class AudioRoutesInfo implements Parcelable { static final int MAIN_SPEAKER = 0; static final int MAIN_HEADSET = 1<<0; static final int MAIN_HEADPHONES = 1<<1; static final int MAIN_DOCK_SPEAKERS = 1<<2; static final int MAIN_HDMI = 1<<3; CharSequence mBluetoothName; int mMainType = MAIN_SPEAKER; public AudioRoutesInfo() { } public AudioRoutesInfo(AudioRoutesInfo o) { mBluetoothName = o.mBluetoothName; mMainType = o.mMainType; } AudioRoutesInfo(Parcel src) { mBluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src); mMainType = src.readInt(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { TextUtils.writeToParcel(mBluetoothName, dest, flags); dest.writeInt(mMainType); } public static final Parcelable.Creator<AudioRoutesInfo> CREATOR = new Parcelable.Creator<AudioRoutesInfo>() { public AudioRoutesInfo createFromParcel(Parcel in) { return new AudioRoutesInfo(in); } public AudioRoutesInfo[] newArray(int size) { return new AudioRoutesInfo[size]; } }; }
media/java/android/media/AudioService.java +80 −2 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; Loading @@ -62,6 +63,7 @@ import android.provider.Settings.System; import android.speech.RecognizerIntent; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.VolumePanel; Loading Loading @@ -135,10 +137,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private static final int MSG_RCDISPLAY_UPDATE = 13; private static final int MSG_SET_ALL_VOLUMES = 14; private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15; private static final int MSG_REPORT_NEW_ROUTES = 16; // messages handled under wakelock, can only be queued, i.e. sent with queueMsgUnderWakeLock(), // and not with sendMsg(..., ..., SENDMSG_QUEUE, ...) private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16; private static final int MSG_SET_A2DP_CONNECTION_STATE = 17; private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 17; private static final int MSG_SET_A2DP_CONNECTION_STATE = 18; // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be Loading Loading @@ -397,6 +400,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private boolean mBluetoothA2dpEnabled; private final Object mBluetoothA2dpEnabledLock = new Object(); // Monitoring of audio routes. Protected by mCurAudioRoutes. final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo(); final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers = new RemoteCallbackList<IAudioRoutesObserver>(); /////////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////////// Loading Loading @@ -3011,6 +3019,26 @@ public class AudioService extends IAudioService.Stub implements OnFinished { onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1); mMediaEventWakeLock.release(); break; case MSG_REPORT_NEW_ROUTES: { int N = mRoutesObservers.beginBroadcast(); if (N > 0) { AudioRoutesInfo routes; synchronized (mCurAudioRoutes) { routes = new AudioRoutesInfo(mCurAudioRoutes); } while (N > 0) { N--; IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N); try { obs.dispatchAudioRoutesChanged(routes); } catch (RemoteException e) { } } } mRoutesObservers.finishBroadcast(); break; } } } } Loading Loading @@ -3127,6 +3155,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } else { makeA2dpDeviceUnavailableNow(address); } synchronized (mCurAudioRoutes) { if (mCurAudioRoutes.mBluetoothName != null) { mCurAudioRoutes.mBluetoothName = null; sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP, 0, 0, null, 0); } } } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) { if (btDevice.isBluetoothDock()) { // this could be a reconnection after a transient disconnection Loading @@ -3141,6 +3176,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { } } makeA2dpDeviceAvailable(address); synchronized (mCurAudioRoutes) { String name = btDevice.getAliasName(); if (!TextUtils.equals(mCurAudioRoutes.mBluetoothName, name)) { mCurAudioRoutes.mBluetoothName = name; sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP, 0, 0, null, 0); } } } } } Loading Loading @@ -3204,20 +3247,43 @@ public class AudioService extends IAudioService.Stub implements OnFinished { intent.putExtra("name", name); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); int connType = 0; if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) { connType = AudioRoutesInfo.MAIN_HEADSET; intent.setAction(Intent.ACTION_HEADSET_PLUG); intent.putExtra("microphone", 1); } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) { connType = AudioRoutesInfo.MAIN_HEADPHONES; intent.setAction(Intent.ACTION_HEADSET_PLUG); intent.putExtra("microphone", 0); } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) { connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS; intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG); } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) { connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS; intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG); } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) { connType = AudioRoutesInfo.MAIN_HDMI; intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG); } synchronized (mCurAudioRoutes) { if (connType != 0) { int newConn = mCurAudioRoutes.mMainType; if (state != 0) { newConn |= connType; } else { newConn &= ~connType; } if (newConn != mCurAudioRoutes.mMainType) { mCurAudioRoutes.mMainType = newConn; sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES, SENDMSG_NOOP, 0, 0, null, 0); } } } ActivityManagerNative.broadcastStickyIntent(intent, null); } Loading Loading @@ -4795,6 +4861,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished { return mRingtonePlayer; } @Override public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) { synchronized (mCurAudioRoutes) { AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes); mRoutesObservers.register(observer); return routes; } } @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); Loading @@ -4803,5 +4878,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished { dumpFocusStack(pw); dumpRCStack(pw); dumpStreamStates(pw); pw.println("\nAudio routes:"); pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType)); pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName); } }
media/java/android/media/IAudioRoutesObserver.aidl 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 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.media; import android.media.AudioRoutesInfo; /** * AIDL for the AudioService to report changes in available audio routes. * @hide */ oneway interface IAudioRoutesObserver { void dispatchAudioRoutesChanged(in AudioRoutesInfo newRoutes); }