mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-03 22:31:31 +00:00
Merge changes Ic4fcbb22,I1be8a18d
* changes: Bluetooth: Use AsyncFdWatcher for power management Bluetooth: AsyncFdWatcher: Refactor timeout lock
This commit is contained in:
@@ -140,9 +140,15 @@ void AsyncFdWatcher::ThreadRoutine() {
|
||||
|
||||
// Timeout.
|
||||
if (retval == 0) {
|
||||
std::unique_lock<std::mutex> guard(timeout_mutex_);
|
||||
if (timeout_ms_ > std::chrono::milliseconds(0) && timeout_cb_)
|
||||
timeout_cb_();
|
||||
// Allow the timeout callback to modify the timeout.
|
||||
TimeoutCallback saved_cb;
|
||||
{
|
||||
std::unique_lock<std::mutex> guard(timeout_mutex_);
|
||||
if (timeout_ms_ > std::chrono::milliseconds(0))
|
||||
saved_cb = timeout_cb_;
|
||||
}
|
||||
if (saved_cb != nullptr)
|
||||
saved_cb();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,7 @@ class AsyncFdWatcherSocketTest : public ::testing::Test {
|
||||
int reuse_flag = 1;
|
||||
EXPECT_FALSE(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_flag,
|
||||
sizeof(reuse_flag)) < 0);
|
||||
EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) <
|
||||
0);
|
||||
EXPECT_FALSE(bind(fd, (sockaddr*)&serv_addr, sizeof(serv_addr)) < 0);
|
||||
|
||||
ALOGD("%s before listen", __func__);
|
||||
listen(fd, 1);
|
||||
@@ -81,11 +80,12 @@ class AsyncFdWatcherSocketTest : public ::testing::Test {
|
||||
int n = TEMP_FAILURE_RETRY(read(fd, server_buffer_, kBufferSize - 1));
|
||||
EXPECT_FALSE(n < 0);
|
||||
|
||||
if (n == 0) // got EOF
|
||||
if (n == 0) { // got EOF
|
||||
ALOGD("%s: EOF", __func__);
|
||||
else
|
||||
} else {
|
||||
ALOGD("%s: Got something", __func__);
|
||||
n = write(fd, "1", 1);
|
||||
}
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
@@ -101,7 +101,10 @@ class AsyncFdWatcherSocketTest : public ::testing::Test {
|
||||
int connection_fd = AcceptConnection(fd);
|
||||
ALOGD("%s: Conn_watcher fd = %d", __func__, fd);
|
||||
|
||||
conn_watcher_.ConfigureTimeout(std::chrono::seconds(0), [this]() { bool connection_timeout_cleared = false; ASSERT_TRUE(connection_timeout_cleared); });
|
||||
conn_watcher_.ConfigureTimeout(std::chrono::seconds(0), [this]() {
|
||||
bool connection_timeout_cleared = false;
|
||||
ASSERT_TRUE(connection_timeout_cleared);
|
||||
});
|
||||
|
||||
ALOGD("%s: 3", __func__);
|
||||
async_fd_watcher_.WatchFdForNonBlockingReads(
|
||||
@@ -110,7 +113,10 @@ class AsyncFdWatcherSocketTest : public ::testing::Test {
|
||||
// Time out if it takes longer than a second.
|
||||
SetTimeout(std::chrono::seconds(1));
|
||||
});
|
||||
conn_watcher_.ConfigureTimeout(std::chrono::seconds(1), [this]() { bool connection_timeout = true; ASSERT_FALSE(connection_timeout); });
|
||||
conn_watcher_.ConfigureTimeout(std::chrono::seconds(1), [this]() {
|
||||
bool connection_timeout = true;
|
||||
ASSERT_FALSE(connection_timeout);
|
||||
});
|
||||
}
|
||||
|
||||
void CleanUpServer() {
|
||||
@@ -135,7 +141,7 @@ class AsyncFdWatcherSocketTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
bool TimedOut() {
|
||||
ALOGD("%s %d", __func__, timed_out_? 1 : 0);
|
||||
ALOGD("%s %d", __func__, timed_out_ ? 1 : 0);
|
||||
return timed_out_;
|
||||
}
|
||||
|
||||
@@ -198,8 +204,8 @@ TEST_F(AsyncFdWatcherSocketTest, Connect) {
|
||||
|
||||
// Fail if the client doesn't connect within 1 second.
|
||||
conn_watcher.ConfigureTimeout(std::chrono::seconds(1), [this]() {
|
||||
bool connection_timeout = true;
|
||||
ASSERT_FALSE(connection_timeout);
|
||||
bool connection_timeout = true;
|
||||
ASSERT_FALSE(connection_timeout);
|
||||
});
|
||||
|
||||
ConnectClient();
|
||||
@@ -220,7 +226,8 @@ TEST_F(AsyncFdWatcherSocketTest, TimedOutConnect) {
|
||||
});
|
||||
|
||||
// Set the timeout flag after 100ms.
|
||||
conn_watcher.ConfigureTimeout(std::chrono::milliseconds(100), [this, timeout_ptr]() { *timeout_ptr = true; });
|
||||
conn_watcher.ConfigureTimeout(std::chrono::milliseconds(100),
|
||||
[this, timeout_ptr]() { *timeout_ptr = true; });
|
||||
EXPECT_FALSE(timed_out);
|
||||
sleep(1);
|
||||
EXPECT_TRUE(timed_out);
|
||||
@@ -228,6 +235,38 @@ TEST_F(AsyncFdWatcherSocketTest, TimedOutConnect) {
|
||||
close(socket_fd);
|
||||
}
|
||||
|
||||
// Modify the timeout in a timeout callback.
|
||||
TEST_F(AsyncFdWatcherSocketTest, TimedOutSchedulesTimeout) {
|
||||
int socket_fd = StartServer();
|
||||
bool timed_out = false;
|
||||
bool timed_out2 = false;
|
||||
|
||||
AsyncFdWatcher conn_watcher;
|
||||
conn_watcher.WatchFdForNonBlockingReads(socket_fd, [this](int fd) {
|
||||
int connection_fd = AcceptConnection(fd);
|
||||
close(connection_fd);
|
||||
});
|
||||
|
||||
// Set a timeout flag in each callback.
|
||||
conn_watcher.ConfigureTimeout(
|
||||
std::chrono::milliseconds(500),
|
||||
[this, &conn_watcher, &timed_out, &timed_out2]() {
|
||||
timed_out = true;
|
||||
conn_watcher.ConfigureTimeout(std::chrono::seconds(1),
|
||||
[&timed_out2]() { timed_out2 = true; });
|
||||
});
|
||||
EXPECT_FALSE(timed_out);
|
||||
EXPECT_FALSE(timed_out2);
|
||||
sleep(1);
|
||||
EXPECT_TRUE(timed_out);
|
||||
EXPECT_FALSE(timed_out2);
|
||||
sleep(1);
|
||||
EXPECT_TRUE(timed_out);
|
||||
EXPECT_TRUE(timed_out2);
|
||||
conn_watcher.StopWatchingFileDescriptor();
|
||||
close(socket_fd);
|
||||
}
|
||||
|
||||
// Use two AsyncFdWatchers to set up a server socket.
|
||||
TEST_F(AsyncFdWatcherSocketTest, ClientServer) {
|
||||
ConfigureServer();
|
||||
|
||||
@@ -44,6 +44,11 @@ struct {
|
||||
uint16_t opcode;
|
||||
} internal_command;
|
||||
|
||||
// True when LPM is not enabled yet or wake is not asserted.
|
||||
bool lpm_wake_deasserted;
|
||||
uint32_t lpm_timeout_ms;
|
||||
bool recent_activity_flag;
|
||||
|
||||
VendorInterface* g_vendor_interface = nullptr;
|
||||
|
||||
const size_t preamble_size_for_type[] = {
|
||||
@@ -271,6 +276,9 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
|
||||
fd_watcher_.WatchFdForNonBlockingReads(uart_fd_,
|
||||
[this](int fd) { OnDataReady(fd); });
|
||||
|
||||
// Initially, the power management is off.
|
||||
lpm_wake_deasserted = false;
|
||||
|
||||
// Start configuring the firmware
|
||||
firmware_startup_timer_ = new FirmwareStartupTimer();
|
||||
lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
|
||||
@@ -302,6 +310,19 @@ void VendorInterface::Close() {
|
||||
size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
|
||||
if (uart_fd_ == INVALID_FD) return 0;
|
||||
|
||||
recent_activity_flag = true;
|
||||
|
||||
if (lpm_wake_deasserted == true) {
|
||||
// Restart the timer.
|
||||
fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
|
||||
[this]() { OnTimeout(); });
|
||||
// Assert wake.
|
||||
lpm_wake_deasserted = false;
|
||||
bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
|
||||
lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
|
||||
ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
|
||||
}
|
||||
|
||||
int rv = write_safely(uart_fd_, &type, sizeof(type));
|
||||
if (rv == sizeof(type))
|
||||
rv = write_safely(uart_fd_, data, length);
|
||||
@@ -321,6 +342,32 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) {
|
||||
initialize_complete_cb_(result == 0);
|
||||
initialize_complete_cb_ = nullptr;
|
||||
}
|
||||
|
||||
lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
|
||||
ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
|
||||
|
||||
bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
|
||||
lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
|
||||
|
||||
ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
|
||||
fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
|
||||
[this]() { OnTimeout(); });
|
||||
|
||||
bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
|
||||
lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
|
||||
}
|
||||
|
||||
void VendorInterface::OnTimeout() {
|
||||
ALOGV("%s", __func__);
|
||||
if (recent_activity_flag == false) {
|
||||
lpm_wake_deasserted = true;
|
||||
bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
|
||||
lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
|
||||
fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
|
||||
ALOGE("Zero timeout! Should never happen.");
|
||||
});
|
||||
}
|
||||
recent_activity_flag = false;
|
||||
}
|
||||
|
||||
void VendorInterface::OnDataReady(int fd) {
|
||||
|
||||
@@ -53,6 +53,8 @@ class VendorInterface {
|
||||
PacketReadCallback packet_read_cb);
|
||||
void Close();
|
||||
|
||||
void OnTimeout();
|
||||
|
||||
void OnDataReady(int fd);
|
||||
|
||||
void *lib_handle_;
|
||||
|
||||
Reference in New Issue
Block a user