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

Commit cc40ff40 authored by Thomas Girardier's avatar Thomas Girardier Committed by Gerrit Code Review
Browse files

Merge "Pandora: Add ResetBluetooth to Host"

parents 80d7c5f7 553c471e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ class IUT:
        # Note: we don't keep a single gRPC channel instance in the IUT class
        # because reset is allowed to close the gRPC server.
        with grpc.insecure_channel(f'localhost:{self.port}') as channel:
            self._retry(Host(channel).Reset)(wait_for_ready=True)
            self._retry(Host(channel).HardReset)(wait_for_ready=True)

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self._a2dp = None
+8 −5
Original line number Diff line number Diff line
@@ -11,13 +11,16 @@ import "google/protobuf/empty.proto";
// At startup, the Host must be in BR/EDR connectable mode
// (see GAP connectability modes)
service Host {
  // Reset the host.
  // **After** responding to this command, the GRPC server should loose
  // Hard reset the host.
  // **After** responding to this command, the gRPC server should loose
  // all its state.
  // This is comparable to a process restart or an hardware reset.
  // The GRPC server might take some time to be available after
  // The gRPC server might take some time to be available after
  // this command.
  rpc Reset(google.protobuf.Empty) returns (google.protobuf.Empty);
  rpc HardReset(google.protobuf.Empty) returns (google.protobuf.Empty);
  // Soft reset the host by performing an HCI reset. Previous bonds must
  // not be removed and the gRPC server must not be restarted.
  rpc SoftReset(google.protobuf.Empty) returns (google.protobuf.Empty);
  // Read the local Bluetooth device address.
  // This should return the same value as a Read BD_ADDR HCI command.
  rpc ReadLocalAddress(google.protobuf.Empty) returns (ReadLocalAddressResponse);
@@ -56,7 +59,7 @@ message ReadLocalAddressResponse {
// A Token representing an ACL connection.
// It's acquired via a Connect on the Host service.
message Connection {
  // Opaque value filled by the GRPC server, must not
  // Opaque value filled by the gRPC server, must not
  // be modified nor crafted.
  bytes cookie = 1;
}
+44 −30
Original line number Diff line number Diff line
@@ -35,17 +35,17 @@ import io.grpc.stub.StreamObserver
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.runBlocking
import pandora.HostGrpc.HostImplBase
import pandora.HostProto.*
@@ -80,16 +80,13 @@ class Host(private val context: Context, private val server: Server) : HostImplB
    scope.cancel()
  }

  override fun reset(request: Empty, responseObserver: StreamObserver<Empty>) {
    grpcUnary<Empty>(scope, responseObserver) {
        Log.i(TAG, "reset")

        bluetoothAdapter.clearBluetooth()
  private suspend fun rebootBluetooth() {
    Log.i(TAG, "rebootBluetooth")

    val stateFlow =
          flow
            .filter { it.getAction() == BluetoothAdapter.ACTION_STATE_CHANGED }
            .map { it.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) }
      flow.filter { it.getAction() == BluetoothAdapter.ACTION_STATE_CHANGED }.map {
        it.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
      }

    if (bluetoothAdapter.isEnabled) {
      bluetoothAdapter.disable()
@@ -101,6 +98,15 @@ class Host(private val context: Context, private val server: Server) : HostImplB

    bluetoothAdapter.enable()
    stateFlow.filter { it == BluetoothAdapter.STATE_ON }.first()
  }

  override fun hardReset(request: Empty, responseObserver: StreamObserver<Empty>) {
    grpcUnary<Empty>(scope, responseObserver) {
      Log.i(TAG, "hardReset")

      bluetoothAdapter.clearBluetooth()

      rebootBluetooth()

      // The last expression is the return value.
      Empty.getDefaultInstance()
@@ -111,6 +117,16 @@ class Host(private val context: Context, private val server: Server) : HostImplB
      }
  }

  override fun softReset(request: Empty, responseObserver: StreamObserver<Empty>) {
    grpcUnary<Empty>(scope, responseObserver) {
      Log.i(TAG, "softReset")

      rebootBluetooth()

      Empty.getDefaultInstance()
    }
  }

  override fun readLocalAddress(
    request: Empty,
    responseObserver: StreamObserver<ReadLocalAddressResponse>
@@ -279,9 +295,7 @@ class Host(private val context: Context, private val server: Server) : HostImplB
      GattInstance(device!!, TRANSPORT_LE, context).waitForState(BluetoothProfile.STATE_CONNECTED)
      ConnectLEResponse.newBuilder()
        .setConnection(
          Connection.newBuilder()
            .setCookie(ByteString.copyFromUtf8(device.address))
            .build()
          Connection.newBuilder().setCookie(ByteString.copyFromUtf8(device.address)).build()
        )
        .build()
    }
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ class ExampleTest(base_test.BaseTestClass):
        self.ref = self.pandora_devices[1]

    def setup_test(self):
        self.dut.host.Reset()
        self.dut.host.HardReset()
        # TODO: wait for server
        time.sleep(3)