Merge changes Ic4fcbb22,I1be8a18d

* changes:
  Bluetooth: Use AsyncFdWatcher for power management
  Bluetooth: AsyncFdWatcher: Refactor timeout lock
diff --git a/bluetooth/1.0/default/async_fd_watcher.cc b/bluetooth/1.0/default/async_fd_watcher.cc
index 9cd86f1..161a74a 100644
--- a/bluetooth/1.0/default/async_fd_watcher.cc
+++ b/bluetooth/1.0/default/async_fd_watcher.cc
@@ -140,9 +140,15 @@
 
     // 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;
     }
 
diff --git a/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc b/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
index c21acb8..49ea44a 100644
--- a/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
+++ b/bluetooth/1.0/default/test/async_fd_watcher_unittest.cc
@@ -56,8 +56,7 @@
     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 @@
     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 @@
       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 @@
       // 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 @@
   }
 
   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 @@
 
   // 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 @@
   });
 
   // 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 @@
   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();
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index 278b66c..f228982 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -44,6 +44,11 @@
   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 @@
   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 @@
 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 @@
     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) {
diff --git a/bluetooth/1.0/default/vendor_interface.h b/bluetooth/1.0/default/vendor_interface.h
index 79611cd..ce5769c 100644
--- a/bluetooth/1.0/default/vendor_interface.h
+++ b/bluetooth/1.0/default/vendor_interface.h
@@ -53,6 +53,8 @@
             PacketReadCallback packet_read_cb);
   void Close();
 
+  void OnTimeout();
+
   void OnDataReady(int fd);
 
   void *lib_handle_;