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

Commit 6424f29c authored by Greg Kaiser's avatar Greg Kaiser
Browse files

Allow longer init timeout on some devices

Finding the Bluetooth HAL within 0.5 seconds isn't a strict
requirement, but failing to do so will give a slow Bluetooth start
up for users, so we generally want to give an error in that case.

However, some devices have very limited hardware resources
and use lazy HALs for Bluetooth, which can result in us expecting
this to sometimes take longer.

Devices are able to set the ro.hw_timeout_multiplier property to
indicate this.  However, we cap this multiplier at 2, because we
don't have an arbitrary amount of time for Bluetooth startup.

Bug: 285748554, 357043853
Test: m mokey_go32-trunk_staging-userdebug; Confirmed on a slow device with this multiplier set that we're able to take longer than 500ms to init, but still not get an error; compiled a one-off version which introduced a usleep() and confirmed the error message gave the correct number of milliseconds for the timeout.
Flags: EXEMPT for bug fix
Change-Id: Id520cd7ce6a972919a289485a75cba94cbe45057
parent c746b8fc
Loading
Loading
Loading
Loading
+40 −20
Original line number Diff line number Diff line
@@ -87,28 +87,34 @@ class HidlHci : public HciBackend {
public:
  HidlHci(Handler* module_handler) {
    log::info("Trying to find a HIDL interface");
    const int32_t timeout_ms = get_adjusted_timeout(500);

    auto get_service_alarm = new os::Alarm(module_handler);
    get_service_alarm->Schedule(BindOnce([] {
    get_service_alarm->Schedule(
            BindOnce(
                    [](uint32_t timeout_ms) {
                      const std::string kBoardProperty = "ro.product.board";
                      const std::string kCuttlefishBoard = "cutf";
                      auto board_name = os::GetSystemProperty(kBoardProperty);
                                  bool emulator = board_name.has_value() &&
                                                  board_name.value() == kCuttlefishBoard;
                      bool emulator =
                              board_name.has_value() && board_name.value() == kCuttlefishBoard;
                      if (emulator) {
                        log::error("board_name: {}", board_name.value());
                        log::error(
                                            "Unable to get a Bluetooth service after 500ms, start "
                                "Unable to get a Bluetooth service after {}ms, start "
                                "the HAL before starting "
                                            "Bluetooth");
                                "Bluetooth",
                                timeout_ms);
                        return;
                      }
                      log::fatal(
                                          "Unable to get a Bluetooth service after 500ms, start "
                              "Unable to get a Bluetooth service after {}ms, start "
                              "the HAL before starting "
                                          "Bluetooth");
                                }),
                                std::chrono::milliseconds(500));
                              "Bluetooth",
                              timeout_ms);
                    },
                    timeout_ms),
            std::chrono::milliseconds(timeout_ms));

    hci_1_1_ = IBluetoothHci_1_1::getService();
    if (hci_1_1_) {
@@ -167,6 +173,20 @@ public:
  }

private:
  static int32_t get_adjusted_timeout(int32_t timeout) {
    // Slower devices set this property.  While waiting longer for bluetooth
    // is a poor user experience, it's not unexpected on these devices.
    // At the same time, we don't get arbitrarily long to start up bluetooth.
    // There are other, more concretely set timeouts which can get triggered,
    // and having a timeout here helps narrow down the problematic area.
    // As a pragmatic compromise, we cap this multiplier at 2.
    const uint32_t multiplier = os::GetSystemPropertyUint32("ro.hw_timeout_multiplier", 1);
    if (multiplier > 1) {
      return timeout * 2;
    }
    return timeout;
  }

  android::sp<DeathRecipient> death_recipient_;
  android::sp<HidlHciCallbacks> hci_callbacks_;
  android::sp<IBluetoothHci_1_0> hci_;