Merge changes from topic "comm_routing" am: 8553f77dce
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1534433 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I35def97c4eda8d484e42addde6b43377d748f578
This commit is contained in:
@@ -294,20 +294,25 @@ static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env,
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define check_AudioSystem_Command(status) _check_AudioSystem_Command(__func__, (status))
|
#define check_AudioSystem_Command(...) _check_AudioSystem_Command(__func__, __VA_ARGS__)
|
||||||
|
|
||||||
static int _check_AudioSystem_Command(const char* caller, status_t status)
|
static int _check_AudioSystem_Command(const char *caller, status_t status,
|
||||||
{
|
std::vector<status_t> ignoredErrors = {}) {
|
||||||
ALOGE_IF(status, "Command failed for %s: %d", caller, status);
|
int jniStatus = kAudioStatusOk;
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case DEAD_OBJECT:
|
case DEAD_OBJECT:
|
||||||
return kAudioStatusMediaServerDied;
|
jniStatus = kAudioStatusMediaServerDied;
|
||||||
|
break;
|
||||||
case NO_ERROR:
|
case NO_ERROR:
|
||||||
return kAudioStatusOk;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (std::find(begin(ignoredErrors), end(ignoredErrors), status) == end(ignoredErrors)) {
|
||||||
|
jniStatus = kAudioStatusError;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return kAudioStatusError;
|
ALOGE_IF(jniStatus != kAudioStatusOk, "Command failed for %s: %d", caller, status);
|
||||||
|
return jniStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes,
|
static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes,
|
||||||
@@ -2381,9 +2386,12 @@ static jint android_media_AudioSystem_setDevicesRoleForStrategy(JNIEnv *env, job
|
|||||||
|
|
||||||
static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
|
static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz,
|
||||||
jint strategy, jint role) {
|
jint strategy, jint role) {
|
||||||
return (jint)check_AudioSystem_Command(
|
return (jint)
|
||||||
AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)strategy,
|
check_AudioSystem_Command(AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)
|
||||||
(device_role_t)role));
|
strategy,
|
||||||
|
(device_role_t)
|
||||||
|
role),
|
||||||
|
{NAME_NOT_FOUND});
|
||||||
}
|
}
|
||||||
|
|
||||||
static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz,
|
static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz,
|
||||||
|
|||||||
@@ -120,7 +120,13 @@ public final class AudioDeviceAttributes implements Parcelable {
|
|||||||
mAddress = address;
|
mAddress = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ AudioDeviceAttributes(int nativeType, @NonNull String address) {
|
/**
|
||||||
|
* @hide
|
||||||
|
* Constructor from internal device type and address
|
||||||
|
* @param type the internal device type, as defined in {@link AudioSystem}
|
||||||
|
* @param address the address of the device, or an empty string for devices without one
|
||||||
|
*/
|
||||||
|
public AudioDeviceAttributes(int nativeType, @NonNull String address) {
|
||||||
mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT;
|
mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT;
|
||||||
mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType);
|
mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType);
|
||||||
mAddress = address;
|
mAddress = address;
|
||||||
@@ -191,10 +197,8 @@ public final class AudioDeviceAttributes implements Parcelable {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return new String("AudioDeviceAttributes:"
|
return new String("AudioDeviceAttributes:"
|
||||||
+ " role:" + roleToString(mRole)
|
+ " role:" + roleToString(mRole)
|
||||||
+ " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(
|
+ " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(mNativeType)
|
||||||
AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType))
|
: AudioSystem.getInputDeviceName(mNativeType))
|
||||||
: AudioSystem.getInputDeviceName(
|
|
||||||
AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType)))
|
|
||||||
+ " addr:" + mAddress);
|
+ " addr:" + mAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1712,7 +1712,7 @@ public class AudioSystem
|
|||||||
int[] types = new int[devices.size()];
|
int[] types = new int[devices.size()];
|
||||||
String[] addresses = new String[devices.size()];
|
String[] addresses = new String[devices.size()];
|
||||||
for (int i = 0; i < devices.size(); ++i) {
|
for (int i = 0; i < devices.size(); ++i) {
|
||||||
types[i] = AudioDeviceInfo.convertDeviceTypeToInternalDevice(devices.get(i).getType());
|
types[i] = devices.get(i).getInternalType();
|
||||||
addresses[i] = devices.get(i).getAddress();
|
addresses[i] = devices.get(i).getAddress();
|
||||||
}
|
}
|
||||||
return setDevicesRoleForStrategy(strategy, role, types, addresses);
|
return setDevicesRoleForStrategy(strategy, role, types, addresses);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
package com.android.server.audio;
|
package com.android.server.audio;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.bluetooth.BluetoothA2dp;
|
import android.bluetooth.BluetoothA2dp;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothHeadset;
|
import android.bluetooth.BluetoothHeadset;
|
||||||
@@ -34,6 +35,7 @@ import android.media.ICapturePresetDevicesRoleDispatcher;
|
|||||||
import android.media.ICommunicationDeviceDispatcher;
|
import android.media.ICommunicationDeviceDispatcher;
|
||||||
import android.media.IStrategyPreferredDevicesDispatcher;
|
import android.media.IStrategyPreferredDevicesDispatcher;
|
||||||
import android.media.MediaMetrics;
|
import android.media.MediaMetrics;
|
||||||
|
import android.media.audiopolicy.AudioProductStrategy;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
@@ -51,6 +53,7 @@ import android.util.PrintWriterPrinter;
|
|||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -77,7 +80,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
private final @NonNull Context mContext;
|
private final @NonNull Context mContext;
|
||||||
|
|
||||||
/** Forced device usage for communications sent to AudioSystem */
|
/** Forced device usage for communications sent to AudioSystem */
|
||||||
private int mForcedUseForComm;
|
private AudioDeviceAttributes mPreferredDeviceforComm;
|
||||||
|
private int mCommunicationStrategyId = -1;
|
||||||
|
|
||||||
// Manages all connected devices, only ever accessed on the message loop
|
// Manages all connected devices, only ever accessed on the message loop
|
||||||
private final AudioDeviceInventory mDeviceInventory;
|
private final AudioDeviceInventory mDeviceInventory;
|
||||||
@@ -133,10 +137,23 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initCommunicationStrategyId() {
|
||||||
|
List<AudioProductStrategy> strategies = AudioProductStrategy.getAudioProductStrategies();
|
||||||
|
for (AudioProductStrategy strategy : strategies) {
|
||||||
|
if (strategy.getAudioAttributesForLegacyStreamType(AudioSystem.STREAM_VOICE_CALL)
|
||||||
|
!= null) {
|
||||||
|
mCommunicationStrategyId = strategy.getId();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mCommunicationStrategyId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
setupMessaging(mContext);
|
setupMessaging(mContext);
|
||||||
|
|
||||||
mForcedUseForComm = AudioSystem.FORCE_NONE;
|
mPreferredDeviceforComm = null;
|
||||||
|
initCommunicationStrategyId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ Context getContext() {
|
/*package*/ Context getContext() {
|
||||||
@@ -221,8 +238,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
synchronized (mDeviceStateLock) {
|
synchronized (mDeviceStateLock) {
|
||||||
AudioDeviceAttributes device = null;
|
AudioDeviceAttributes device = null;
|
||||||
if (on) {
|
if (on) {
|
||||||
device = new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT,
|
device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, "");
|
||||||
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, "");
|
|
||||||
} else {
|
} else {
|
||||||
CommunicationRouteClient client = getCommunicationRouteClientForPid(pid);
|
CommunicationRouteClient client = getCommunicationRouteClientForPid(pid);
|
||||||
if (client == null || !client.requestsSpeakerphone()) {
|
if (client == null || !client.requestsSpeakerphone()) {
|
||||||
@@ -275,6 +291,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
if (AudioService.DEBUG_COMM_RTE) {
|
if (AudioService.DEBUG_COMM_RTE) {
|
||||||
Log.v(TAG, "setCommunicationRouteForClient: device: " + device);
|
Log.v(TAG, "setCommunicationRouteForClient: device: " + device);
|
||||||
}
|
}
|
||||||
|
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
|
||||||
|
"setCommunicationRouteForClient for pid: " + pid
|
||||||
|
+ " device: " + device
|
||||||
|
+ " from API: " + eventSource)).printLog(TAG));
|
||||||
|
|
||||||
final boolean wasBtScoRequested = isBluetoothScoRequested();
|
final boolean wasBtScoRequested = isBluetoothScoRequested();
|
||||||
final boolean wasSpeakerphoneRequested = isSpeakerphoneRequested();
|
final boolean wasSpeakerphoneRequested = isSpeakerphoneRequested();
|
||||||
@@ -393,7 +413,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
* @return true if speakerphone is active, false otherwise.
|
* @return true if speakerphone is active, false otherwise.
|
||||||
*/
|
*/
|
||||||
/*package*/ boolean isSpeakerphoneOn() {
|
/*package*/ boolean isSpeakerphoneOn() {
|
||||||
return getForcedUseForComm() == AudioSystem.FORCE_SPEAKER;
|
AudioDeviceAttributes device = getPreferredDeviceForComm();
|
||||||
|
if (device == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return device.getInternalType() == AudioSystem.DEVICE_OUT_SPEAKER;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -560,7 +584,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
* @return true if Bluetooth SCO is active , false otherwise.
|
* @return true if Bluetooth SCO is active , false otherwise.
|
||||||
*/
|
*/
|
||||||
/*package*/ boolean isBluetoothScoOn() {
|
/*package*/ boolean isBluetoothScoOn() {
|
||||||
return getForcedUseForComm() == AudioSystem.FORCE_BT_SCO;
|
AudioDeviceAttributes device = getPreferredDeviceForComm();
|
||||||
|
if (device == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(device.getInternalType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
|
/*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
|
||||||
@@ -612,8 +640,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
|
|
||||||
synchronized (mSetModeLock) {
|
synchronized (mSetModeLock) {
|
||||||
synchronized (mDeviceStateLock) {
|
synchronized (mDeviceStateLock) {
|
||||||
AudioDeviceAttributes device = new AudioDeviceAttributes(
|
AudioDeviceAttributes device =
|
||||||
AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BLUETOOTH_SCO, "");
|
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, "");
|
||||||
setCommunicationRouteForClient(cb, pid, device, scoAudioMode, eventSource);
|
setCommunicationRouteForClient(cb, pid, device, scoAudioMode, eventSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -643,10 +671,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
return mDeviceInventory.setPreferredDevicesForStrategySync(strategy, devices);
|
return mDeviceInventory.setPreferredDevicesForStrategySync(strategy, devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*package*/ void postSetPreferredDevicesForStrategy(int strategy,
|
||||||
|
@NonNull List<AudioDeviceAttributes> devices) {
|
||||||
|
sendILMsgNoDelay(MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY, SENDMSG_REPLACE, strategy, devices);
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ int removePreferredDevicesForStrategySync(int strategy) {
|
/*package*/ int removePreferredDevicesForStrategySync(int strategy) {
|
||||||
return mDeviceInventory.removePreferredDevicesForStrategySync(strategy);
|
return mDeviceInventory.removePreferredDevicesForStrategySync(strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*package*/ void postRemovePreferredDevicesForStrategy(int strategy) {
|
||||||
|
sendIMsgNoDelay(MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_REPLACE, strategy);
|
||||||
|
}
|
||||||
|
|
||||||
/*package*/ void registerStrategyPreferredDevicesDispatcher(
|
/*package*/ void registerStrategyPreferredDevicesDispatcher(
|
||||||
@NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
|
@NonNull IStrategyPreferredDevicesDispatcher dispatcher) {
|
||||||
mDeviceInventory.registerStrategyPreferredDevicesDispatcher(dispatcher);
|
mDeviceInventory.registerStrategyPreferredDevicesDispatcher(dispatcher);
|
||||||
@@ -971,9 +1008,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
pw.println(" " + prefix + "pid: " + cl.getPid() + " device: "
|
pw.println(" " + prefix + "pid: " + cl.getPid() + " device: "
|
||||||
+ cl.getDevice() + " cb: " + cl.getBinder()); });
|
+ cl.getDevice() + " cb: " + cl.getBinder()); });
|
||||||
|
|
||||||
pw.println("\n" + prefix + "mForcedUseForComm: "
|
pw.println("\n" + prefix + "mPreferredDeviceforComm: "
|
||||||
+ AudioSystem.forceUseConfigToString(mForcedUseForComm));
|
+ mPreferredDeviceforComm);
|
||||||
pw.println(prefix + "mModeOwnerPid: " + mModeOwnerPid);
|
pw.println(prefix + "mCommunicationStrategyId: "
|
||||||
|
+ mCommunicationStrategyId);
|
||||||
|
|
||||||
|
pw.println("\n" + prefix + "mModeOwnerPid: " + mModeOwnerPid);
|
||||||
|
|
||||||
mBtHelper.dump(pw, prefix);
|
mBtHelper.dump(pw, prefix);
|
||||||
}
|
}
|
||||||
@@ -1068,6 +1108,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
case MSG_RESTORE_DEVICES:
|
case MSG_RESTORE_DEVICES:
|
||||||
synchronized (mSetModeLock) {
|
synchronized (mSetModeLock) {
|
||||||
synchronized (mDeviceStateLock) {
|
synchronized (mDeviceStateLock) {
|
||||||
|
initCommunicationStrategyId();
|
||||||
mDeviceInventory.onRestoreDevices();
|
mDeviceInventory.onRestoreDevices();
|
||||||
mBtHelper.onAudioServerDiedRestoreA2dp();
|
mBtHelper.onAudioServerDiedRestoreA2dp();
|
||||||
onUpdateCommunicationRoute("MSG_RESTORE_DEVICES");
|
onUpdateCommunicationRoute("MSG_RESTORE_DEVICES");
|
||||||
@@ -1277,6 +1318,17 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
final int strategy = msg.arg1;
|
final int strategy = msg.arg1;
|
||||||
mDeviceInventory.onSaveRemovePreferredDevices(strategy);
|
mDeviceInventory.onSaveRemovePreferredDevices(strategy);
|
||||||
} break;
|
} break;
|
||||||
|
case MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY: {
|
||||||
|
final int strategy = msg.arg1;
|
||||||
|
final List<AudioDeviceAttributes> devices =
|
||||||
|
(List<AudioDeviceAttributes>) msg.obj;
|
||||||
|
setPreferredDevicesForStrategySync(strategy, devices);
|
||||||
|
|
||||||
|
} break;
|
||||||
|
case MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY: {
|
||||||
|
final int strategy = msg.arg1;
|
||||||
|
removePreferredDevicesForStrategySync(strategy);
|
||||||
|
} break;
|
||||||
case MSG_CHECK_MUTE_MUSIC:
|
case MSG_CHECK_MUTE_MUSIC:
|
||||||
checkMessagesMuteMusic(0);
|
checkMessagesMuteMusic(0);
|
||||||
break;
|
break;
|
||||||
@@ -1369,7 +1421,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 38;
|
private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 38;
|
||||||
|
|
||||||
private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE = 39;
|
private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE = 39;
|
||||||
|
private static final int MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY = 40;
|
||||||
|
private static final int MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY = 41;
|
||||||
|
|
||||||
private static boolean isMessageHandledUnderWakelock(int msgId) {
|
private static boolean isMessageHandledUnderWakelock(int msgId) {
|
||||||
switch(msgId) {
|
switch(msgId) {
|
||||||
@@ -1609,16 +1662,25 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
* @return selected forced usage for communication.
|
* @return selected forced usage for communication.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mDeviceStateLock")
|
@GuardedBy("mDeviceStateLock")
|
||||||
private int getForcedUseForComm() {
|
@Nullable private AudioDeviceAttributes getPreferredDeviceForComm() {
|
||||||
boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
|
boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn();
|
||||||
|
|
||||||
if (btSCoOn) {
|
if (btSCoOn) {
|
||||||
return AudioSystem.FORCE_BT_SCO;
|
// Use the SCO device known to BtHelper so that it matches exactly
|
||||||
|
// what has been communicated to audio policy manager. The device
|
||||||
|
// returned by requestedCommunicationDevice() can be a dummy SCO device if legacy
|
||||||
|
// APIs are used to start SCO audio.
|
||||||
|
AudioDeviceAttributes device = mBtHelper.getHeadsetAudioDevice();
|
||||||
|
if (device != null) {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (isSpeakerphoneRequested()) {
|
AudioDeviceAttributes device = requestedCommunicationDevice();
|
||||||
return AudioSystem.FORCE_SPEAKER;
|
if (device == null
|
||||||
|
|| AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(device.getInternalType())) {
|
||||||
|
// Do not indicate BT SCO selection if SCO is requested but SCO is not ON
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return AudioSystem.FORCE_NONE;
|
return device;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1628,30 +1690,24 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
// @GuardedBy("mSetModeLock")
|
// @GuardedBy("mSetModeLock")
|
||||||
@GuardedBy("mDeviceStateLock")
|
@GuardedBy("mDeviceStateLock")
|
||||||
private void onUpdateCommunicationRoute(String eventSource) {
|
private void onUpdateCommunicationRoute(String eventSource) {
|
||||||
mForcedUseForComm = getForcedUseForComm();
|
mPreferredDeviceforComm = getPreferredDeviceForComm();
|
||||||
|
|
||||||
if (AudioService.DEBUG_COMM_RTE) {
|
if (AudioService.DEBUG_COMM_RTE) {
|
||||||
Log.v(TAG, "onUpdateCommunicationRoute, mForcedUseForComm: " + mForcedUseForComm
|
Log.v(TAG, "onUpdateCommunicationRoute, mPreferredDeviceforComm: "
|
||||||
+ " eventSource: " + eventSource);
|
+ mPreferredDeviceforComm + " eventSource: " + eventSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
|
if (mPreferredDeviceforComm == null
|
||||||
AudioSystem.setParameters("BT_SCO=on");
|
|| !AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains(
|
||||||
setForceUse_Async(
|
mPreferredDeviceforComm.getInternalType())) {
|
||||||
AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO, eventSource);
|
|
||||||
setForceUse_Async(
|
|
||||||
AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO, eventSource);
|
|
||||||
} else {
|
|
||||||
AudioSystem.setParameters("BT_SCO=off");
|
AudioSystem.setParameters("BT_SCO=off");
|
||||||
setForceUse_Async(
|
} else {
|
||||||
AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource);
|
AudioSystem.setParameters("BT_SCO=on");
|
||||||
if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) {
|
}
|
||||||
setForceUse_Async(
|
if (mPreferredDeviceforComm == null) {
|
||||||
AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_SPEAKER, eventSource);
|
postRemovePreferredDevicesForStrategy(mCommunicationStrategyId);
|
||||||
} else {
|
} else {
|
||||||
setForceUse_Async(
|
postSetPreferredDevicesForStrategy(
|
||||||
AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE, eventSource);
|
mCommunicationStrategyId, Arrays.asList(mPreferredDeviceforComm));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mAudioService.postUpdateRingerModeServiceInt();
|
mAudioService.postUpdateRingerModeServiceInt();
|
||||||
dispatchCommunicationDevice();
|
dispatchCommunicationDevice();
|
||||||
|
|||||||
@@ -648,6 +648,10 @@ public class AudioDeviceInventory {
|
|||||||
/*package*/ int setPreferredDevicesForStrategySync(int strategy,
|
/*package*/ int setPreferredDevicesForStrategySync(int strategy,
|
||||||
@NonNull List<AudioDeviceAttributes> devices) {
|
@NonNull List<AudioDeviceAttributes> devices) {
|
||||||
final long identity = Binder.clearCallingIdentity();
|
final long identity = Binder.clearCallingIdentity();
|
||||||
|
|
||||||
|
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
|
||||||
|
"setPreferredDevicesForStrategySync, strategy: " + strategy
|
||||||
|
+ " devices: " + devices)).printLog(TAG));
|
||||||
final int status = mAudioSystem.setDevicesRoleForStrategy(
|
final int status = mAudioSystem.setDevicesRoleForStrategy(
|
||||||
strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
|
strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices);
|
||||||
Binder.restoreCallingIdentity(identity);
|
Binder.restoreCallingIdentity(identity);
|
||||||
|
|||||||
@@ -4972,8 +4972,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
switch (mPlatformType) {
|
switch (mPlatformType) {
|
||||||
case AudioSystem.PLATFORM_VOICE:
|
case AudioSystem.PLATFORM_VOICE:
|
||||||
if (isInCommunication()) {
|
if (isInCommunication()) {
|
||||||
if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
|
if (mDeviceBroker.isBluetoothScoOn()) {
|
||||||
== AudioSystem.FORCE_BT_SCO) {
|
|
||||||
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
|
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
|
||||||
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
||||||
} else {
|
} else {
|
||||||
@@ -5009,8 +5008,7 @@ public class AudioService extends IAudioService.Stub
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (isInCommunication()) {
|
if (isInCommunication()) {
|
||||||
if (AudioSystem.getForceUse(AudioSystem.FOR_COMMUNICATION)
|
if (mDeviceBroker.isBluetoothScoOn()) {
|
||||||
== AudioSystem.FORCE_BT_SCO) {
|
|
||||||
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
|
if (DEBUG_VOL) Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO");
|
||||||
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
return AudioSystem.STREAM_BLUETOOTH_SCO;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.bluetooth.BluetoothHeadset;
|
|||||||
import android.bluetooth.BluetoothHearingAid;
|
import android.bluetooth.BluetoothHearingAid;
|
||||||
import android.bluetooth.BluetoothProfile;
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.media.AudioDeviceAttributes;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioSystem;
|
import android.media.AudioSystem;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
@@ -530,46 +531,64 @@ public class BtHelper {
|
|||||||
mDeviceBroker.postBroadcastScoConnectionState(state);
|
mDeviceBroker.postBroadcastScoConnectionState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
|
@Nullable AudioDeviceAttributes getHeadsetAudioDevice() {
|
||||||
if (btDevice == null) {
|
if (mBluetoothHeadsetDevice == null) {
|
||||||
return true;
|
return null;
|
||||||
}
|
}
|
||||||
|
return btHeadsetDeviceToAudioDevice(mBluetoothHeadsetDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AudioDeviceAttributes btHeadsetDeviceToAudioDevice(BluetoothDevice btDevice) {
|
||||||
String address = btDevice.getAddress();
|
String address = btDevice.getAddress();
|
||||||
|
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
|
||||||
|
address = "";
|
||||||
|
}
|
||||||
BluetoothClass btClass = btDevice.getBluetoothClass();
|
BluetoothClass btClass = btDevice.getBluetoothClass();
|
||||||
int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
|
int nativeType = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
|
||||||
int[] outDeviceTypes = {
|
|
||||||
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
|
|
||||||
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
|
|
||||||
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT
|
|
||||||
};
|
|
||||||
if (btClass != null) {
|
if (btClass != null) {
|
||||||
switch (btClass.getDeviceClass()) {
|
switch (btClass.getDeviceClass()) {
|
||||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||||
outDeviceTypes = new int[] { AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET };
|
nativeType = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
|
||||||
break;
|
break;
|
||||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||||
outDeviceTypes = new int[] { AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT };
|
nativeType = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
|
if (AudioService.DEBUG_DEVICES) {
|
||||||
address = "";
|
Log.i(TAG, "btHeadsetDeviceToAudioDevice btDevice: " + btDevice
|
||||||
|
+ " btClass: " + (btClass == null ? "Unknown" : btClass)
|
||||||
|
+ " nativeType: " + nativeType + " address: " + address);
|
||||||
}
|
}
|
||||||
|
return new AudioDeviceAttributes(nativeType, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
|
||||||
|
if (btDevice == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
|
||||||
|
AudioDeviceAttributes audioDevice = btHeadsetDeviceToAudioDevice(btDevice);
|
||||||
String btDeviceName = getName(btDevice);
|
String btDeviceName = getName(btDevice);
|
||||||
boolean result = false;
|
boolean result = false;
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
result |= mDeviceBroker.handleDeviceConnection(
|
result |= mDeviceBroker.handleDeviceConnection(isActive, audioDevice.getInternalType(),
|
||||||
isActive, outDeviceTypes[0], address, btDeviceName);
|
audioDevice.getAddress(), btDeviceName);
|
||||||
} else {
|
} else {
|
||||||
|
int[] outDeviceTypes = {
|
||||||
|
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
|
||||||
|
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
|
||||||
|
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT
|
||||||
|
};
|
||||||
for (int outDeviceType : outDeviceTypes) {
|
for (int outDeviceType : outDeviceTypes) {
|
||||||
result |= mDeviceBroker.handleDeviceConnection(
|
result |= mDeviceBroker.handleDeviceConnection(
|
||||||
isActive, outDeviceType, address, btDeviceName);
|
isActive, outDeviceType, audioDevice.getAddress(), btDeviceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// handleDeviceConnection() && result to make sure the method get executed
|
// handleDeviceConnection() && result to make sure the method get executed
|
||||||
result = mDeviceBroker.handleDeviceConnection(
|
result = mDeviceBroker.handleDeviceConnection(
|
||||||
isActive, inDevice, address, btDeviceName) && result;
|
isActive, inDevice, audioDevice.getAddress(), btDeviceName) && result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user