Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ed0ba32 authored by Thomas Girardier's avatar Thomas Girardier Committed by Automerger Merge Worker
Browse files

Merge "PTS-bot: Build AudioTrack at first Start" am: 32be2d35 am: c8252f92

parents 798b5691 c8252f92
Loading
Loading
Loading
Loading
+37 −29
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.media.*
import android.util.Log
import pandora.A2DPGrpc.A2DPImplBase
import pandora.A2dpProto.*
import io.grpc.Status
import io.grpc.stub.StreamObserver
import kotlinx.coroutines.CoroutineScope
@@ -40,6 +38,8 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import pandora.A2DPGrpc.A2DPImplBase
import pandora.A2dpProto.*

@kotlinx.coroutines.ExperimentalCoroutinesApi
class A2dp(val context: Context) : A2DPImplBase() {
@@ -56,7 +56,24 @@ class A2dp(val context: Context) : A2DPImplBase() {
  private val bluetoothAdapter = bluetoothManager.adapter
  private val bluetoothA2dp = getProfileProxy<BluetoothA2dp>(context, BluetoothProfile.A2DP)

  private val audioTrack: AudioTrack =
  private var audioTrack: AudioTrack? = null

  init {
    scope = CoroutineScope(Dispatchers.Default)
    val intentFilter = IntentFilter()
    intentFilter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)
    intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)

    flow = intentFlow(context, intentFilter).shareIn(scope, SharingStarted.Eagerly)
  }

  fun deinit() {
    bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, bluetoothA2dp)
    scope.cancel()
  }

  fun buildAudioTrack(): AudioTrack? {
    audioTrack =
      AudioTrack.Builder()
        .setAudioAttributes(
          AudioAttributes.Builder()
@@ -74,19 +91,7 @@ class A2dp(val context: Context) : A2DPImplBase() {
        .setTransferMode(AudioTrack.MODE_STREAM)
        .setBufferSizeInBytes(44100 * 2 * 2)
        .build()

  init {
    scope = CoroutineScope(Dispatchers.Default)
    val intentFilter = IntentFilter()
    intentFilter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)
    intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)

    flow = intentFlow(context, intentFilter).shareIn(scope, SharingStarted.Eagerly)
  }

  fun deinit() {
    bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, bluetoothA2dp)
    scope.cancel()
    return audioTrack
  }

  override fun openSource(
@@ -168,6 +173,9 @@ class A2dp(val context: Context) : A2DPImplBase() {

  override fun start(request: StartRequest, responseObserver: StreamObserver<StartResponse>) {
    grpcUnary<StartResponse>(scope, responseObserver) {
      if (audioTrack == null) {
        audioTrack = buildAudioTrack()
      }
      val address = request.source.cookie.toByteArray().decodeToString()
      val device = bluetoothAdapter.getRemoteDevice(address)
      Log.i(TAG, "start: address=$address")
@@ -177,7 +185,7 @@ class A2dp(val context: Context) : A2DPImplBase() {
        throw Status.UNKNOWN.asException()
      }

      audioTrack.play()
      audioTrack!!.play()

      // If A2dp is not already playing, wait for it
      if (!bluetoothA2dp.isA2dpPlaying(device)) {
@@ -218,7 +226,7 @@ class A2dp(val context: Context) : A2DPImplBase() {
          }
          .map { it.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothAdapter.ERROR) }

      audioTrack.pause()
      audioTrack!!.pause()
      a2dpPlayingStateFlow.filter { it == BluetoothA2dp.STATE_NOT_PLAYING }.first()
      SuspendResponse.getDefaultInstance()
    }
@@ -274,8 +282,10 @@ class A2dp(val context: Context) : A2DPImplBase() {
  ): StreamObserver<PlaybackAudioRequest> {
    Log.i(TAG, "playbackAudio")

    if (audioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
      responseObserver.onError(Status.UNKNOWN.withDescription("AudioTrack is not started").asException())
    if (audioTrack!!.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
      responseObserver.onError(
        Status.UNKNOWN.withDescription("AudioTrack is not started").asException()
      )
    }

    // Volume is maxed out to avoid any amplitude modification of the provided audio data,
@@ -297,9 +307,7 @@ class A2dp(val context: Context) : A2DPImplBase() {
    return object : StreamObserver<PlaybackAudioRequest> {
      override fun onNext(request: PlaybackAudioRequest) {
        val data = request.data.toByteArray()
        val written = synchronized(audioTrack) {
          audioTrack.write(data, 0, data.size)
        }
        val written = synchronized(audioTrack!!) { audioTrack!!.write(data, 0, data.size) }
        if (written != data.size) {
          responseObserver.onError(
            Status.UNKNOWN.withDescription("AudioTrack write failed").asException()
+3 −3
Original line number Diff line number Diff line
@@ -24,8 +24,6 @@ import android.content.Intent
import android.content.IntentFilter
import android.net.MacAddress
import android.util.Log
import pandora.HostGrpc.HostImplBase
import pandora.HostProto.*
import com.google.protobuf.ByteString
import com.google.protobuf.Empty
import io.grpc.Status
@@ -41,6 +39,8 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import pandora.HostGrpc.HostImplBase
import pandora.HostProto.*

@kotlinx.coroutines.ExperimentalCoroutinesApi
class Host(private val context: Context, private val server: Server) : HostImplBase() {
+13 −13

File changed.

Contains only whitespace changes.