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

Commit c55eb6ca authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Use aggressive initial connection params" into main

parents dd5dbfd7 9afa0243
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify;

import android.bluetooth.test_utils.EnableBluetoothRule;
import android.content.Context;
import android.os.SystemProperties;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -93,6 +94,11 @@ public class GattClientTest {
    private static final UUID TEST_CHARACTERISTIC_UUID =
            UUID.fromString("00010001-0000-0000-0000-000000000000");

    private static final int MIN_CONN_INTERVAL_RELAXED =
            SystemProperties.getInt("bluetooth.core.le.min_connection_interval_relaxed", 0x0018);
    private static final int MAX_CONN_INTERVAL_RELAXED =
            SystemProperties.getInt("bluetooth.core.le.max_connection_interval_relaxed", 0x0028);

    @Rule(order = 0)
    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();

@@ -172,6 +178,31 @@ public class GattClientTest {
        disconnectAndWaitDisconnection(gatt, gattCallback);
    }

    @RequiresFlagsEnabled(Flags.FLAG_INITIAL_CONN_PARAMS_P1)
    @Test
    public void onConnectionUpdatedIsCalledOnlyOnceForRelaxingConnectionParameters_noGattCache() {
        BluetoothGattCallback gattCallback = mock(BluetoothGattCallback.class);
        ArgumentCaptor<Integer> connectionIntervalCaptor = ArgumentCaptor.forClass(Integer.class);

        BluetoothGatt gatt = connectGattAndWaitConnection(gattCallback, false);

        // Wait until service discovery is done and parameters are relaxed.
        verify(gattCallback, timeout(10_000).times(1))
                .onConnectionUpdated(
                        any(), connectionIntervalCaptor.capture(), anyInt(), anyInt(), anyInt());

        List<Integer> capturedConnectionIntervals = connectionIntervalCaptor.getAllValues();
        assertThat(capturedConnectionIntervals).hasSize(1);

        // Since aggressive parameters are used in the initial connection,
        // there should be only one connection parameters update event for relaxing them.
        int relaxedConnIntervalAfterServiceDiscovery = capturedConnectionIntervals.get(0);
        assertThat(relaxedConnIntervalAfterServiceDiscovery).isAtLeast(MIN_CONN_INTERVAL_RELAXED);
        assertThat(relaxedConnIntervalAfterServiceDiscovery).isAtMost(MAX_CONN_INTERVAL_RELAXED);

        disconnectAndWaitDisconnection(gatt, gattCallback);
    }

    @Test
    public void reconnectExistingClient() throws Exception {
        advertiseWithBumble();
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ cc_library_static {
    ],
    srcs: [
        "address_obfuscator.cc",
        "le_conn_params.cc",
        "message_loop_thread.cc",
        "metric_id_allocator.cc",
        "os_utils.cc",
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
static_library("common") {
  sources = [
    "address_obfuscator.cc",
    "le_conn_params.cc",
    "message_loop_thread.cc",
    "metric_id_allocator.cc",
    "metrics_linux.cc",
+142 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "le_conn_params"

#include "common/le_conn_params.h"

#include <bluetooth/log.h>

#include <cstdint>

#include "os/system_properties.h"
#include "stack/include/btm_ble_api_types.h"

using namespace bluetooth;

const std::string LeConnectionParameters::kPropertyAggressiveConnThreshold =
        "bluetooth.core.le.aggressive_connection_threshold";
const std::string LeConnectionParameters::kPropertyMinConnIntervalAggressive =
        "bluetooth.core.le.min_connection_interval_aggressive";
const std::string LeConnectionParameters::kPropertyMaxConnIntervalAggressive =
        "bluetooth.core.le.max_connection_interval_aggressive";
const std::string LeConnectionParameters::kPropertyMinConnIntervalRelaxed =
        "bluetooth.core.le.min_connection_interval_relaxed";
const std::string LeConnectionParameters::kPropertyMaxConnIntervalRelaxed =
        "bluetooth.core.le.max_connection_interval_relaxed";

bool LeConnectionParameters::initialized = false;
uint32_t LeConnectionParameters::aggressive_conn_threshold = kAggressiveConnThreshold;
uint32_t LeConnectionParameters::min_conn_interval_aggressive = kMinConnIntervalAggressive;
uint32_t LeConnectionParameters::max_conn_interval_aggressive = kMaxConnIntervalAggressive;
uint32_t LeConnectionParameters::min_conn_interval_relaxed = kMinConnIntervalRelaxed;
uint32_t LeConnectionParameters::max_conn_interval_relaxed = kMaxConnIntervalRelaxed;

void LeConnectionParameters::InitConnParamsWithSystemProperties() {
  aggressive_conn_threshold =
          os::GetSystemPropertyUint32(kPropertyAggressiveConnThreshold, kAggressiveConnThreshold);
  min_conn_interval_aggressive = os::GetSystemPropertyUint32(kPropertyMinConnIntervalAggressive,
                                                             kMinConnIntervalAggressive);
  max_conn_interval_aggressive = os::GetSystemPropertyUint32(kPropertyMaxConnIntervalAggressive,
                                                             kMaxConnIntervalAggressive);
  min_conn_interval_relaxed =
          os::GetSystemPropertyUint32(kPropertyMinConnIntervalRelaxed, kMinConnIntervalRelaxed);
  max_conn_interval_relaxed =
          os::GetSystemPropertyUint32(kPropertyMaxConnIntervalRelaxed, kMaxConnIntervalRelaxed);

  log::debug("Before checking validity: threshold={}, aggressive={}/{}, relaxed={}/{}",
             aggressive_conn_threshold, min_conn_interval_aggressive, max_conn_interval_aggressive,
             min_conn_interval_relaxed, max_conn_interval_relaxed);

  // Check validity of each values
  if (aggressive_conn_threshold < 0) {
    log::warn("Invalid aggressive connection threshold. Using default value.",
              aggressive_conn_threshold);
    aggressive_conn_threshold = kAggressiveConnThreshold;
  }

  if (min_conn_interval_aggressive < BTM_BLE_CONN_INT_MIN ||
      min_conn_interval_aggressive > BTM_BLE_CONN_INT_MAX ||
      max_conn_interval_aggressive < BTM_BLE_CONN_INT_MIN ||
      max_conn_interval_aggressive > BTM_BLE_CONN_INT_MAX ||
      max_conn_interval_aggressive < min_conn_interval_aggressive) {
    log::warn("Invalid aggressive connection intervals. Using default values.");
    min_conn_interval_aggressive = kMinConnIntervalAggressive;
    max_conn_interval_aggressive = kMaxConnIntervalAggressive;
  }

  if (min_conn_interval_relaxed < BTM_BLE_CONN_INT_MIN ||
      min_conn_interval_relaxed > BTM_BLE_CONN_INT_MAX ||
      max_conn_interval_relaxed < BTM_BLE_CONN_INT_MIN ||
      max_conn_interval_relaxed > BTM_BLE_CONN_INT_MAX ||
      max_conn_interval_relaxed < min_conn_interval_relaxed) {
    log::warn("Invalid relaxed connection intervals. Using default values.");
    min_conn_interval_relaxed = kMinConnIntervalRelaxed;
    max_conn_interval_relaxed = kMaxConnIntervalRelaxed;
  }

  if ((min_conn_interval_aggressive > min_conn_interval_relaxed) &&
      (max_conn_interval_aggressive > max_conn_interval_relaxed)) {
    log::warn(
            "Relaxed connection intervals are more aggressive than aggressive ones."
            " Setting all intervals to default values.");
    min_conn_interval_aggressive = kMinConnIntervalAggressive;
    max_conn_interval_aggressive = kMaxConnIntervalAggressive;
    min_conn_interval_relaxed = kMinConnIntervalRelaxed;
    max_conn_interval_relaxed = kMaxConnIntervalRelaxed;
  }

  log::debug("After checking validity: threshold={}, aggressive={}/{}, relaxed={}/{}",
             aggressive_conn_threshold, min_conn_interval_aggressive, max_conn_interval_aggressive,
             min_conn_interval_relaxed, max_conn_interval_relaxed);

  initialized = true;
}

uint32_t LeConnectionParameters::GetAggressiveConnThreshold() {
  if (!initialized) {
    InitConnParamsWithSystemProperties();
  }
  return aggressive_conn_threshold;
}

uint32_t LeConnectionParameters::GetMinConnIntervalAggressive() {
  if (!initialized) {
    InitConnParamsWithSystemProperties();
  }
  return min_conn_interval_aggressive;
}

uint32_t LeConnectionParameters::GetMaxConnIntervalAggressive() {
  if (!initialized) {
    InitConnParamsWithSystemProperties();
  }
  return max_conn_interval_aggressive;
}

uint32_t LeConnectionParameters::GetMinConnIntervalRelaxed() {
  if (!initialized) {
    InitConnParamsWithSystemProperties();
  }
  return min_conn_interval_relaxed;
}

uint32_t LeConnectionParameters::GetMaxConnIntervalRelaxed() {
  if (!initialized) {
    InitConnParamsWithSystemProperties();
  }
  return max_conn_interval_relaxed;
}
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <bluetooth/log.h>

#include <cstdint>

class LeConnectionParameters {
public:
  static constexpr uint16_t kAggressiveConnThreshold = 2;
  static constexpr uint16_t kMinConnIntervalAggressive = 0x0008;  // 8, *1.25 becomes 10ms
  static constexpr uint16_t kMaxConnIntervalAggressive = 0x0010;  // 16, *1.25 becomes 20ms
  static constexpr uint16_t kMinConnIntervalRelaxed = 0x0018;     // 24, *1.25 becomes 30ms
  static constexpr uint16_t kMaxConnIntervalRelaxed = 0x0028;     // 40, *1.25 becomes 50ms

  static const std::string kPropertyAggressiveConnThreshold;
  static const std::string kPropertyMinConnIntervalAggressive;
  static const std::string kPropertyMaxConnIntervalAggressive;
  static const std::string kPropertyMinConnIntervalRelaxed;
  static const std::string kPropertyMaxConnIntervalRelaxed;

  static void InitConnParamsWithSystemProperties();
  static uint32_t GetAggressiveConnThreshold();
  static uint32_t GetMinConnIntervalAggressive();
  static uint32_t GetMaxConnIntervalAggressive();
  static uint32_t GetMinConnIntervalRelaxed();
  static uint32_t GetMaxConnIntervalRelaxed();

private:
  static bool initialized;
  static uint32_t aggressive_conn_threshold;
  static uint32_t min_conn_interval_aggressive;
  static uint32_t max_conn_interval_aggressive;
  static uint32_t min_conn_interval_relaxed;
  static uint32_t max_conn_interval_relaxed;
};
Loading