Loading core/jni/android_media_AudioSystem.cpp +18 −10 Original line number Diff line number Diff line Loading @@ -298,20 +298,25 @@ static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env, 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) { ALOGE_IF(status, "Command failed for %s: %d", caller, status); static int _check_AudioSystem_Command(const char *caller, status_t status, std::vector<status_t> ignoredErrors = {}) { int jniStatus = kAudioStatusOk; switch (status) { case DEAD_OBJECT: return kAudioStatusMediaServerDied; jniStatus = kAudioStatusMediaServerDied; break; case NO_ERROR: return kAudioStatusOk; break; default: if (std::find(begin(ignoredErrors), end(ignoredErrors), status) == end(ignoredErrors)) { jniStatus = kAudioStatusError; } break; } return kAudioStatusError; ALOGE_IF(jniStatus != kAudioStatusOk, "Command failed for %s: %d", caller, status); return jniStatus; } static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes, Loading Loading @@ -2350,9 +2355,12 @@ static jint android_media_AudioSystem_setDevicesRoleForStrategy(JNIEnv *env, job static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz, jint strategy, jint role) { return (jint)check_AudioSystem_Command( AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)strategy, (device_role_t)role)); return (jint) check_AudioSystem_Command(AudioSystem::removeDevicesRoleForStrategy((product_strategy_t) strategy, (device_role_t) role), {NAME_NOT_FOUND}); } static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz, Loading media/java/android/media/AudioDeviceAttributes.java +9 −5 Original line number Diff line number Diff line Loading @@ -120,7 +120,13 @@ public final class AudioDeviceAttributes implements Parcelable { 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; mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType); mAddress = address; Loading Loading @@ -191,10 +197,8 @@ public final class AudioDeviceAttributes implements Parcelable { public String toString() { return new String("AudioDeviceAttributes:" + " role:" + roleToString(mRole) + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName( AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType)) : AudioSystem.getInputDeviceName( AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType))) + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(mNativeType) : AudioSystem.getInputDeviceName(mNativeType)) + " addr:" + mAddress); } Loading media/java/android/media/AudioSystem.java +1 −1 Original line number Diff line number Diff line Loading @@ -1730,7 +1730,7 @@ public class AudioSystem int[] types = new int[devices.size()]; String[] addresses = new String[devices.size()]; 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(); } return setDevicesRoleForStrategy(strategy, role, types, addresses); Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +93 −37 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.audio; import android.annotation.NonNull; import android.annotation.Nullable; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; Loading @@ -34,6 +35,7 @@ import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.MediaMetrics; import android.media.audiopolicy.AudioProductStrategy; import android.os.Binder; import android.os.Handler; import android.os.IBinder; Loading @@ -51,6 +53,7 @@ import android.util.PrintWriterPrinter; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedList; import java.util.List; Loading @@ -77,7 +80,8 @@ import java.util.concurrent.atomic.AtomicBoolean; private final @NonNull Context mContext; /** 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 private final AudioDeviceInventory mDeviceInventory; Loading Loading @@ -133,10 +137,23 @@ import java.util.concurrent.atomic.AtomicBoolean; 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() { setupMessaging(mContext); mForcedUseForComm = AudioSystem.FORCE_NONE; mPreferredDeviceforComm = null; initCommunicationStrategyId(); } /*package*/ Context getContext() { Loading Loading @@ -221,8 +238,7 @@ import java.util.concurrent.atomic.AtomicBoolean; synchronized (mDeviceStateLock) { AudioDeviceAttributes device = null; if (on) { device = new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, ""); device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""); } else { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null || !client.requestsSpeakerphone()) { Loading Loading @@ -275,6 +291,10 @@ import java.util.concurrent.atomic.AtomicBoolean; if (AudioService.DEBUG_COMM_RTE) { 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 wasSpeakerphoneRequested = isSpeakerphoneRequested(); Loading Loading @@ -393,7 +413,11 @@ import java.util.concurrent.atomic.AtomicBoolean; * @return true if speakerphone is active, false otherwise. */ /*package*/ boolean isSpeakerphoneOn() { return getForcedUseForComm() == AudioSystem.FORCE_SPEAKER; AudioDeviceAttributes device = getPreferredDeviceForComm(); if (device == null) { return false; } return device.getInternalType() == AudioSystem.DEVICE_OUT_SPEAKER; } /** Loading Loading @@ -560,7 +584,11 @@ import java.util.concurrent.atomic.AtomicBoolean; * @return true if Bluetooth SCO is active , false otherwise. */ /*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) { Loading Loading @@ -612,8 +640,8 @@ import java.util.concurrent.atomic.AtomicBoolean; synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes device = new AudioDeviceAttributes( AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BLUETOOTH_SCO, ""); AudioDeviceAttributes device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""); setCommunicationRouteForClient(cb, pid, device, scoAudioMode, eventSource); } } Loading Loading @@ -643,10 +671,19 @@ import java.util.concurrent.atomic.AtomicBoolean; 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) { return mDeviceInventory.removePreferredDevicesForStrategySync(strategy); } /*package*/ void postRemovePreferredDevicesForStrategy(int strategy) { sendIMsgNoDelay(MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_REPLACE, strategy); } /*package*/ void registerStrategyPreferredDevicesDispatcher( @NonNull IStrategyPreferredDevicesDispatcher dispatcher) { mDeviceInventory.registerStrategyPreferredDevicesDispatcher(dispatcher); Loading Loading @@ -971,9 +1008,12 @@ import java.util.concurrent.atomic.AtomicBoolean; pw.println(" " + prefix + "pid: " + cl.getPid() + " device: " + cl.getDevice() + " cb: " + cl.getBinder()); }); pw.println("\n" + prefix + "mForcedUseForComm: " + AudioSystem.forceUseConfigToString(mForcedUseForComm)); pw.println(prefix + "mModeOwnerPid: " + mModeOwnerPid); pw.println("\n" + prefix + "mPreferredDeviceforComm: " + mPreferredDeviceforComm); pw.println(prefix + "mCommunicationStrategyId: " + mCommunicationStrategyId); pw.println("\n" + prefix + "mModeOwnerPid: " + mModeOwnerPid); mBtHelper.dump(pw, prefix); } Loading Loading @@ -1068,6 +1108,7 @@ import java.util.concurrent.atomic.AtomicBoolean; case MSG_RESTORE_DEVICES: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { initCommunicationStrategyId(); mDeviceInventory.onRestoreDevices(); mBtHelper.onAudioServerDiedRestoreA2dp(); onUpdateCommunicationRoute("MSG_RESTORE_DEVICES"); Loading Loading @@ -1277,6 +1318,17 @@ import java.util.concurrent.atomic.AtomicBoolean; final int strategy = msg.arg1; mDeviceInventory.onSaveRemovePreferredDevices(strategy); } 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: checkMessagesMuteMusic(0); break; Loading Loading @@ -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_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) { switch(msgId) { Loading Loading @@ -1609,16 +1662,25 @@ import java.util.concurrent.atomic.AtomicBoolean; * @return selected forced usage for communication. */ @GuardedBy("mDeviceStateLock") private int getForcedUseForComm() { @Nullable private AudioDeviceAttributes getPreferredDeviceForComm() { boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn(); 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()) { return AudioSystem.FORCE_SPEAKER; } return AudioSystem.FORCE_NONE; AudioDeviceAttributes device = requestedCommunicationDevice(); 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 device; } /** Loading @@ -1628,30 +1690,24 @@ import java.util.concurrent.atomic.AtomicBoolean; // @GuardedBy("mSetModeLock") @GuardedBy("mDeviceStateLock") private void onUpdateCommunicationRoute(String eventSource) { mForcedUseForComm = getForcedUseForComm(); mPreferredDeviceforComm = getPreferredDeviceForComm(); if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onUpdateCommunicationRoute, mForcedUseForComm: " + mForcedUseForComm + " eventSource: " + eventSource); Log.v(TAG, "onUpdateCommunicationRoute, mPreferredDeviceforComm: " + mPreferredDeviceforComm + " eventSource: " + eventSource); } if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { AudioSystem.setParameters("BT_SCO=on"); setForceUse_Async( AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO, eventSource); setForceUse_Async( AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO, eventSource); } else { if (mPreferredDeviceforComm == null || !AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains( mPreferredDeviceforComm.getInternalType())) { AudioSystem.setParameters("BT_SCO=off"); setForceUse_Async( AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource); if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) { setForceUse_Async( AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_SPEAKER, eventSource); } else { setForceUse_Async( AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE, eventSource); AudioSystem.setParameters("BT_SCO=on"); } if (mPreferredDeviceforComm == null) { postRemovePreferredDevicesForStrategy(mCommunicationStrategyId); } else { postSetPreferredDevicesForStrategy( mCommunicationStrategyId, Arrays.asList(mPreferredDeviceforComm)); } mAudioService.postUpdateRingerModeServiceInt(); dispatchCommunicationDevice(); Loading services/core/java/com/android/server/audio/AudioDeviceInventory.java +4 −0 Original line number Diff line number Diff line Loading @@ -648,6 +648,10 @@ public class AudioDeviceInventory { /*package*/ int setPreferredDevicesForStrategySync(int strategy, @NonNull List<AudioDeviceAttributes> devices) { final long identity = Binder.clearCallingIdentity(); AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent( "setPreferredDevicesForStrategySync, strategy: " + strategy + " devices: " + devices)).printLog(TAG)); final int status = mAudioSystem.setDevicesRoleForStrategy( strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); Binder.restoreCallingIdentity(identity); Loading Loading
core/jni/android_media_AudioSystem.cpp +18 −10 Original line number Diff line number Diff line Loading @@ -298,20 +298,25 @@ static sp<JNIAudioPortCallback> setJniCallback(JNIEnv* env, 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) { ALOGE_IF(status, "Command failed for %s: %d", caller, status); static int _check_AudioSystem_Command(const char *caller, status_t status, std::vector<status_t> ignoredErrors = {}) { int jniStatus = kAudioStatusOk; switch (status) { case DEAD_OBJECT: return kAudioStatusMediaServerDied; jniStatus = kAudioStatusMediaServerDied; break; case NO_ERROR: return kAudioStatusOk; break; default: if (std::find(begin(ignoredErrors), end(ignoredErrors), status) == end(ignoredErrors)) { jniStatus = kAudioStatusError; } break; } return kAudioStatusError; ALOGE_IF(jniStatus != kAudioStatusOk, "Command failed for %s: %d", caller, status); return jniStatus; } static jint getVectorOfAudioDeviceTypeAddr(JNIEnv *env, jintArray deviceTypes, Loading Loading @@ -2350,9 +2355,12 @@ static jint android_media_AudioSystem_setDevicesRoleForStrategy(JNIEnv *env, job static jint android_media_AudioSystem_removeDevicesRoleForStrategy(JNIEnv *env, jobject thiz, jint strategy, jint role) { return (jint)check_AudioSystem_Command( AudioSystem::removeDevicesRoleForStrategy((product_strategy_t)strategy, (device_role_t)role)); return (jint) check_AudioSystem_Command(AudioSystem::removeDevicesRoleForStrategy((product_strategy_t) strategy, (device_role_t) role), {NAME_NOT_FOUND}); } static jint android_media_AudioSystem_getDevicesForRoleAndStrategy(JNIEnv *env, jobject thiz, Loading
media/java/android/media/AudioDeviceAttributes.java +9 −5 Original line number Diff line number Diff line Loading @@ -120,7 +120,13 @@ public final class AudioDeviceAttributes implements Parcelable { 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; mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType); mAddress = address; Loading Loading @@ -191,10 +197,8 @@ public final class AudioDeviceAttributes implements Parcelable { public String toString() { return new String("AudioDeviceAttributes:" + " role:" + roleToString(mRole) + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName( AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType)) : AudioSystem.getInputDeviceName( AudioDeviceInfo.convertDeviceTypeToInternalDevice(mType))) + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(mNativeType) : AudioSystem.getInputDeviceName(mNativeType)) + " addr:" + mAddress); } Loading
media/java/android/media/AudioSystem.java +1 −1 Original line number Diff line number Diff line Loading @@ -1730,7 +1730,7 @@ public class AudioSystem int[] types = new int[devices.size()]; String[] addresses = new String[devices.size()]; 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(); } return setDevicesRoleForStrategy(strategy, role, types, addresses); Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +93 −37 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.audio; import android.annotation.NonNull; import android.annotation.Nullable; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; Loading @@ -34,6 +35,7 @@ import android.media.ICapturePresetDevicesRoleDispatcher; import android.media.ICommunicationDeviceDispatcher; import android.media.IStrategyPreferredDevicesDispatcher; import android.media.MediaMetrics; import android.media.audiopolicy.AudioProductStrategy; import android.os.Binder; import android.os.Handler; import android.os.IBinder; Loading @@ -51,6 +53,7 @@ import android.util.PrintWriterPrinter; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedList; import java.util.List; Loading @@ -77,7 +80,8 @@ import java.util.concurrent.atomic.AtomicBoolean; private final @NonNull Context mContext; /** 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 private final AudioDeviceInventory mDeviceInventory; Loading Loading @@ -133,10 +137,23 @@ import java.util.concurrent.atomic.AtomicBoolean; 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() { setupMessaging(mContext); mForcedUseForComm = AudioSystem.FORCE_NONE; mPreferredDeviceforComm = null; initCommunicationStrategyId(); } /*package*/ Context getContext() { Loading Loading @@ -221,8 +238,7 @@ import java.util.concurrent.atomic.AtomicBoolean; synchronized (mDeviceStateLock) { AudioDeviceAttributes device = null; if (on) { device = new AudioDeviceAttributes(AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER, ""); device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""); } else { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null || !client.requestsSpeakerphone()) { Loading Loading @@ -275,6 +291,10 @@ import java.util.concurrent.atomic.AtomicBoolean; if (AudioService.DEBUG_COMM_RTE) { 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 wasSpeakerphoneRequested = isSpeakerphoneRequested(); Loading Loading @@ -393,7 +413,11 @@ import java.util.concurrent.atomic.AtomicBoolean; * @return true if speakerphone is active, false otherwise. */ /*package*/ boolean isSpeakerphoneOn() { return getForcedUseForComm() == AudioSystem.FORCE_SPEAKER; AudioDeviceAttributes device = getPreferredDeviceForComm(); if (device == null) { return false; } return device.getInternalType() == AudioSystem.DEVICE_OUT_SPEAKER; } /** Loading Loading @@ -560,7 +584,11 @@ import java.util.concurrent.atomic.AtomicBoolean; * @return true if Bluetooth SCO is active , false otherwise. */ /*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) { Loading Loading @@ -612,8 +640,8 @@ import java.util.concurrent.atomic.AtomicBoolean; synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes device = new AudioDeviceAttributes( AudioDeviceAttributes.ROLE_OUTPUT, AudioDeviceInfo.TYPE_BLUETOOTH_SCO, ""); AudioDeviceAttributes device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""); setCommunicationRouteForClient(cb, pid, device, scoAudioMode, eventSource); } } Loading Loading @@ -643,10 +671,19 @@ import java.util.concurrent.atomic.AtomicBoolean; 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) { return mDeviceInventory.removePreferredDevicesForStrategySync(strategy); } /*package*/ void postRemovePreferredDevicesForStrategy(int strategy) { sendIMsgNoDelay(MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY, SENDMSG_REPLACE, strategy); } /*package*/ void registerStrategyPreferredDevicesDispatcher( @NonNull IStrategyPreferredDevicesDispatcher dispatcher) { mDeviceInventory.registerStrategyPreferredDevicesDispatcher(dispatcher); Loading Loading @@ -971,9 +1008,12 @@ import java.util.concurrent.atomic.AtomicBoolean; pw.println(" " + prefix + "pid: " + cl.getPid() + " device: " + cl.getDevice() + " cb: " + cl.getBinder()); }); pw.println("\n" + prefix + "mForcedUseForComm: " + AudioSystem.forceUseConfigToString(mForcedUseForComm)); pw.println(prefix + "mModeOwnerPid: " + mModeOwnerPid); pw.println("\n" + prefix + "mPreferredDeviceforComm: " + mPreferredDeviceforComm); pw.println(prefix + "mCommunicationStrategyId: " + mCommunicationStrategyId); pw.println("\n" + prefix + "mModeOwnerPid: " + mModeOwnerPid); mBtHelper.dump(pw, prefix); } Loading Loading @@ -1068,6 +1108,7 @@ import java.util.concurrent.atomic.AtomicBoolean; case MSG_RESTORE_DEVICES: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { initCommunicationStrategyId(); mDeviceInventory.onRestoreDevices(); mBtHelper.onAudioServerDiedRestoreA2dp(); onUpdateCommunicationRoute("MSG_RESTORE_DEVICES"); Loading Loading @@ -1277,6 +1318,17 @@ import java.util.concurrent.atomic.AtomicBoolean; final int strategy = msg.arg1; mDeviceInventory.onSaveRemovePreferredDevices(strategy); } 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: checkMessagesMuteMusic(0); break; Loading Loading @@ -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_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) { switch(msgId) { Loading Loading @@ -1609,16 +1662,25 @@ import java.util.concurrent.atomic.AtomicBoolean; * @return selected forced usage for communication. */ @GuardedBy("mDeviceStateLock") private int getForcedUseForComm() { @Nullable private AudioDeviceAttributes getPreferredDeviceForComm() { boolean btSCoOn = mBluetoothScoOn && mBtHelper.isBluetoothScoOn(); 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()) { return AudioSystem.FORCE_SPEAKER; } return AudioSystem.FORCE_NONE; AudioDeviceAttributes device = requestedCommunicationDevice(); 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 device; } /** Loading @@ -1628,30 +1690,24 @@ import java.util.concurrent.atomic.AtomicBoolean; // @GuardedBy("mSetModeLock") @GuardedBy("mDeviceStateLock") private void onUpdateCommunicationRoute(String eventSource) { mForcedUseForComm = getForcedUseForComm(); mPreferredDeviceforComm = getPreferredDeviceForComm(); if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onUpdateCommunicationRoute, mForcedUseForComm: " + mForcedUseForComm + " eventSource: " + eventSource); Log.v(TAG, "onUpdateCommunicationRoute, mPreferredDeviceforComm: " + mPreferredDeviceforComm + " eventSource: " + eventSource); } if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) { AudioSystem.setParameters("BT_SCO=on"); setForceUse_Async( AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO, eventSource); setForceUse_Async( AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO, eventSource); } else { if (mPreferredDeviceforComm == null || !AudioSystem.DEVICE_OUT_ALL_SCO_SET.contains( mPreferredDeviceforComm.getInternalType())) { AudioSystem.setParameters("BT_SCO=off"); setForceUse_Async( AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE, eventSource); if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) { setForceUse_Async( AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_SPEAKER, eventSource); } else { setForceUse_Async( AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE, eventSource); AudioSystem.setParameters("BT_SCO=on"); } if (mPreferredDeviceforComm == null) { postRemovePreferredDevicesForStrategy(mCommunicationStrategyId); } else { postSetPreferredDevicesForStrategy( mCommunicationStrategyId, Arrays.asList(mPreferredDeviceforComm)); } mAudioService.postUpdateRingerModeServiceInt(); dispatchCommunicationDevice(); Loading
services/core/java/com/android/server/audio/AudioDeviceInventory.java +4 −0 Original line number Diff line number Diff line Loading @@ -648,6 +648,10 @@ public class AudioDeviceInventory { /*package*/ int setPreferredDevicesForStrategySync(int strategy, @NonNull List<AudioDeviceAttributes> devices) { final long identity = Binder.clearCallingIdentity(); AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent( "setPreferredDevicesForStrategySync, strategy: " + strategy + " devices: " + devices)).printLog(TAG)); final int status = mAudioSystem.setDevicesRoleForStrategy( strategy, AudioSystem.DEVICE_ROLE_PREFERRED, devices); Binder.restoreCallingIdentity(identity); Loading