Skip to content

Commit 87959cd

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Add new callback for MediaRouter to found out about device changes." into jb-dev
2 parents c4f4b0f + 632ca41 commit 87959cd

File tree

7 files changed

+268
-83
lines changed

7 files changed

+268
-83
lines changed

Android.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ LOCAL_SRC_FILES += \
193193
location/java/android/location/INetInitiatedListener.aidl \
194194
media/java/android/media/IAudioService.aidl \
195195
media/java/android/media/IAudioFocusDispatcher.aidl \
196+
media/java/android/media/IAudioRoutesObserver.aidl \
196197
media/java/android/media/IMediaScannerListener.aidl \
197198
media/java/android/media/IMediaScannerService.aidl \
198199
media/java/android/media/IRemoteControlClient.aidl \
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* Copyright 2012, The Android Open Source Project
2+
**
3+
** Licensed under the Apache License, Version 2.0 (the "License");
4+
** you may not use this file except in compliance with the License.
5+
** You may obtain a copy of the License at
6+
**
7+
** http://www.apache.org/licenses/LICENSE-2.0
8+
**
9+
** Unless required by applicable law or agreed to in writing, software
10+
** distributed under the License is distributed on an "AS IS" BASIS,
11+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
** See the License for the specific language governing permissions and
13+
** limitations under the License.
14+
*/
15+
16+
package android.media;
17+
18+
parcelable AudioRoutesInfo;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package android.media;
18+
19+
import android.os.Parcel;
20+
import android.os.Parcelable;
21+
import android.text.TextUtils;
22+
23+
/**
24+
* Information available from AudioService about the current routes.
25+
* @hide
26+
*/
27+
public class AudioRoutesInfo implements Parcelable {
28+
static final int MAIN_SPEAKER = 0;
29+
static final int MAIN_HEADSET = 1<<0;
30+
static final int MAIN_HEADPHONES = 1<<1;
31+
static final int MAIN_DOCK_SPEAKERS = 1<<2;
32+
static final int MAIN_HDMI = 1<<3;
33+
34+
CharSequence mBluetoothName;
35+
int mMainType = MAIN_SPEAKER;
36+
37+
public AudioRoutesInfo() {
38+
}
39+
40+
public AudioRoutesInfo(AudioRoutesInfo o) {
41+
mBluetoothName = o.mBluetoothName;
42+
mMainType = o.mMainType;
43+
}
44+
45+
AudioRoutesInfo(Parcel src) {
46+
mBluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
47+
mMainType = src.readInt();
48+
}
49+
50+
@Override
51+
public int describeContents() {
52+
return 0;
53+
}
54+
55+
@Override
56+
public void writeToParcel(Parcel dest, int flags) {
57+
TextUtils.writeToParcel(mBluetoothName, dest, flags);
58+
dest.writeInt(mMainType);
59+
}
60+
61+
public static final Parcelable.Creator<AudioRoutesInfo> CREATOR
62+
= new Parcelable.Creator<AudioRoutesInfo>() {
63+
public AudioRoutesInfo createFromParcel(Parcel in) {
64+
return new AudioRoutesInfo(in);
65+
}
66+
67+
public AudioRoutesInfo[] newArray(int size) {
68+
return new AudioRoutesInfo[size];
69+
}
70+
};
71+
}

media/java/android/media/AudioService.java

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import android.os.Looper;
5454
import android.os.Message;
5555
import android.os.PowerManager;
56+
import android.os.RemoteCallbackList;
5657
import android.os.RemoteException;
5758
import android.os.ServiceManager;
5859
import android.os.SystemProperties;
@@ -62,6 +63,7 @@
6263
import android.speech.RecognizerIntent;
6364
import android.telephony.PhoneStateListener;
6465
import android.telephony.TelephonyManager;
66+
import android.text.TextUtils;
6567
import android.util.Log;
6668
import android.view.KeyEvent;
6769
import android.view.VolumePanel;
@@ -135,10 +137,11 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
135137
private static final int MSG_RCDISPLAY_UPDATE = 13;
136138
private static final int MSG_SET_ALL_VOLUMES = 14;
137139
private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
140+
private static final int MSG_REPORT_NEW_ROUTES = 16;
138141
// messages handled under wakelock, can only be queued, i.e. sent with queueMsgUnderWakeLock(),
139142
// and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
140-
private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
141-
private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
143+
private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 17;
144+
private static final int MSG_SET_A2DP_CONNECTION_STATE = 18;
142145

143146

144147
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -397,6 +400,11 @@ public void onError(int error) {
397400
private boolean mBluetoothA2dpEnabled;
398401
private final Object mBluetoothA2dpEnabledLock = new Object();
399402

403+
// Monitoring of audio routes. Protected by mCurAudioRoutes.
404+
final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
405+
final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers
406+
= new RemoteCallbackList<IAudioRoutesObserver>();
407+
400408
///////////////////////////////////////////////////////////////////////////
401409
// Construction
402410
///////////////////////////////////////////////////////////////////////////
@@ -3011,6 +3019,26 @@ public void handleMessage(Message msg) {
30113019
onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
30123020
mMediaEventWakeLock.release();
30133021
break;
3022+
3023+
case MSG_REPORT_NEW_ROUTES: {
3024+
int N = mRoutesObservers.beginBroadcast();
3025+
if (N > 0) {
3026+
AudioRoutesInfo routes;
3027+
synchronized (mCurAudioRoutes) {
3028+
routes = new AudioRoutesInfo(mCurAudioRoutes);
3029+
}
3030+
while (N > 0) {
3031+
N--;
3032+
IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N);
3033+
try {
3034+
obs.dispatchAudioRoutesChanged(routes);
3035+
} catch (RemoteException e) {
3036+
}
3037+
}
3038+
}
3039+
mRoutesObservers.finishBroadcast();
3040+
break;
3041+
}
30143042
}
30153043
}
30163044
}
@@ -3127,6 +3155,13 @@ private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
31273155
} else {
31283156
makeA2dpDeviceUnavailableNow(address);
31293157
}
3158+
synchronized (mCurAudioRoutes) {
3159+
if (mCurAudioRoutes.mBluetoothName != null) {
3160+
mCurAudioRoutes.mBluetoothName = null;
3161+
sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
3162+
SENDMSG_NOOP, 0, 0, null, 0);
3163+
}
3164+
}
31303165
} else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
31313166
if (btDevice.isBluetoothDock()) {
31323167
// this could be a reconnection after a transient disconnection
@@ -3141,6 +3176,14 @@ private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
31413176
}
31423177
}
31433178
makeA2dpDeviceAvailable(address);
3179+
synchronized (mCurAudioRoutes) {
3180+
String name = btDevice.getAliasName();
3181+
if (!TextUtils.equals(mCurAudioRoutes.mBluetoothName, name)) {
3182+
mCurAudioRoutes.mBluetoothName = name;
3183+
sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
3184+
SENDMSG_NOOP, 0, 0, null, 0);
3185+
}
3186+
}
31443187
}
31453188
}
31463189
}
@@ -3204,20 +3247,43 @@ private void sendDeviceConnectionIntent(int device, int state, String name)
32043247
intent.putExtra("name", name);
32053248
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
32063249

3250+
int connType = 0;
3251+
32073252
if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
3253+
connType = AudioRoutesInfo.MAIN_HEADSET;
32083254
intent.setAction(Intent.ACTION_HEADSET_PLUG);
32093255
intent.putExtra("microphone", 1);
32103256
} else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
3257+
connType = AudioRoutesInfo.MAIN_HEADPHONES;
32113258
intent.setAction(Intent.ACTION_HEADSET_PLUG);
32123259
intent.putExtra("microphone", 0);
32133260
} else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
3261+
connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
32143262
intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
32153263
} else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
3264+
connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
32163265
intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
32173266
} else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
3267+
connType = AudioRoutesInfo.MAIN_HDMI;
32183268
intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
32193269
}
32203270

3271+
synchronized (mCurAudioRoutes) {
3272+
if (connType != 0) {
3273+
int newConn = mCurAudioRoutes.mMainType;
3274+
if (state != 0) {
3275+
newConn |= connType;
3276+
} else {
3277+
newConn &= ~connType;
3278+
}
3279+
if (newConn != mCurAudioRoutes.mMainType) {
3280+
mCurAudioRoutes.mMainType = newConn;
3281+
sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
3282+
SENDMSG_NOOP, 0, 0, null, 0);
3283+
}
3284+
}
3285+
}
3286+
32213287
ActivityManagerNative.broadcastStickyIntent(intent, null);
32223288
}
32233289

@@ -4795,6 +4861,15 @@ public IRingtonePlayer getRingtonePlayer() {
47954861
return mRingtonePlayer;
47964862
}
47974863

4864+
@Override
4865+
public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
4866+
synchronized (mCurAudioRoutes) {
4867+
AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes);
4868+
mRoutesObservers.register(observer);
4869+
return routes;
4870+
}
4871+
}
4872+
47984873
@Override
47994874
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
48004875
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
@@ -4803,5 +4878,8 @@ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
48034878
dumpFocusStack(pw);
48044879
dumpRCStack(pw);
48054880
dumpStreamStates(pw);
4881+
pw.println("\nAudio routes:");
4882+
pw.print(" mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
4883+
pw.print(" mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);
48064884
}
48074885
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (C) 2012 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package android.media;
18+
19+
import android.media.AudioRoutesInfo;
20+
21+
/**
22+
* AIDL for the AudioService to report changes in available audio routes.
23+
* @hide
24+
*/
25+
oneway interface IAudioRoutesObserver {
26+
void dispatchAudioRoutesChanged(in AudioRoutesInfo newRoutes);
27+
}

media/java/android/media/IAudioService.aidl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ package android.media;
1919
import android.app.PendingIntent;
2020
import android.bluetooth.BluetoothDevice;
2121
import android.content.ComponentName;
22+
import android.media.AudioRoutesInfo;
2223
import android.media.IAudioFocusDispatcher;
24+
import android.media.IAudioRoutesObserver;
2325
import android.media.IRemoteControlClient;
2426
import android.media.IRemoteControlDisplay;
2527
import android.media.IRingtonePlayer;
@@ -137,4 +139,6 @@ interface IAudioService {
137139

138140
void setWiredDeviceConnectionState(int device, int state, String name);
139141
int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
142+
143+
AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
140144
}

0 commit comments

Comments
 (0)