Merge "Add a mechanism for configuring the A2DP Source codecs" am: 63270f2b96 am: 8b46f87e7e am: da3de76bdb
am: 62c5226e9c
Change-Id: I14d4cc2dc91cb1ab431eda32d5066ac8f471c3a6
This commit is contained in:
@@ -632,6 +632,7 @@ android.bluetooth.BluetoothAdapter$LeScanCallback
|
||||
android.bluetooth.BluetoothAudioConfig
|
||||
android.bluetooth.BluetoothClass
|
||||
android.bluetooth.BluetoothClass$1
|
||||
android.bluetooth.BluetoothCodecConfig
|
||||
android.bluetooth.BluetoothDevice
|
||||
android.bluetooth.BluetoothDevice$1
|
||||
android.bluetooth.BluetoothDevice$2
|
||||
|
||||
@@ -102,6 +102,27 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
||||
public static final String ACTION_AVRCP_CONNECTION_STATE_CHANGED =
|
||||
"android.bluetooth.a2dp.profile.action.AVRCP_CONNECTION_STATE_CHANGED";
|
||||
|
||||
/**
|
||||
* Intent used to broadcast the change in the Audio Codec state of the
|
||||
* A2DP Source profile.
|
||||
*
|
||||
* <p>This intent will have 3 extras:
|
||||
* <ul>
|
||||
* <li> {@link #EXTRA_CODEC_CONFIG} - The current codec configuration. </li>
|
||||
* <li> {@link #EXTRA_PREVIOUS_CODEC_CONFIG} - The previous codec configuration. </li>
|
||||
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device if the device is currently
|
||||
* connected, otherwise it is not included.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
|
||||
* receive.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_CODEC_CONFIG_CHANGED =
|
||||
"android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
|
||||
|
||||
/**
|
||||
* A2DP sink device is streaming music. This state can be one of
|
||||
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
|
||||
@@ -543,6 +564,54 @@ public final class BluetoothA2dp implements BluetoothProfile {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current codec configuration.
|
||||
*
|
||||
* @return the current codec configuration
|
||||
* @hide
|
||||
*/
|
||||
public BluetoothCodecConfig getCodecConfig() {
|
||||
if (DBG) Log.d(TAG, "getCodecConfig");
|
||||
try {
|
||||
mServiceLock.readLock().lock();
|
||||
if (mService != null && isEnabled()) {
|
||||
return mService.getCodecConfig();
|
||||
}
|
||||
if (mService == null) {
|
||||
Log.w(TAG, "Proxy not attached to service");
|
||||
}
|
||||
return null;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error talking to BT service in getCodecConfig()", e);
|
||||
return null;
|
||||
} finally {
|
||||
mServiceLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the codec configuration preference.
|
||||
*
|
||||
* @param codecConfig the codec configuration preference
|
||||
* @hide
|
||||
*/
|
||||
public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) {
|
||||
if (DBG) Log.d(TAG, "setCodecConfigPreference");
|
||||
try {
|
||||
mServiceLock.readLock().lock();
|
||||
if (mService != null && isEnabled()) {
|
||||
mService.setCodecConfigPreference(codecConfig);
|
||||
}
|
||||
if (mService == null) Log.w(TAG, "Proxy not attached to service");
|
||||
return;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error talking to BT service in setCodecConfigPreference()", e);
|
||||
return;
|
||||
} finally {
|
||||
mServiceLock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for converting a state to a string.
|
||||
*
|
||||
|
||||
19
core/java/android/bluetooth/BluetoothCodecConfig.aidl
Normal file
19
core/java/android/bluetooth/BluetoothCodecConfig.aidl
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.bluetooth;
|
||||
|
||||
parcelable BluetoothCodecConfig;
|
||||
287
core/java/android/bluetooth/BluetoothCodecConfig.java
Normal file
287
core/java/android/bluetooth/BluetoothCodecConfig.java
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.bluetooth;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents the codec configuration for a Bluetooth A2DP source device.
|
||||
*
|
||||
* {@see BluetoothA2dp}
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public final class BluetoothCodecConfig implements Parcelable {
|
||||
|
||||
/**
|
||||
* Extra for the codec configuration intents of the individual profiles.
|
||||
*
|
||||
* This extra represents the current codec configuration of the A2DP
|
||||
* profile.
|
||||
*/
|
||||
public static final String EXTRA_CODEC_CONFIG = "android.bluetooth.codec.extra.CODEC_CONFIG";
|
||||
|
||||
/**
|
||||
* Extra for the codec configuration intents of the individual profiles.
|
||||
*
|
||||
* This extra represents the previous codec configuration of the A2DP
|
||||
* profile.
|
||||
*/
|
||||
public static final String EXTRA_PREVIOUS_CODEC_CONFIG =
|
||||
"android.bluetooth.codec.extra.PREVIOUS_CODEC_CONFIG";
|
||||
|
||||
public static final int SOURCE_CODEC_TYPE_SBC = 0;
|
||||
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
|
||||
|
||||
public static final int CODEC_PRIORITY_DEFAULT = 0;
|
||||
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
|
||||
|
||||
public static final int SAMPLE_RATE_NONE = 0;
|
||||
public static final int SAMPLE_RATE_44100 = 0x1 << 0;
|
||||
public static final int SAMPLE_RATE_48000 = 0x1 << 1;
|
||||
public static final int SAMPLE_RATE_88200 = 0x1 << 2;
|
||||
public static final int SAMPLE_RATE_96000 = 0x1 << 3;
|
||||
public static final int SAMPLE_RATE_176400 = 0x1 << 4;
|
||||
public static final int SAMPLE_RATE_192000 = 0x1 << 5;
|
||||
|
||||
public static final int BITS_PER_SAMPLE_NONE = 0;
|
||||
public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
|
||||
public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
|
||||
public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
|
||||
|
||||
public static final int CHANNEL_MODE_NONE = 0;
|
||||
public static final int CHANNEL_MODE_MONO = 0x1 << 0;
|
||||
public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
|
||||
|
||||
private final int mCodecType;
|
||||
private final int mCodecPriority;
|
||||
private final int mSampleRate;
|
||||
private final int mBitsPerSample;
|
||||
private final int mChannelMode;
|
||||
private final long mCodecSpecific1;
|
||||
private final long mCodecSpecific2;
|
||||
private final long mCodecSpecific3;
|
||||
private final long mCodecSpecific4;
|
||||
|
||||
public BluetoothCodecConfig(int codecType, int codecPriority,
|
||||
int sampleRate, int bitsPerSample,
|
||||
int channelMode,long codecSpecific1,
|
||||
long codecSpecific2, long codecSpecific3,
|
||||
long codecSpecific4) {
|
||||
mCodecType = codecType;
|
||||
mCodecPriority = codecPriority;
|
||||
mSampleRate = sampleRate;
|
||||
mBitsPerSample = bitsPerSample;
|
||||
mChannelMode = channelMode;
|
||||
mCodecSpecific1 = codecSpecific1;
|
||||
mCodecSpecific2 = codecSpecific2;
|
||||
mCodecSpecific3 = codecSpecific3;
|
||||
mCodecSpecific4 = codecSpecific4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof BluetoothCodecConfig) {
|
||||
BluetoothCodecConfig other = (BluetoothCodecConfig)o;
|
||||
return (other.mCodecType == mCodecType &&
|
||||
other.mCodecPriority == mCodecPriority &&
|
||||
other.mSampleRate == mSampleRate &&
|
||||
other.mBitsPerSample == mBitsPerSample &&
|
||||
other.mChannelMode == mChannelMode &&
|
||||
other.mCodecSpecific1 == mCodecSpecific1 &&
|
||||
other.mCodecSpecific2 == mCodecSpecific2 &&
|
||||
other.mCodecSpecific3 == mCodecSpecific3 &&
|
||||
other.mCodecSpecific4 == mCodecSpecific4);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
|
||||
mBitsPerSample, mChannelMode, mCodecSpecific1,
|
||||
mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{mCodecType:" + mCodecType +
|
||||
",mCodecPriority:" + mCodecPriority +
|
||||
",mSampleRate:" + String.format("0x%x", mSampleRate) +
|
||||
",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) +
|
||||
",mChannelMode:" + String.format("0x%x", mChannelMode) +
|
||||
",mCodecSpecific1:" + mCodecSpecific1 +
|
||||
",mCodecSpecific2:" + mCodecSpecific2 +
|
||||
",mCodecSpecific3:" + mCodecSpecific3 +
|
||||
",mCodecSpecific4:" + mCodecSpecific4 + "}";
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<BluetoothCodecConfig> CREATOR =
|
||||
new Parcelable.Creator<BluetoothCodecConfig>() {
|
||||
public BluetoothCodecConfig createFromParcel(Parcel in) {
|
||||
final int codecType = in.readInt();
|
||||
final int codecPriority = in.readInt();
|
||||
final int sampleRate = in.readInt();
|
||||
final int bitsPerSample = in.readInt();
|
||||
final int channelMode = in.readInt();
|
||||
final long codecSpecific1 = in.readLong();
|
||||
final long codecSpecific2 = in.readLong();
|
||||
final long codecSpecific3 = in.readLong();
|
||||
final long codecSpecific4 = in.readLong();
|
||||
return new BluetoothCodecConfig(codecType, codecPriority,
|
||||
sampleRate, bitsPerSample,
|
||||
channelMode, codecSpecific1,
|
||||
codecSpecific2, codecSpecific3,
|
||||
codecSpecific4);
|
||||
}
|
||||
public BluetoothCodecConfig[] newArray(int size) {
|
||||
return new BluetoothCodecConfig[size];
|
||||
}
|
||||
};
|
||||
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mCodecType);
|
||||
out.writeInt(mCodecPriority);
|
||||
out.writeInt(mSampleRate);
|
||||
out.writeInt(mBitsPerSample);
|
||||
out.writeInt(mChannelMode);
|
||||
out.writeLong(mCodecSpecific1);
|
||||
out.writeLong(mCodecSpecific2);
|
||||
out.writeLong(mCodecSpecific3);
|
||||
out.writeLong(mCodecSpecific4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codec type.
|
||||
* See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}.
|
||||
*
|
||||
* @return the codec type
|
||||
*/
|
||||
public int getCodecType() {
|
||||
return mCodecType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codec selection priority.
|
||||
* The codec selection priority is relative to other codecs: larger value
|
||||
* means higher priority. If 0, reset to default.
|
||||
*
|
||||
* @return the codec priority
|
||||
*/
|
||||
public int getCodecPriority() {
|
||||
return mCodecPriority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codec sample rate. The value can be a bitmask with all
|
||||
* supported sample rates:
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_48000} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_88200} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_96000} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_176400} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_192000}
|
||||
*
|
||||
* @return the codec sample rate
|
||||
*/
|
||||
public int getSampleRate() {
|
||||
return mSampleRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codec bits per sample. The value can be a bitmask with all
|
||||
* bits per sample supported:
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_24} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_32}
|
||||
*
|
||||
* @return the codec bits per sample
|
||||
*/
|
||||
public int getBitsPerSample() {
|
||||
return mBitsPerSample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the codec channel mode. The value can be a bitmask with all
|
||||
* supported channel modes:
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
|
||||
* {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO}
|
||||
*
|
||||
* @return the codec channel mode
|
||||
*/
|
||||
public int getChannelMode() {
|
||||
return mChannelMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a codec specific value1.
|
||||
*
|
||||
* @return a codec specific value1.
|
||||
*/
|
||||
public long getCodecSpecific1() {
|
||||
return mCodecSpecific1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a codec specific value2.
|
||||
*
|
||||
* @return a codec specific value2
|
||||
*/
|
||||
public long getCodecSpecific2() {
|
||||
return mCodecSpecific2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a codec specific value3.
|
||||
*
|
||||
* @return a codec specific value3
|
||||
*/
|
||||
public long getCodecSpecific3() {
|
||||
return mCodecSpecific3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a codec specific value4.
|
||||
*
|
||||
* @return a codec specific value4
|
||||
*/
|
||||
public long getCodecSpecific4() {
|
||||
return mCodecSpecific4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the audio feeding parameters are same.
|
||||
*
|
||||
* @param other the codec config to compare against
|
||||
* @return true if the audio feeding parameters are same, otherwise false
|
||||
*/
|
||||
public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
|
||||
return (other != null && other.mSampleRate == mSampleRate &&
|
||||
other.mBitsPerSample == mBitsPerSample &&
|
||||
other.mChannelMode == mChannelMode);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package android.bluetooth;
|
||||
|
||||
import android.bluetooth.BluetoothCodecConfig;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
@@ -36,4 +37,6 @@ interface IBluetoothA2dp {
|
||||
oneway void adjustAvrcpAbsoluteVolume(int direction);
|
||||
oneway void setAvrcpAbsoluteVolume(int volume);
|
||||
boolean isA2dpPlaying(in BluetoothDevice device);
|
||||
BluetoothCodecConfig getCodecConfig();
|
||||
oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig);
|
||||
}
|
||||
|
||||
@@ -462,6 +462,18 @@ android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, ji
|
||||
return (jint) state;
|
||||
}
|
||||
|
||||
static jint
|
||||
android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name)
|
||||
{
|
||||
const char *c_address = env->GetStringUTFChars(device_address, NULL);
|
||||
const char *c_name = env->GetStringUTFChars(device_name, NULL);
|
||||
int status = check_AudioSystem_Command(AudioSystem::handleDeviceConfigChange(static_cast <audio_devices_t>(device),
|
||||
c_address, c_name));
|
||||
env->ReleaseStringUTFChars(device_address, c_address);
|
||||
env->ReleaseStringUTFChars(device_name, c_name);
|
||||
return (jint) status;
|
||||
}
|
||||
|
||||
static jint
|
||||
android_media_AudioSystem_setPhoneState(JNIEnv *env, jobject thiz, jint state)
|
||||
{
|
||||
@@ -1764,6 +1776,7 @@ static const JNINativeMethod gMethods[] = {
|
||||
{"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
|
||||
{"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
|
||||
{"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
|
||||
{"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
|
||||
{"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
|
||||
{"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
|
||||
{"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
|
||||
|
||||
@@ -167,6 +167,8 @@
|
||||
android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
|
||||
<protected-broadcast
|
||||
android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
|
||||
<protected-broadcast
|
||||
android:name="android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED" />
|
||||
<protected-broadcast
|
||||
android:name="android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED" />
|
||||
<protected-broadcast
|
||||
|
||||
@@ -3482,6 +3482,20 @@ public class AudioManager {
|
||||
return delay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate A2DP device configuration has changed.
|
||||
* @param device Bluetooth device whose configuration has changed.
|
||||
* {@hide}
|
||||
*/
|
||||
public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device) {
|
||||
IAudioService service = getService();
|
||||
try {
|
||||
service.handleBluetoothA2dpDeviceConfigChange(device);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public IRingtonePlayer getRingtonePlayer() {
|
||||
try {
|
||||
|
||||
@@ -689,6 +689,9 @@ public class AudioSystem
|
||||
public static native int setDeviceConnectionState(int device, int state,
|
||||
String device_address, String device_name);
|
||||
public static native int getDeviceConnectionState(int device, String device_address);
|
||||
public static native int handleDeviceConfigChange(int device,
|
||||
String device_address,
|
||||
String device_name);
|
||||
public static native int setPhoneState(int state);
|
||||
public static native int setForceUse(int usage, int config);
|
||||
public static native int getForceUse(int usage);
|
||||
|
||||
@@ -143,6 +143,8 @@ interface IAudioService {
|
||||
|
||||
int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state, int profile);
|
||||
|
||||
void handleBluetoothA2dpDeviceConfigChange(in BluetoothDevice device);
|
||||
|
||||
AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
|
||||
|
||||
boolean isCameraSoundForced();
|
||||
|
||||
@@ -232,6 +232,7 @@ public class AudioService extends IAudioService.Stub
|
||||
private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 100;
|
||||
private static final int MSG_SET_A2DP_SRC_CONNECTION_STATE = 101;
|
||||
private static final int MSG_SET_A2DP_SINK_CONNECTION_STATE = 102;
|
||||
private static final int MSG_A2DP_DEVICE_CONFIG_CHANGE = 103;
|
||||
// end of messages handled under wakelock
|
||||
|
||||
private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
|
||||
@@ -3183,7 +3184,7 @@ public class AudioService extends IAudioService.Stub
|
||||
queueMsgUnderWakeLock(mAudioHandler,
|
||||
MSG_SET_A2DP_SINK_CONNECTION_STATE,
|
||||
state,
|
||||
0,
|
||||
0 /* arg2 unused */,
|
||||
btDevice,
|
||||
delay);
|
||||
}
|
||||
@@ -3200,7 +3201,7 @@ public class AudioService extends IAudioService.Stub
|
||||
queueMsgUnderWakeLock(mAudioHandler,
|
||||
MSG_SET_A2DP_SRC_CONNECTION_STATE,
|
||||
state,
|
||||
0,
|
||||
0 /* arg2 unused */,
|
||||
btDevice,
|
||||
0 /* delay */);
|
||||
}
|
||||
@@ -3848,8 +3849,8 @@ public class AudioService extends IAudioService.Stub
|
||||
int delay = checkSendBecomingNoisyIntent(type, state);
|
||||
queueMsgUnderWakeLock(mAudioHandler,
|
||||
MSG_SET_WIRED_DEVICE_CONNECTION_STATE,
|
||||
0,
|
||||
0,
|
||||
0 /* arg1 unused */,
|
||||
0 /* arg2 unused */,
|
||||
new WiredDeviceConnectionState(type, state, address, name, caller),
|
||||
delay);
|
||||
}
|
||||
@@ -3872,13 +3873,25 @@ public class AudioService extends IAudioService.Stub
|
||||
(profile == BluetoothProfile.A2DP ?
|
||||
MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
|
||||
state,
|
||||
0,
|
||||
0 /* arg2 unused */,
|
||||
device,
|
||||
delay);
|
||||
}
|
||||
return delay;
|
||||
}
|
||||
|
||||
public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)
|
||||
{
|
||||
synchronized (mConnectedDevices) {
|
||||
queueMsgUnderWakeLock(mAudioHandler,
|
||||
MSG_A2DP_DEVICE_CONFIG_CHANGE,
|
||||
0 /* arg1 unused */,
|
||||
0 /* arg1 unused */,
|
||||
device,
|
||||
0 /* delay */);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Inner classes
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -4691,6 +4704,11 @@ public class AudioService extends IAudioService.Stub
|
||||
mAudioEventWakeLock.release();
|
||||
break;
|
||||
|
||||
case MSG_A2DP_DEVICE_CONFIG_CHANGE:
|
||||
onBluetoothA2dpDeviceConfigChange((BluetoothDevice)msg.obj);
|
||||
mAudioEventWakeLock.release();
|
||||
break;
|
||||
|
||||
case MSG_REPORT_NEW_ROUTES: {
|
||||
int N = mRoutesObservers.beginBroadcast();
|
||||
if (N > 0) {
|
||||
@@ -4913,7 +4931,7 @@ public class AudioService extends IAudioService.Stub
|
||||
private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state)
|
||||
{
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "onSetA2dpSinkConnectionState btDevice="+btDevice+"state="+state);
|
||||
Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice+"state=" + state);
|
||||
}
|
||||
if (btDevice == null) {
|
||||
return;
|
||||
@@ -4924,9 +4942,9 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
synchronized (mConnectedDevices) {
|
||||
String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
|
||||
btDevice.getAddress());
|
||||
DeviceListSpec deviceSpec = mConnectedDevices.get(key);
|
||||
final String key = makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
|
||||
btDevice.getAddress());
|
||||
final DeviceListSpec deviceSpec = mConnectedDevices.get(key);
|
||||
boolean isConnected = deviceSpec != null;
|
||||
|
||||
if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
|
||||
@@ -4977,7 +4995,7 @@ public class AudioService extends IAudioService.Stub
|
||||
private void onSetA2dpSourceConnectionState(BluetoothDevice btDevice, int state)
|
||||
{
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "onSetA2dpSourceConnectionState btDevice="+btDevice+" state="+state);
|
||||
Log.d(TAG, "onSetA2dpSourceConnectionState btDevice=" + btDevice + " state=" + state);
|
||||
}
|
||||
if (btDevice == null) {
|
||||
return;
|
||||
@@ -4988,8 +5006,8 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
synchronized (mConnectedDevices) {
|
||||
String key = makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address);
|
||||
DeviceListSpec deviceSpec = mConnectedDevices.get(key);
|
||||
final String key = makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address);
|
||||
final DeviceListSpec deviceSpec = mConnectedDevices.get(key);
|
||||
boolean isConnected = deviceSpec != null;
|
||||
|
||||
if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
|
||||
@@ -5000,6 +5018,31 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void onBluetoothA2dpDeviceConfigChange(BluetoothDevice btDevice)
|
||||
{
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "onBluetoothA2dpDeviceConfigChange btDevice=" + btDevice);
|
||||
}
|
||||
if (btDevice == null) {
|
||||
return;
|
||||
}
|
||||
String address = btDevice.getAddress();
|
||||
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
|
||||
address = "";
|
||||
}
|
||||
|
||||
int device = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
|
||||
synchronized (mConnectedDevices) {
|
||||
final String key = makeDeviceListKey(device, address);
|
||||
final DeviceListSpec deviceSpec = mConnectedDevices.get(key);
|
||||
if (deviceSpec != null) {
|
||||
// Device is connected
|
||||
AudioSystem.handleDeviceConfigChange(device, address,
|
||||
btDevice.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
|
||||
// address is not used for now, but may be used when multiple a2dp devices are supported
|
||||
synchronized (mA2dpAvrcpLock) {
|
||||
|
||||
Reference in New Issue
Block a user