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

Commit 9afa0243 authored by Hyundo Moon's avatar Hyundo Moon
Browse files

Use aggressive initial connection params

This CL makes the stack use aggressive initial connection
parameters when there are less than 2 ongoing ACL connections.

Bug: 308483803
Bug: 378595485
Flag: com.android.bluetooth.flags.initial_conn_params_p1
Test: atest LeImplTest
Test: atest GattClientTest
Test: Manual, checked aggressive params are used for first connection,
      and relaxed params are used from the third connection.
Test: Manual, checked that paramters are relaxed after service
      discovery. Also for the case when the service discovery is
      skipped.
Test: Manual, made GATT connection while music is playing via A2DP/ASHA.
      The music was continously playing while service discovery.
Test: Manual, had a Wifi traffic and phone call with HFP/ASHA.
      The phone call has no noticable sound errors.
Change-Id: Idd8cac01f67e4dd797487fad87781fddb5ce73d3
parent 28ef7557
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