Commit d9dac6e9 authored by Michael Hansen's avatar Michael Hansen Committed by Commit Bot

[Nearby] Implement BluetoothAdvertisingIntervalClient.

This CL implements the BluetoothAdvertisingIntervalClient which will set
the advertising interval for Nearby Sharing. It will also handle
restoring the default advertising interval when advertising stops.

Bug: 1119970
Change-Id: Ia4c0febed23dcd751f9e72dace37dd7069b3f33e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2466263Reviewed-by: default avatarJosh Nohle <nohle@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Reviewed-by: default avatarRyan Hansberry <hansberry@chromium.org>
Commit-Queue: Michael Hansen <hansenmichael@google.com>
Cr-Commit-Position: refs/heads/master@{#818633}
parent 5405ba98
......@@ -4159,6 +4159,8 @@ static_library("browser") {
"metrics/perf/windowed_incognito_observer.h",
"nearby_sharing/attachment_info.cc",
"nearby_sharing/attachment_info.h",
"nearby_sharing/bluetooth_advertising_interval_client.cc",
"nearby_sharing/bluetooth_advertising_interval_client.h",
"nearby_sharing/constants.h",
"nearby_sharing/fast_initiation_manager.cc",
"nearby_sharing/fast_initiation_manager.h",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/nearby_sharing/bluetooth_advertising_interval_client.h"
#include <utility>
#include "base/bind_helpers.h"
#include "base/time/time.h"
#include "chrome/browser/nearby_sharing/logging/logging.h"
#include "device/bluetooth/bluetooth_adapter.h"
namespace {
constexpr base::TimeDelta kIntervalMin = base::TimeDelta::FromMilliseconds(100);
constexpr base::TimeDelta kIntervalMax = base::TimeDelta::FromMilliseconds(100);
// A value of 0 will restore the interval to the system default.
constexpr base::TimeDelta kDefaultIntervalMin =
base::TimeDelta::FromMilliseconds(0);
constexpr base::TimeDelta kDefaultIntervalMax =
base::TimeDelta::FromMilliseconds(0);
} // namespace
BluetoothAdvertisingIntervalClient::BluetoothAdvertisingIntervalClient(
scoped_refptr<device::BluetoothAdapter> adapter)
: adapter_(adapter) {}
BluetoothAdvertisingIntervalClient::~BluetoothAdvertisingIntervalClient() {
RestoreDefaultInterval();
}
void BluetoothAdvertisingIntervalClient::ReduceInterval(
base::OnceClosure callback,
base::OnceClosure error_callback) {
adapter_->SetAdvertisingInterval(
kIntervalMin, kIntervalMax, std::move(callback),
base::BindOnce(
&BluetoothAdvertisingIntervalClient::OnSetIntervalForAdvertisingError,
weak_ptr_factory_.GetWeakPtr(), std::move(error_callback)));
}
void BluetoothAdvertisingIntervalClient::RestoreDefaultInterval() {
adapter_->SetAdvertisingInterval(
kDefaultIntervalMin, kDefaultIntervalMax, base::DoNothing(),
base::BindOnce(
&BluetoothAdvertisingIntervalClient::OnRestoreDefaultIntervalError,
weak_ptr_factory_.GetWeakPtr()));
}
void BluetoothAdvertisingIntervalClient::OnSetIntervalForAdvertisingError(
base::OnceClosure error_callback,
device::BluetoothAdvertisement::ErrorCode code) {
NS_LOG(WARNING) << __func__
<< "SetAdvertisingInterval() failed with error code = "
<< code;
std::move(error_callback).Run();
}
void BluetoothAdvertisingIntervalClient::OnRestoreDefaultIntervalError(
device::BluetoothAdvertisement::ErrorCode code) {
NS_LOG(WARNING) << __func__
<< "SetAdvertisingInterval() failed with error code = "
<< code;
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_NEARBY_SHARING_BLUETOOTH_ADVERTISING_INTERVAL_CLIENT_H_
#define CHROME_BROWSER_NEARBY_SHARING_BLUETOOTH_ADVERTISING_INTERVAL_CLIENT_H_
#include <memory>
#include "base/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "device/bluetooth/bluetooth_advertisement.h"
namespace device {
class BluetoothAdapter;
} // namespace device
// BluetoothAdvertisingIntervalClient is responsible for setting the Bluetooth
// advertising interval to a lower value when we start advertising for Nearby
// Share, and then restores the interval to the system default when advertising
// stops.
class BluetoothAdvertisingIntervalClient {
public:
BluetoothAdvertisingIntervalClient(
scoped_refptr<device::BluetoothAdapter> adapter);
~BluetoothAdvertisingIntervalClient();
// Sets the advertising interval to a lowered value to allow for faster
// connections.
void ReduceInterval(base::OnceClosure callback,
base::OnceClosure error_callback);
// Restores the advertising interval to the system default.
void RestoreDefaultInterval();
private:
void OnSetIntervalForAdvertisingError(
base::OnceClosure error_callback,
device::BluetoothAdvertisement::ErrorCode code);
void OnRestoreDefaultIntervalError(
device::BluetoothAdvertisement::ErrorCode code);
scoped_refptr<device::BluetoothAdapter> adapter_;
base::WeakPtrFactory<BluetoothAdvertisingIntervalClient> weak_ptr_factory_{
this};
};
#endif // CHROME_BROWSER_NEARBY_SHARING_BLUETOOTH_ADVERTISING_INTERVAL_CLIENT_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/nearby_sharing/bluetooth_advertising_interval_client.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
using ::testing::_;
using testing::NiceMock;
namespace {
const int64_t kInterval = 100;
const int64_t kDefaultInterval = 0;
} // namespace
class MockBluetoothAdapterWithInterval : public device::MockBluetoothAdapter {
public:
MOCK_METHOD2(OnSetAdvertisingInterval, void(int64_t, int64_t));
MOCK_METHOD0(OnSetAdvertisingIntervalError, void());
void SetAdvertisingInterval(
const base::TimeDelta& min,
const base::TimeDelta& max,
base::OnceClosure callback,
AdvertisementErrorCallback error_callback) override {
if (set_advertising_interval_error_) {
std::move(error_callback)
.Run(device::BluetoothAdvertisement::ErrorCode::
ERROR_INVALID_ADVERTISEMENT_INTERVAL);
OnSetAdvertisingIntervalError();
} else {
std::move(callback).Run();
OnSetAdvertisingInterval(min.InMilliseconds(), max.InMilliseconds());
}
}
void SetAdvertisingIntervalError(bool error) {
set_advertising_interval_error_ = error;
}
protected:
~MockBluetoothAdapterWithInterval() override = default;
bool set_advertising_interval_error_ = false;
};
class BluetoothAdvertisingIntervalClientTest : public testing::Test {
protected:
void SetUp() override {
mock_adapter_ =
base::MakeRefCounted<NiceMock<MockBluetoothAdapterWithInterval>>();
ON_CALL(*mock_adapter_, OnSetAdvertisingInterval(_, _))
.WillByDefault(Invoke(
this,
&BluetoothAdvertisingIntervalClientTest::OnSetAdvertisingInterval));
ON_CALL(*mock_adapter_, OnSetAdvertisingIntervalError())
.WillByDefault(Invoke(this, &BluetoothAdvertisingIntervalClientTest::
OnSetAdvertisingIntervalError));
client_ =
std::make_unique<BluetoothAdvertisingIntervalClient>(mock_adapter_);
}
void SetAdvertisingInterval() {
client_->ReduceInterval(
base::BindOnce(&BluetoothAdvertisingIntervalClientTest::
OnSetAdvertisingIntervalCallback,
base::Unretained(this)),
base::BindOnce(&BluetoothAdvertisingIntervalClientTest::
OnSetAdvertisingIntervalErrorCallback,
base::Unretained(this)));
}
void OnSetAdvertisingInterval(int64_t min, int64_t max) {
++set_advertising_interval_call_count_;
last_advertising_interval_min_ = min;
last_advertising_interval_max_ = max;
}
void OnSetAdvertisingIntervalError() {
++set_advertising_interval_error_call_count_;
}
void OnSetAdvertisingIntervalCallback() {
++set_advertising_interval_callback_call_count_;
}
void OnSetAdvertisingIntervalErrorCallback() {
++set_advertising_interval_error_callback_call_count_;
}
void RestoreDefaultInterval() { client_->RestoreDefaultInterval(); }
const size_t set_advertising_interval_call_count() {
return set_advertising_interval_call_count_;
}
const size_t set_advertising_interval_error_call_count() {
return set_advertising_interval_error_call_count_;
}
const size_t set_advertising_interval_callback_call_count() {
return set_advertising_interval_callback_call_count_;
}
const size_t set_advertising_interval_error_callback_call_count() {
return set_advertising_interval_error_callback_call_count_;
}
const int64_t last_advertising_interval_min() {
return last_advertising_interval_min_;
}
const int64_t last_advertising_interval_max() {
return last_advertising_interval_max_;
}
scoped_refptr<NiceMock<MockBluetoothAdapterWithInterval>> mock_adapter_;
std::unique_ptr<BluetoothAdvertisingIntervalClient> client_;
size_t set_advertising_interval_call_count_ = 0u;
size_t set_advertising_interval_error_call_count_ = 0u;
size_t set_advertising_interval_callback_call_count_ = 0u;
size_t set_advertising_interval_error_callback_call_count_ = 0u;
int64_t last_advertising_interval_min_ = 0;
int64_t last_advertising_interval_max_ = 0;
};
TEST_F(BluetoothAdvertisingIntervalClientTest, SetAndRestore) {
SetAdvertisingInterval();
EXPECT_EQ(1, set_advertising_interval_call_count());
EXPECT_EQ(0, set_advertising_interval_error_call_count());
EXPECT_EQ(1, set_advertising_interval_callback_call_count());
EXPECT_EQ(0, set_advertising_interval_error_callback_call_count());
EXPECT_EQ(kInterval, last_advertising_interval_min());
EXPECT_EQ(kInterval, last_advertising_interval_max());
RestoreDefaultInterval();
EXPECT_EQ(2, set_advertising_interval_call_count());
EXPECT_EQ(0, set_advertising_interval_error_call_count());
EXPECT_EQ(0, set_advertising_interval_error_callback_call_count());
EXPECT_EQ(kDefaultInterval, last_advertising_interval_min());
EXPECT_EQ(kDefaultInterval, last_advertising_interval_max());
}
TEST_F(BluetoothAdvertisingIntervalClientTest, SetError) {
mock_adapter_->SetAdvertisingIntervalError(true);
SetAdvertisingInterval();
EXPECT_EQ(0, set_advertising_interval_call_count());
EXPECT_EQ(1, set_advertising_interval_error_call_count());
EXPECT_EQ(0, set_advertising_interval_callback_call_count());
EXPECT_EQ(1, set_advertising_interval_error_callback_call_count());
}
......@@ -4838,6 +4838,7 @@ test("unit_tests") {
"../browser/metrics/perf/process_type_collector_unittest.cc",
"../browser/metrics/perf/profile_provider_chromeos_unittest.cc",
"../browser/metrics/perf/windowed_incognito_observer_unittest.cc",
"../browser/nearby_sharing/bluetooth_advertising_interval_client_unittest.cc",
"../browser/nearby_sharing/fake_nearby_connection.cc",
"../browser/nearby_sharing/fake_nearby_connection.h",
"../browser/nearby_sharing/fake_nearby_connections_manager.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment