Loading services/core/java/com/android/server/audio/AudioDeviceBroker.java +105 −102 Original line number Diff line number Diff line Loading @@ -286,22 +286,9 @@ import java.util.concurrent.atomic.AtomicBoolean; if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "setSpeakerphoneOn, on: " + on + " pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes device = null; if (on) { device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""); } else { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null || !client.requestsSpeakerphone()) { return; } } postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, device, BtHelper.SCO_MODE_UNDEFINED, eventSource)); } } postSetCommunicationDeviceForClient(new CommunicationDeviceInfo( cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""), on, BtHelper.SCO_MODE_UNDEFINED, eventSource, false)); } /** Loading @@ -311,6 +298,9 @@ import java.util.concurrent.atomic.AtomicBoolean; * @param device Device selected or null to unselect. * @param eventSource for logging purposes */ private static final long SET_COMMUNICATION_DEVICE_TIMEOUT_MS = 3000; /*package*/ boolean setCommunicationDevice( IBinder cb, int pid, AudioDeviceInfo device, String eventSource) { Loading @@ -318,21 +308,53 @@ import java.util.concurrent.atomic.AtomicBoolean; Log.v(TAG, "setCommunicationDevice, device: " + device + ", pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes deviceAttr = null; if (device != null) { deviceAttr = new AudioDeviceAttributes(device); } else { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null) { return false; AudioDeviceAttributes deviceAttr = (device != null) ? new AudioDeviceAttributes(device) : null; CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(cb, pid, deviceAttr, device != null, BtHelper.SCO_MODE_UNDEFINED, eventSource, true); postSetCommunicationDeviceForClient(deviceInfo); boolean status; synchronized (deviceInfo) { final long start = System.currentTimeMillis(); long elapsed = 0; while (deviceInfo.mWaitForStatus) { try { deviceInfo.wait(SET_COMMUNICATION_DEVICE_TIMEOUT_MS - elapsed); } catch (InterruptedException e) { elapsed = System.currentTimeMillis() - start; if (elapsed >= SET_COMMUNICATION_DEVICE_TIMEOUT_MS) { deviceInfo.mStatus = false; deviceInfo.mWaitForStatus = false; } } } postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, deviceAttr, BtHelper.SCO_MODE_UNDEFINED, eventSource)); status = deviceInfo.mStatus; } return status; } /** * Sets or resets the communication device for matching client. If no client matches and the * request is to reset for a given device (deviceInfo.mOn == false), the method is a noop. * @param deviceInfo information on the device and requester {@link #CommunicationDeviceInfo} * @return true if the communication device is set or reset */ @GuardedBy("mDeviceStateLock") /*package*/ boolean onSetCommunicationDeviceForClient(CommunicationDeviceInfo deviceInfo) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onSetCommunicationDeviceForClient: " + deviceInfo); } if (!deviceInfo.mOn) { CommunicationRouteClient client = getCommunicationRouteClientForPid(deviceInfo.mPid); if (client == null || (deviceInfo.mDevice != null && !deviceInfo.mDevice.equals(client.getDevice()))) { return false; } } AudioDeviceAttributes device = deviceInfo.mOn ? deviceInfo.mDevice : null; setCommunicationRouteForClient(deviceInfo.mCb, deviceInfo.mPid, device, deviceInfo.mScoAudioMode, deviceInfo.mEventSource); return true; } Loading Loading @@ -390,7 +412,7 @@ import java.util.concurrent.atomic.AtomicBoolean; mBtHelper.stopBluetoothSco(eventSource); } sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE, SENDMSG_QUEUE, eventSource); updateCommunicationRoute(eventSource); } /** Loading Loading @@ -424,7 +446,7 @@ import java.util.concurrent.atomic.AtomicBoolean; CommunicationRouteClient crc = topCommunicationRouteClient(); AudioDeviceAttributes device = crc != null ? crc.getDevice() : null; if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "requestedCommunicationDevice, device: " Log.v(TAG, "requestedCommunicationDevice: " + device + " mAudioModeOwner: " + mAudioModeOwner.toString()); } return device; Loading Loading @@ -822,37 +844,22 @@ import java.util.concurrent.atomic.AtomicBoolean; @NonNull String eventSource) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "startBluetoothScoForClient_Sync, pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""); postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, device, scoAudioMode, eventSource)); } Log.v(TAG, "startBluetoothScoForClient, pid: " + pid); } postSetCommunicationDeviceForClient(new CommunicationDeviceInfo( cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""), true, scoAudioMode, eventSource, false)); } /*package*/ void stopBluetoothScoForClient( IBinder cb, int pid, @NonNull String eventSource) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "stopBluetoothScoForClient_Sync, pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null || !client.requestsBluetoothSco()) { return; } postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, null, BtHelper.SCO_MODE_UNDEFINED, eventSource)); } Log.v(TAG, "stopBluetoothScoForClient, pid: " + pid); } postSetCommunicationDeviceForClient(new CommunicationDeviceInfo( cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""), false, BtHelper.SCO_MODE_UNDEFINED, eventSource, false)); } /*package*/ int setPreferredDevicesForStrategySync(int strategy, Loading Loading @@ -990,7 +997,8 @@ import java.util.concurrent.atomic.AtomicBoolean; } //--------------------------------------------------------------------- // Message handling on behalf of helper classes // Message handling on behalf of helper classes. // Each of these methods posts a message to mBrokerHandler message queue. /*package*/ void postBroadcastScoConnectionState(int state) { sendIMsgNoDelay(MSG_I_BROADCAST_BT_CONNECTION_STATE, SENDMSG_QUEUE, state); } Loading Loading @@ -1046,28 +1054,34 @@ import java.util.concurrent.atomic.AtomicBoolean; sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE, eventSource); } /*package*/ void postSetCommunicationRouteForClient(CommunicationClientInfo info) { sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT, SENDMSG_QUEUE, info); /*package*/ void postSetCommunicationDeviceForClient(CommunicationDeviceInfo info) { sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT, SENDMSG_QUEUE, info); } /*package*/ void postScoAudioStateChanged(int state) { sendIMsgNoDelay(MSG_I_SCO_AUDIO_STATE_CHANGED, SENDMSG_QUEUE, state); } /*package*/ static final class CommunicationClientInfo { final @NonNull IBinder mCb; final int mPid; final @NonNull AudioDeviceAttributes mDevice; final int mScoAudioMode; final @NonNull String mEventSource; /*package*/ static final class CommunicationDeviceInfo { final @NonNull IBinder mCb; // Identifies the requesting client for death handler final int mPid; // Requester process ID final @Nullable AudioDeviceAttributes mDevice; // Device being set or reset. final boolean mOn; // true if setting, false if resetting final int mScoAudioMode; // only used for SCO: requested audio mode final @NonNull String mEventSource; // caller identifier for logging boolean mWaitForStatus; // true if the caller waits for a completion status (API dependent) boolean mStatus = false; // completion status only used if mWaitForStatus is true CommunicationClientInfo(@NonNull IBinder cb, int pid, @NonNull AudioDeviceAttributes device, int scoAudioMode, @NonNull String eventSource) { CommunicationDeviceInfo(@NonNull IBinder cb, int pid, @Nullable AudioDeviceAttributes device, boolean on, int scoAudioMode, @NonNull String eventSource, boolean waitForStatus) { mCb = cb; mPid = pid; mDevice = device; mOn = on; mScoAudioMode = scoAudioMode; mEventSource = eventSource; mWaitForStatus = waitForStatus; } // redefine equality op so we can match messages intended for this client Loading @@ -1079,21 +1093,24 @@ import java.util.concurrent.atomic.AtomicBoolean; if (this == o) { return true; } if (!(o instanceof CommunicationClientInfo)) { if (!(o instanceof CommunicationDeviceInfo)) { return false; } return mCb.equals(((CommunicationClientInfo) o).mCb) && mPid == ((CommunicationClientInfo) o).mPid; return mCb.equals(((CommunicationDeviceInfo) o).mCb) && mPid == ((CommunicationDeviceInfo) o).mPid; } @Override public String toString() { return "CommunicationClientInfo mCb=" + mCb.toString() return "CommunicationDeviceInfo mCb=" + mCb.toString() + " mPid=" + mPid +"mDevice=" + mDevice.toString() + " mDevice=[" + (mDevice != null ? mDevice.toString() : "null") + "]" + " mOn=" + mOn + " mScoAudioMode=" + mScoAudioMode +"mEventSource=" + mEventSource; + " mEventSource=" + mEventSource + " mWaitForStatus=" + mWaitForStatus + " mStatus=" + mStatus; } } Loading Loading @@ -1297,7 +1314,7 @@ import java.util.concurrent.atomic.AtomicBoolean; updateActiveCommunicationDevice(); mDeviceInventory.onRestoreDevices(); mBtHelper.onAudioServerDiedRestoreA2dp(); onUpdateCommunicationRoute("MSG_RESTORE_DEVICES"); updateCommunicationRoute("MSG_RESTORE_DEVICES"); } } break; Loading Loading @@ -1392,28 +1409,27 @@ import java.util.concurrent.atomic.AtomicBoolean; } break; case MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT: case MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT: CommunicationDeviceInfo deviceInfo = (CommunicationDeviceInfo) msg.obj; boolean status; synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { CommunicationClientInfo info = (CommunicationClientInfo) msg.obj; setCommunicationRouteForClient(info.mCb, info.mPid, info.mDevice, info.mScoAudioMode, info.mEventSource); status = onSetCommunicationDeviceForClient(deviceInfo); } } break; case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { onUpdateCommunicationRouteClient((String) msg.obj); synchronized (deviceInfo) { if (deviceInfo.mWaitForStatus) { deviceInfo.mStatus = status; deviceInfo.mWaitForStatus = false; deviceInfo.notify(); } } break; case MSG_L_UPDATE_COMMUNICATION_ROUTE: case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { onUpdateCommunicationRoute((String) msg.obj); onUpdateCommunicationRouteClient((String) msg.obj); } } break; Loading Loading @@ -1568,8 +1584,7 @@ import java.util.concurrent.atomic.AtomicBoolean; private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET = 37; 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_SET_COMMUNICATION_ROUTE_FOR_CLIENT = 42; private static final int MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT = 42; private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43; private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44; Loading Loading @@ -1793,18 +1808,6 @@ import java.util.concurrent.atomic.AtomicBoolean; AudioDeviceAttributes getDevice() { return mDevice; } boolean requestsBluetoothSco() { return mDevice != null && mDevice.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO; } boolean requestsSpeakerphone() { return mDevice != null && mDevice.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER; } } // @GuardedBy("mSetModeLock") Loading Loading @@ -1852,14 +1855,14 @@ import java.util.concurrent.atomic.AtomicBoolean; */ // @GuardedBy("mSetModeLock") @GuardedBy("mDeviceStateLock") private void onUpdateCommunicationRoute(String eventSource) { private void updateCommunicationRoute(String eventSource) { AudioDeviceAttributes preferredCommunicationDevice = preferredCommunicationDevice(); if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onUpdateCommunicationRoute, preferredCommunicationDevice: " Log.v(TAG, "updateCommunicationRoute, preferredCommunicationDevice: " + preferredCommunicationDevice + " eventSource: " + eventSource); } AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent( "onUpdateCommunicationRoute, preferredCommunicationDevice: " "updateCommunicationRoute, preferredCommunicationDevice: " + preferredCommunicationDevice + " eventSource: " + eventSource))); if (preferredCommunicationDevice == null Loading Loading @@ -1895,7 +1898,7 @@ import java.util.concurrent.atomic.AtomicBoolean; // @GuardedBy("mSetModeLock") @GuardedBy("mDeviceStateLock") private void onUpdateCommunicationRouteClient(String eventSource) { onUpdateCommunicationRoute(eventSource); updateCommunicationRoute(eventSource); CommunicationRouteClient crc = topCommunicationRouteClient(); if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " Loading Loading
services/core/java/com/android/server/audio/AudioDeviceBroker.java +105 −102 Original line number Diff line number Diff line Loading @@ -286,22 +286,9 @@ import java.util.concurrent.atomic.AtomicBoolean; if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "setSpeakerphoneOn, on: " + on + " pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes device = null; if (on) { device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""); } else { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null || !client.requestsSpeakerphone()) { return; } } postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, device, BtHelper.SCO_MODE_UNDEFINED, eventSource)); } } postSetCommunicationDeviceForClient(new CommunicationDeviceInfo( cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""), on, BtHelper.SCO_MODE_UNDEFINED, eventSource, false)); } /** Loading @@ -311,6 +298,9 @@ import java.util.concurrent.atomic.AtomicBoolean; * @param device Device selected or null to unselect. * @param eventSource for logging purposes */ private static final long SET_COMMUNICATION_DEVICE_TIMEOUT_MS = 3000; /*package*/ boolean setCommunicationDevice( IBinder cb, int pid, AudioDeviceInfo device, String eventSource) { Loading @@ -318,21 +308,53 @@ import java.util.concurrent.atomic.AtomicBoolean; Log.v(TAG, "setCommunicationDevice, device: " + device + ", pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes deviceAttr = null; if (device != null) { deviceAttr = new AudioDeviceAttributes(device); } else { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null) { return false; AudioDeviceAttributes deviceAttr = (device != null) ? new AudioDeviceAttributes(device) : null; CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(cb, pid, deviceAttr, device != null, BtHelper.SCO_MODE_UNDEFINED, eventSource, true); postSetCommunicationDeviceForClient(deviceInfo); boolean status; synchronized (deviceInfo) { final long start = System.currentTimeMillis(); long elapsed = 0; while (deviceInfo.mWaitForStatus) { try { deviceInfo.wait(SET_COMMUNICATION_DEVICE_TIMEOUT_MS - elapsed); } catch (InterruptedException e) { elapsed = System.currentTimeMillis() - start; if (elapsed >= SET_COMMUNICATION_DEVICE_TIMEOUT_MS) { deviceInfo.mStatus = false; deviceInfo.mWaitForStatus = false; } } } postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, deviceAttr, BtHelper.SCO_MODE_UNDEFINED, eventSource)); status = deviceInfo.mStatus; } return status; } /** * Sets or resets the communication device for matching client. If no client matches and the * request is to reset for a given device (deviceInfo.mOn == false), the method is a noop. * @param deviceInfo information on the device and requester {@link #CommunicationDeviceInfo} * @return true if the communication device is set or reset */ @GuardedBy("mDeviceStateLock") /*package*/ boolean onSetCommunicationDeviceForClient(CommunicationDeviceInfo deviceInfo) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onSetCommunicationDeviceForClient: " + deviceInfo); } if (!deviceInfo.mOn) { CommunicationRouteClient client = getCommunicationRouteClientForPid(deviceInfo.mPid); if (client == null || (deviceInfo.mDevice != null && !deviceInfo.mDevice.equals(client.getDevice()))) { return false; } } AudioDeviceAttributes device = deviceInfo.mOn ? deviceInfo.mDevice : null; setCommunicationRouteForClient(deviceInfo.mCb, deviceInfo.mPid, device, deviceInfo.mScoAudioMode, deviceInfo.mEventSource); return true; } Loading Loading @@ -390,7 +412,7 @@ import java.util.concurrent.atomic.AtomicBoolean; mBtHelper.stopBluetoothSco(eventSource); } sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE, SENDMSG_QUEUE, eventSource); updateCommunicationRoute(eventSource); } /** Loading Loading @@ -424,7 +446,7 @@ import java.util.concurrent.atomic.AtomicBoolean; CommunicationRouteClient crc = topCommunicationRouteClient(); AudioDeviceAttributes device = crc != null ? crc.getDevice() : null; if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "requestedCommunicationDevice, device: " Log.v(TAG, "requestedCommunicationDevice: " + device + " mAudioModeOwner: " + mAudioModeOwner.toString()); } return device; Loading Loading @@ -822,37 +844,22 @@ import java.util.concurrent.atomic.AtomicBoolean; @NonNull String eventSource) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "startBluetoothScoForClient_Sync, pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { AudioDeviceAttributes device = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""); postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, device, scoAudioMode, eventSource)); } Log.v(TAG, "startBluetoothScoForClient, pid: " + pid); } postSetCommunicationDeviceForClient(new CommunicationDeviceInfo( cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""), true, scoAudioMode, eventSource, false)); } /*package*/ void stopBluetoothScoForClient( IBinder cb, int pid, @NonNull String eventSource) { if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "stopBluetoothScoForClient_Sync, pid: " + pid); } synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { CommunicationRouteClient client = getCommunicationRouteClientForPid(pid); if (client == null || !client.requestsBluetoothSco()) { return; } postSetCommunicationRouteForClient(new CommunicationClientInfo( cb, pid, null, BtHelper.SCO_MODE_UNDEFINED, eventSource)); } Log.v(TAG, "stopBluetoothScoForClient, pid: " + pid); } postSetCommunicationDeviceForClient(new CommunicationDeviceInfo( cb, pid, new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, ""), false, BtHelper.SCO_MODE_UNDEFINED, eventSource, false)); } /*package*/ int setPreferredDevicesForStrategySync(int strategy, Loading Loading @@ -990,7 +997,8 @@ import java.util.concurrent.atomic.AtomicBoolean; } //--------------------------------------------------------------------- // Message handling on behalf of helper classes // Message handling on behalf of helper classes. // Each of these methods posts a message to mBrokerHandler message queue. /*package*/ void postBroadcastScoConnectionState(int state) { sendIMsgNoDelay(MSG_I_BROADCAST_BT_CONNECTION_STATE, SENDMSG_QUEUE, state); } Loading Loading @@ -1046,28 +1054,34 @@ import java.util.concurrent.atomic.AtomicBoolean; sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE, eventSource); } /*package*/ void postSetCommunicationRouteForClient(CommunicationClientInfo info) { sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT, SENDMSG_QUEUE, info); /*package*/ void postSetCommunicationDeviceForClient(CommunicationDeviceInfo info) { sendLMsgNoDelay(MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT, SENDMSG_QUEUE, info); } /*package*/ void postScoAudioStateChanged(int state) { sendIMsgNoDelay(MSG_I_SCO_AUDIO_STATE_CHANGED, SENDMSG_QUEUE, state); } /*package*/ static final class CommunicationClientInfo { final @NonNull IBinder mCb; final int mPid; final @NonNull AudioDeviceAttributes mDevice; final int mScoAudioMode; final @NonNull String mEventSource; /*package*/ static final class CommunicationDeviceInfo { final @NonNull IBinder mCb; // Identifies the requesting client for death handler final int mPid; // Requester process ID final @Nullable AudioDeviceAttributes mDevice; // Device being set or reset. final boolean mOn; // true if setting, false if resetting final int mScoAudioMode; // only used for SCO: requested audio mode final @NonNull String mEventSource; // caller identifier for logging boolean mWaitForStatus; // true if the caller waits for a completion status (API dependent) boolean mStatus = false; // completion status only used if mWaitForStatus is true CommunicationClientInfo(@NonNull IBinder cb, int pid, @NonNull AudioDeviceAttributes device, int scoAudioMode, @NonNull String eventSource) { CommunicationDeviceInfo(@NonNull IBinder cb, int pid, @Nullable AudioDeviceAttributes device, boolean on, int scoAudioMode, @NonNull String eventSource, boolean waitForStatus) { mCb = cb; mPid = pid; mDevice = device; mOn = on; mScoAudioMode = scoAudioMode; mEventSource = eventSource; mWaitForStatus = waitForStatus; } // redefine equality op so we can match messages intended for this client Loading @@ -1079,21 +1093,24 @@ import java.util.concurrent.atomic.AtomicBoolean; if (this == o) { return true; } if (!(o instanceof CommunicationClientInfo)) { if (!(o instanceof CommunicationDeviceInfo)) { return false; } return mCb.equals(((CommunicationClientInfo) o).mCb) && mPid == ((CommunicationClientInfo) o).mPid; return mCb.equals(((CommunicationDeviceInfo) o).mCb) && mPid == ((CommunicationDeviceInfo) o).mPid; } @Override public String toString() { return "CommunicationClientInfo mCb=" + mCb.toString() return "CommunicationDeviceInfo mCb=" + mCb.toString() + " mPid=" + mPid +"mDevice=" + mDevice.toString() + " mDevice=[" + (mDevice != null ? mDevice.toString() : "null") + "]" + " mOn=" + mOn + " mScoAudioMode=" + mScoAudioMode +"mEventSource=" + mEventSource; + " mEventSource=" + mEventSource + " mWaitForStatus=" + mWaitForStatus + " mStatus=" + mStatus; } } Loading Loading @@ -1297,7 +1314,7 @@ import java.util.concurrent.atomic.AtomicBoolean; updateActiveCommunicationDevice(); mDeviceInventory.onRestoreDevices(); mBtHelper.onAudioServerDiedRestoreA2dp(); onUpdateCommunicationRoute("MSG_RESTORE_DEVICES"); updateCommunicationRoute("MSG_RESTORE_DEVICES"); } } break; Loading Loading @@ -1392,28 +1409,27 @@ import java.util.concurrent.atomic.AtomicBoolean; } break; case MSG_L_SET_COMMUNICATION_ROUTE_FOR_CLIENT: case MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT: CommunicationDeviceInfo deviceInfo = (CommunicationDeviceInfo) msg.obj; boolean status; synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { CommunicationClientInfo info = (CommunicationClientInfo) msg.obj; setCommunicationRouteForClient(info.mCb, info.mPid, info.mDevice, info.mScoAudioMode, info.mEventSource); status = onSetCommunicationDeviceForClient(deviceInfo); } } break; case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { onUpdateCommunicationRouteClient((String) msg.obj); synchronized (deviceInfo) { if (deviceInfo.mWaitForStatus) { deviceInfo.mStatus = status; deviceInfo.mWaitForStatus = false; deviceInfo.notify(); } } break; case MSG_L_UPDATE_COMMUNICATION_ROUTE: case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT: synchronized (mSetModeLock) { synchronized (mDeviceStateLock) { onUpdateCommunicationRoute((String) msg.obj); onUpdateCommunicationRouteClient((String) msg.obj); } } break; Loading Loading @@ -1568,8 +1584,7 @@ import java.util.concurrent.atomic.AtomicBoolean; private static final int MSG_IL_SAVE_PREF_DEVICES_FOR_CAPTURE_PRESET = 37; 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_SET_COMMUNICATION_ROUTE_FOR_CLIENT = 42; private static final int MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT = 42; private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43; private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44; Loading Loading @@ -1793,18 +1808,6 @@ import java.util.concurrent.atomic.AtomicBoolean; AudioDeviceAttributes getDevice() { return mDevice; } boolean requestsBluetoothSco() { return mDevice != null && mDevice.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_SCO; } boolean requestsSpeakerphone() { return mDevice != null && mDevice.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER; } } // @GuardedBy("mSetModeLock") Loading Loading @@ -1852,14 +1855,14 @@ import java.util.concurrent.atomic.AtomicBoolean; */ // @GuardedBy("mSetModeLock") @GuardedBy("mDeviceStateLock") private void onUpdateCommunicationRoute(String eventSource) { private void updateCommunicationRoute(String eventSource) { AudioDeviceAttributes preferredCommunicationDevice = preferredCommunicationDevice(); if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onUpdateCommunicationRoute, preferredCommunicationDevice: " Log.v(TAG, "updateCommunicationRoute, preferredCommunicationDevice: " + preferredCommunicationDevice + " eventSource: " + eventSource); } AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent( "onUpdateCommunicationRoute, preferredCommunicationDevice: " "updateCommunicationRoute, preferredCommunicationDevice: " + preferredCommunicationDevice + " eventSource: " + eventSource))); if (preferredCommunicationDevice == null Loading Loading @@ -1895,7 +1898,7 @@ import java.util.concurrent.atomic.AtomicBoolean; // @GuardedBy("mSetModeLock") @GuardedBy("mDeviceStateLock") private void onUpdateCommunicationRouteClient(String eventSource) { onUpdateCommunicationRoute(eventSource); updateCommunicationRoute(eventSource); CommunicationRouteClient crc = topCommunicationRouteClient(); if (AudioService.DEBUG_COMM_RTE) { Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " Loading