Loading android/pandora/server/proto/pandora/a2dp.proto +2 −3 Original line number Original line Diff line number Diff line Loading @@ -5,7 +5,6 @@ option java_outer_classname = "A2dpProto"; package pandora; package pandora; import "pandora/host.proto"; import "pandora/host.proto"; import "google/protobuf/wrappers.proto"; // Service to trigger A2DP (Advanced Audio Distribution Profile) procedures. // Service to trigger A2DP (Advanced Audio Distribution Profile) procedures. // // Loading Loading @@ -86,7 +85,7 @@ enum AudioEncoding { message Source { message Source { // Opaque value filled by the GRPC server, must not // Opaque value filled by the GRPC server, must not // be modified nor crafted. // be modified nor crafted. bytes cookie = 1; Connection connection = 1; } } // A Token representing a Sink stream (see [A2DP] 2.2). // A Token representing a Sink stream (see [A2DP] 2.2). Loading @@ -94,7 +93,7 @@ message Source { message Sink { message Sink { // Opaque value filled by the GRPC server, must not // Opaque value filled by the GRPC server, must not // be modified nor crafted. // be modified nor crafted. bytes cookie = 1; Connection connection = 1; } } // Request for the `OpenSource` method. // Request for the `OpenSource` method. Loading android/pandora/server/src/com/android/pandora/A2dp.kt +21 −26 Original line number Original line Diff line number Diff line Loading @@ -97,9 +97,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<OpenSourceResponse> responseObserver: StreamObserver<OpenSourceResponse> ) { ) { grpcUnary<OpenSourceResponse>(scope, responseObserver) { grpcUnary<OpenSourceResponse>(scope, responseObserver) { val address = request.connection.cookie.toByteArray().decodeToString() val device = request.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "openSource: device=$device") Log.i(TAG, "openSource: address=$address") if (device.getBondState() != BluetoothDevice.BOND_BONDED) { if (device.getBondState() != BluetoothDevice.BOND_BONDED) { Log.e(TAG, "Device is not bonded, cannot openSource") Log.e(TAG, "Device is not bonded, cannot openSource") Loading @@ -111,6 +110,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val state = val state = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .filter { .filter { it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED Loading @@ -126,7 +126,7 @@ class A2dp(val context: Context) : A2DPImplBase() { // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. delay(2000L) delay(2000L) val source = Source.newBuilder().setCookie(request.connection.cookie).build() val source = Source.newBuilder().setConnection(request.connection).build() OpenSourceResponse.newBuilder().setSource(source).build() OpenSourceResponse.newBuilder().setSource(source).build() } } } } Loading @@ -136,9 +136,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<WaitSourceResponse> responseObserver: StreamObserver<WaitSourceResponse> ) { ) { grpcUnary<WaitSourceResponse>(scope, responseObserver) { grpcUnary<WaitSourceResponse>(scope, responseObserver) { val address = request.connection.cookie.toByteArray().decodeToString() val device = request.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "waitSource: device=$device") Log.i(TAG, "waitSource: address=$address") if (device.getBondState() != BluetoothDevice.BOND_BONDED) { if (device.getBondState() != BluetoothDevice.BOND_BONDED) { Log.e(TAG, "Device is not bonded, cannot openSource") Log.e(TAG, "Device is not bonded, cannot openSource") Loading @@ -149,6 +148,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val state = val state = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .filter { .filter { it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED Loading @@ -164,7 +164,7 @@ class A2dp(val context: Context) : A2DPImplBase() { // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. delay(2000L) delay(2000L) val source = Source.newBuilder().setCookie(request.connection.cookie).build() val source = Source.newBuilder().setConnection(request.connection).build() WaitSourceResponse.newBuilder().setSource(source).build() WaitSourceResponse.newBuilder().setSource(source).build() } } } } Loading @@ -174,9 +174,8 @@ class A2dp(val context: Context) : A2DPImplBase() { if (audioTrack == null) { if (audioTrack == null) { audioTrack = buildAudioTrack() audioTrack = buildAudioTrack() } } val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "start: device=$device") Log.i(TAG, "start: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot start") Log.e(TAG, "Device is not connected, cannot start") Loading @@ -189,7 +188,7 @@ class A2dp(val context: Context) : A2DPImplBase() { if (!bluetoothA2dp.isA2dpPlaying(device)) { if (!bluetoothA2dp.isA2dpPlaying(device)) { flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra().address == address } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .filter { it == BluetoothA2dp.STATE_PLAYING } .filter { it == BluetoothA2dp.STATE_PLAYING } .first() .first() Loading @@ -200,9 +199,8 @@ class A2dp(val context: Context) : A2DPImplBase() { override fun suspend(request: SuspendRequest, responseObserver: StreamObserver<SuspendResponse>) { override fun suspend(request: SuspendRequest, responseObserver: StreamObserver<SuspendResponse>) { grpcUnary<SuspendResponse>(scope, responseObserver) { grpcUnary<SuspendResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "suspend: device=$device") Log.i(TAG, "suspend: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot suspend") Log.e(TAG, "Device is not connected, cannot suspend") Loading @@ -217,7 +215,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val a2dpPlayingStateFlow = val a2dpPlayingStateFlow = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra().address == address } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } audioTrack!!.pause() audioTrack!!.pause() Loading @@ -231,9 +229,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<IsSuspendedResponse> responseObserver: StreamObserver<IsSuspendedResponse> ) { ) { grpcUnary<IsSuspendedResponse>(scope, responseObserver) { grpcUnary<IsSuspendedResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "isSuspended: device=$device") Log.i(TAG, "isSuspended: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot get suspend state") Log.e(TAG, "Device is not connected, cannot get suspend state") Loading @@ -247,9 +244,8 @@ class A2dp(val context: Context) : A2DPImplBase() { override fun close(request: CloseRequest, responseObserver: StreamObserver<CloseResponse>) { override fun close(request: CloseRequest, responseObserver: StreamObserver<CloseResponse>) { grpcUnary<CloseResponse>(scope, responseObserver) { grpcUnary<CloseResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "close: device=$device") Log.i(TAG, "close: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot close") Log.e(TAG, "Device is not connected, cannot close") Loading @@ -259,7 +255,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val a2dpConnectionStateChangedFlow = val a2dpConnectionStateChangedFlow = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra().address == address } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } bluetoothA2dp.disconnect(device) bluetoothA2dp.disconnect(device) Loading Loading @@ -322,9 +318,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<GetAudioEncodingResponse> responseObserver: StreamObserver<GetAudioEncodingResponse> ) { ) { grpcUnary<GetAudioEncodingResponse>(scope, responseObserver) { grpcUnary<GetAudioEncodingResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "getAudioEncoding: device=$device") Log.i(TAG, "getAudioEncoding: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot getAudioEncoding") Log.e(TAG, "Device is not connected, cannot getAudioEncoding") Loading Loading
android/pandora/server/proto/pandora/a2dp.proto +2 −3 Original line number Original line Diff line number Diff line Loading @@ -5,7 +5,6 @@ option java_outer_classname = "A2dpProto"; package pandora; package pandora; import "pandora/host.proto"; import "pandora/host.proto"; import "google/protobuf/wrappers.proto"; // Service to trigger A2DP (Advanced Audio Distribution Profile) procedures. // Service to trigger A2DP (Advanced Audio Distribution Profile) procedures. // // Loading Loading @@ -86,7 +85,7 @@ enum AudioEncoding { message Source { message Source { // Opaque value filled by the GRPC server, must not // Opaque value filled by the GRPC server, must not // be modified nor crafted. // be modified nor crafted. bytes cookie = 1; Connection connection = 1; } } // A Token representing a Sink stream (see [A2DP] 2.2). // A Token representing a Sink stream (see [A2DP] 2.2). Loading @@ -94,7 +93,7 @@ message Source { message Sink { message Sink { // Opaque value filled by the GRPC server, must not // Opaque value filled by the GRPC server, must not // be modified nor crafted. // be modified nor crafted. bytes cookie = 1; Connection connection = 1; } } // Request for the `OpenSource` method. // Request for the `OpenSource` method. Loading
android/pandora/server/src/com/android/pandora/A2dp.kt +21 −26 Original line number Original line Diff line number Diff line Loading @@ -97,9 +97,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<OpenSourceResponse> responseObserver: StreamObserver<OpenSourceResponse> ) { ) { grpcUnary<OpenSourceResponse>(scope, responseObserver) { grpcUnary<OpenSourceResponse>(scope, responseObserver) { val address = request.connection.cookie.toByteArray().decodeToString() val device = request.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "openSource: device=$device") Log.i(TAG, "openSource: address=$address") if (device.getBondState() != BluetoothDevice.BOND_BONDED) { if (device.getBondState() != BluetoothDevice.BOND_BONDED) { Log.e(TAG, "Device is not bonded, cannot openSource") Log.e(TAG, "Device is not bonded, cannot openSource") Loading @@ -111,6 +110,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val state = val state = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .filter { .filter { it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED Loading @@ -126,7 +126,7 @@ class A2dp(val context: Context) : A2DPImplBase() { // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. delay(2000L) delay(2000L) val source = Source.newBuilder().setCookie(request.connection.cookie).build() val source = Source.newBuilder().setConnection(request.connection).build() OpenSourceResponse.newBuilder().setSource(source).build() OpenSourceResponse.newBuilder().setSource(source).build() } } } } Loading @@ -136,9 +136,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<WaitSourceResponse> responseObserver: StreamObserver<WaitSourceResponse> ) { ) { grpcUnary<WaitSourceResponse>(scope, responseObserver) { grpcUnary<WaitSourceResponse>(scope, responseObserver) { val address = request.connection.cookie.toByteArray().decodeToString() val device = request.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "waitSource: device=$device") Log.i(TAG, "waitSource: address=$address") if (device.getBondState() != BluetoothDevice.BOND_BONDED) { if (device.getBondState() != BluetoothDevice.BOND_BONDED) { Log.e(TAG, "Device is not bonded, cannot openSource") Log.e(TAG, "Device is not bonded, cannot openSource") Loading @@ -149,6 +148,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val state = val state = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothAdapter.ERROR) } .filter { .filter { it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED it == BluetoothProfile.STATE_CONNECTED || it == BluetoothProfile.STATE_DISCONNECTED Loading @@ -164,7 +164,7 @@ class A2dp(val context: Context) : A2DPImplBase() { // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. // TODO: b/234891800, AVDTP start request sometimes never sent if playback starts too early. delay(2000L) delay(2000L) val source = Source.newBuilder().setCookie(request.connection.cookie).build() val source = Source.newBuilder().setConnection(request.connection).build() WaitSourceResponse.newBuilder().setSource(source).build() WaitSourceResponse.newBuilder().setSource(source).build() } } } } Loading @@ -174,9 +174,8 @@ class A2dp(val context: Context) : A2DPImplBase() { if (audioTrack == null) { if (audioTrack == null) { audioTrack = buildAudioTrack() audioTrack = buildAudioTrack() } } val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "start: device=$device") Log.i(TAG, "start: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot start") Log.e(TAG, "Device is not connected, cannot start") Loading @@ -189,7 +188,7 @@ class A2dp(val context: Context) : A2DPImplBase() { if (!bluetoothA2dp.isA2dpPlaying(device)) { if (!bluetoothA2dp.isA2dpPlaying(device)) { flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra().address == address } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .filter { it == BluetoothA2dp.STATE_PLAYING } .filter { it == BluetoothA2dp.STATE_PLAYING } .first() .first() Loading @@ -200,9 +199,8 @@ class A2dp(val context: Context) : A2DPImplBase() { override fun suspend(request: SuspendRequest, responseObserver: StreamObserver<SuspendResponse>) { override fun suspend(request: SuspendRequest, responseObserver: StreamObserver<SuspendResponse>) { grpcUnary<SuspendResponse>(scope, responseObserver) { grpcUnary<SuspendResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "suspend: device=$device") Log.i(TAG, "suspend: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot suspend") Log.e(TAG, "Device is not connected, cannot suspend") Loading @@ -217,7 +215,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val a2dpPlayingStateFlow = val a2dpPlayingStateFlow = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra().address == address } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } audioTrack!!.pause() audioTrack!!.pause() Loading @@ -231,9 +229,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<IsSuspendedResponse> responseObserver: StreamObserver<IsSuspendedResponse> ) { ) { grpcUnary<IsSuspendedResponse>(scope, responseObserver) { grpcUnary<IsSuspendedResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "isSuspended: device=$device") Log.i(TAG, "isSuspended: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot get suspend state") Log.e(TAG, "Device is not connected, cannot get suspend state") Loading @@ -247,9 +244,8 @@ class A2dp(val context: Context) : A2DPImplBase() { override fun close(request: CloseRequest, responseObserver: StreamObserver<CloseResponse>) { override fun close(request: CloseRequest, responseObserver: StreamObserver<CloseResponse>) { grpcUnary<CloseResponse>(scope, responseObserver) { grpcUnary<CloseResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "close: device=$device") Log.i(TAG, "close: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot close") Log.e(TAG, "Device is not connected, cannot close") Loading @@ -259,7 +255,7 @@ class A2dp(val context: Context) : A2DPImplBase() { val a2dpConnectionStateChangedFlow = val a2dpConnectionStateChangedFlow = flow flow .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getAction() == BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED } .filter { it.getBluetoothDeviceExtra().address == address } .filter { it.getBluetoothDeviceExtra() == device } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) } bluetoothA2dp.disconnect(device) bluetoothA2dp.disconnect(device) Loading Loading @@ -322,9 +318,8 @@ class A2dp(val context: Context) : A2DPImplBase() { responseObserver: StreamObserver<GetAudioEncodingResponse> responseObserver: StreamObserver<GetAudioEncodingResponse> ) { ) { grpcUnary<GetAudioEncodingResponse>(scope, responseObserver) { grpcUnary<GetAudioEncodingResponse>(scope, responseObserver) { val address = request.source.cookie.toByteArray().decodeToString() val device = request.source.connection.toBluetoothDevice(bluetoothAdapter) val device = bluetoothAdapter.getRemoteDevice(address) Log.i(TAG, "getAudioEncoding: device=$device") Log.i(TAG, "getAudioEncoding: address=$address") if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { if (bluetoothA2dp.getConnectionState(device) != BluetoothA2dp.STATE_CONNECTED) { Log.e(TAG, "Device is not connected, cannot getAudioEncoding") Log.e(TAG, "Device is not connected, cannot getAudioEncoding") Loading