Allow RAMDISK_KERNEL_MODULES to be overriden. am: 823e746b0a

Original change: https://googleplex-android-review.googlesource.com/c/device/google/cuttlefish/+/26566541

Change-Id: I426000b75114683471876e9f01fc0cfba8ad66b9
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/TEST_MAPPING b/TEST_MAPPING
index f711b63..fadf79d 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -28,6 +28,15 @@
     },
     {
       "name": "CtsScopedStorageDeviceOnlyTest"
+    },
+    {
+      "name": "CtsScopedStorageBypassDatabaseOperationsTest"
+    },
+    {
+      "name": "CtsScopedStorageGeneralTest"
+    },
+    {
+      "name": "CtsScopedStorageRedactUriTest"
     }
   ],
   "auto-presubmit": [
diff --git a/guest/commands/bt_vhci_forwarder/Android.bp b/guest/commands/bt_vhci_forwarder/Android.bp
index 03b7a05..45308ba 100644
--- a/guest/commands/bt_vhci_forwarder/Android.bp
+++ b/guest/commands/bt_vhci_forwarder/Android.bp
@@ -20,6 +20,8 @@
 cc_binary {
     name: "bt_vhci_forwarder",
     srcs: [
+        "hci/h4_packetizer.cc",
+        "hci/h4_parser.cc",
         "main.cpp",
     ],
     shared_libs: [
@@ -28,7 +30,6 @@
         "liblog",
     ],
     static_libs: [
-        "h4_packetizer_lib",
         "libgflags",
     ],
     defaults: ["cuttlefish_guest_only"]
diff --git a/guest/commands/bt_vhci_forwarder/hci/h4.h b/guest/commands/bt_vhci_forwarder/hci/h4.h
new file mode 100644
index 0000000..e05a129
--- /dev/null
+++ b/guest/commands/bt_vhci_forwarder/hci/h4.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2021 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 <cstdint>  // for uint8_t
+
+namespace rootcanal {
+
+enum class PacketType : uint8_t {
+  UNKNOWN = 0,
+  COMMAND = 1,
+  ACL = 2,
+  SCO = 3,
+  EVENT = 4,
+  ISO = 5,
+};
+
+}  // namespace rootcanal
diff --git a/guest/commands/bt_vhci_forwarder/hci/h4_packetizer.cc b/guest/commands/bt_vhci_forwarder/hci/h4_packetizer.cc
new file mode 100644
index 0000000..9564669
--- /dev/null
+++ b/guest/commands/bt_vhci_forwarder/hci/h4_packetizer.cc
@@ -0,0 +1,92 @@
+//
+// Copyright 2017 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.
+//
+
+#include "h4_packetizer.h"
+
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#include <cerrno>
+
+#include "log.h"
+
+namespace rootcanal {
+
+H4Packetizer::H4Packetizer(int fd, PacketReadCallback command_cb,
+                           PacketReadCallback event_cb,
+                           PacketReadCallback acl_cb, PacketReadCallback sco_cb,
+                           PacketReadCallback iso_cb,
+                           ClientDisconnectCallback disconnect_cb)
+    : uart_fd_(fd),
+      h4_parser_(command_cb, event_cb, acl_cb, sco_cb, iso_cb),
+      disconnect_cb_(std::move(disconnect_cb)) {}
+
+size_t H4Packetizer::Send(uint8_t type, const uint8_t* data, size_t length) {
+  struct iovec iov[] = {{&type, sizeof(type)},
+                        {const_cast<uint8_t*>(data), length}};
+  ssize_t ret = 0;
+  do {
+    ret = writev(uart_fd_, iov, sizeof(iov) / sizeof(iov[0]));
+  } while (-1 == ret && (EINTR == errno || EAGAIN == errno));
+
+  if (ret == -1) {
+    LOG_ERROR("Error writing to UART (%s)", strerror(errno));
+  } else if (ret < static_cast<ssize_t>(length + 1)) {
+    LOG_ERROR("%d / %d bytes written - something went wrong...",
+              static_cast<int>(ret), static_cast<int>(length + 1));
+  }
+  return ret;
+}
+
+void H4Packetizer::OnDataReady(int fd) {
+  if (disconnected_) {
+    return;
+  }
+  ssize_t bytes_to_read = h4_parser_.BytesRequested();
+  std::vector<uint8_t> buffer(bytes_to_read);
+
+  ssize_t bytes_read;
+  do {
+    bytes_read = read(fd, buffer.data(), bytes_to_read);
+  } while (bytes_read == -1 && errno == EINTR);
+
+  if (bytes_read == 0) {
+    LOG_INFO("remote disconnected!");
+    disconnected_ = true;
+    disconnect_cb_();
+    return;
+  }
+  if (bytes_read < 0) {
+    if (errno == EAGAIN) {
+      // No data, try again later.
+      return;
+    }
+    if (errno == ECONNRESET) {
+      // They probably rejected our packet
+      disconnected_ = true;
+      disconnect_cb_();
+      return;
+    }
+
+    LOG_ALWAYS_FATAL("Read error in %d: %s", h4_parser_.CurrentState(),
+                     strerror(errno));
+  }
+  h4_parser_.Consume(buffer.data(), bytes_read);
+}
+
+}  // namespace rootcanal
diff --git a/guest/commands/bt_vhci_forwarder/hci/h4_packetizer.h b/guest/commands/bt_vhci_forwarder/hci/h4_packetizer.h
new file mode 100644
index 0000000..4feed95
--- /dev/null
+++ b/guest/commands/bt_vhci_forwarder/hci/h4_packetizer.h
@@ -0,0 +1,49 @@
+//
+// Copyright 2017 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 <functional>
+#include <vector>
+
+#include "h4_parser.h"
+
+namespace rootcanal {
+
+// A socket based H4Packetizer. Call OnDataReady whenever
+// data can be read from file descriptor fd.
+//
+// This is only supported on unix.
+class H4Packetizer {
+ public:
+  H4Packetizer(int fd, PacketReadCallback command_cb,
+               PacketReadCallback event_cb, PacketReadCallback acl_cb,
+               PacketReadCallback sco_cb, PacketReadCallback iso_cb,
+               ClientDisconnectCallback disconnect_cb);
+
+  size_t Send(uint8_t type, const uint8_t* data, size_t length);
+
+  void OnDataReady(int fd);
+
+ private:
+  int uart_fd_;
+  H4Parser h4_parser_;
+
+  ClientDisconnectCallback disconnect_cb_;
+  bool disconnected_{false};
+};
+
+}  // namespace rootcanal
diff --git a/guest/commands/bt_vhci_forwarder/hci/h4_parser.cc b/guest/commands/bt_vhci_forwarder/hci/h4_parser.cc
new file mode 100644
index 0000000..f616340
--- /dev/null
+++ b/guest/commands/bt_vhci_forwarder/hci/h4_parser.cc
@@ -0,0 +1,215 @@
+//
+// Copyright 20 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.
+//
+
+#include "hci/h4_parser.h"  // for H4Parser, PacketType, H4Pars...
+
+#include <array>
+#include <cstddef>     // for size_t
+#include <cstdint>     // for uint8_t, int32_t
+#include <functional>  // for function
+#include <utility>     // for move
+#include <vector>      // for vector
+
+#include "log.h"  // for LOG_ALWAYS_FATAL, LOG_INFO
+
+namespace rootcanal {
+
+void H4Parser::Reset() {
+  state_ = HCI_TYPE;
+  packet_.clear();
+  bytes_wanted_ = 0;
+  packet_type_ = 0;
+}
+
+size_t H4Parser::HciGetPacketLengthForType(PacketType type,
+                                           const uint8_t* preamble) {
+  static const size_t
+      packet_length_offset[static_cast<size_t>(PacketType::ISO) + 1] = {
+          0,
+          H4Parser::COMMAND_LENGTH_OFFSET,
+          H4Parser::ACL_LENGTH_OFFSET,
+          H4Parser::SCO_LENGTH_OFFSET,
+          H4Parser::EVENT_LENGTH_OFFSET,
+          H4Parser::ISO_LENGTH_OFFSET,
+      };
+
+  size_t offset = packet_length_offset[static_cast<size_t>(type)];
+  size_t size = preamble[offset];
+  if (type == PacketType::ACL) {
+    size |= ((size_t)preamble[offset + 1]) << 8;
+  }
+  if (type == PacketType::ISO) {
+    size |= ((size_t)preamble[offset + 1] & 0x0fU) << 8;
+  }
+  return size;
+}
+
+H4Parser::H4Parser(PacketReadCallback command_cb, PacketReadCallback event_cb,
+                   PacketReadCallback acl_cb, PacketReadCallback sco_cb,
+                   PacketReadCallback iso_cb, bool enable_recovery_state)
+    : command_cb_(std::move(command_cb)),
+      event_cb_(std::move(event_cb)),
+      acl_cb_(std::move(acl_cb)),
+      sco_cb_(std::move(sco_cb)),
+      iso_cb_(std::move(iso_cb)),
+      enable_recovery_state_(enable_recovery_state) {}
+
+void H4Parser::OnPacketReady() {
+  switch (hci_packet_type_) {
+    case PacketType::COMMAND:
+      command_cb_(packet_);
+      break;
+    case PacketType::ACL:
+      acl_cb_(packet_);
+      break;
+    case PacketType::SCO:
+      sco_cb_(packet_);
+      break;
+    case PacketType::EVENT:
+      event_cb_(packet_);
+      break;
+    case PacketType::ISO:
+      iso_cb_(packet_);
+      break;
+    default:
+      LOG_ALWAYS_FATAL("Unimplemented packet type %d",
+                       static_cast<int>(hci_packet_type_));
+  }
+  // Get ready for the next type byte.
+  hci_packet_type_ = PacketType::UNKNOWN;
+}
+
+size_t H4Parser::BytesRequested() {
+  switch (state_) {
+    case HCI_TYPE:
+    case HCI_RECOVERY:
+      return 1;
+    case HCI_PREAMBLE:
+    case HCI_PAYLOAD:
+      return bytes_wanted_;
+  }
+}
+
+bool H4Parser::Consume(const uint8_t* buffer, int32_t bytes_read) {
+  size_t bytes_to_read = BytesRequested();
+  if (bytes_read <= 0) {
+    LOG_INFO("remote disconnected, or unhandled error?");
+    return false;
+  }
+  if ((uint32_t)bytes_read > BytesRequested()) {
+    LOG_ALWAYS_FATAL("More bytes read (%u) than expected (%u)!",
+                     static_cast<int>(bytes_read),
+                     static_cast<int>(bytes_to_read));
+  }
+
+  static const size_t preamble_size[static_cast<size_t>(PacketType::ISO) + 1] =
+      {
+          0,
+          H4Parser::COMMAND_PREAMBLE_SIZE,
+          H4Parser::ACL_PREAMBLE_SIZE,
+          H4Parser::SCO_PREAMBLE_SIZE,
+          H4Parser::EVENT_PREAMBLE_SIZE,
+          H4Parser::ISO_PREAMBLE_SIZE,
+      };
+  switch (state_) {
+    case HCI_TYPE:
+      // bytes_read >= 1
+      packet_type_ = *buffer;
+      packet_.clear();
+      break;
+
+    case HCI_RECOVERY: {
+      // Skip all received bytes until the HCI Reset command is received.
+      // The parser can end up in a bad state when the host is restarted.
+      const std::array<uint8_t, 4> reset_command{0x01, 0x03, 0x0c, 0x00};
+      size_t offset = packet_.size();
+      LOG_WARN("Received byte in recovery state : 0x%x",
+               static_cast<unsigned>(*buffer));
+      packet_.push_back(*buffer);
+
+      // Last byte does not match expected byte in the sequence.
+      // Drop all the bytes and start over.
+      if (packet_[offset] != reset_command[offset]) {
+        packet_.clear();
+        // The mismatched byte can also be the first of the correct sequence.
+        if (*buffer == reset_command[0]) {
+          packet_.push_back(*buffer);
+        }
+      }
+
+      // Received full reset command.
+      if (packet_.size() == reset_command.size()) {
+        LOG_INFO("Received HCI Reset command, exiting recovery state");
+        // Pop the Idc from the received packet.
+        packet_.erase(packet_.begin());
+        bytes_wanted_ = 0;
+      }
+      break;
+    }
+
+    case HCI_PREAMBLE:
+    case HCI_PAYLOAD:
+      packet_.insert(packet_.end(), buffer, buffer + bytes_read);
+      bytes_wanted_ -= bytes_read;
+      break;
+  }
+
+  switch (state_) {
+    case HCI_TYPE:
+      hci_packet_type_ = static_cast<PacketType>(packet_type_);
+      if (hci_packet_type_ != PacketType::ACL &&
+          hci_packet_type_ != PacketType::SCO &&
+          hci_packet_type_ != PacketType::COMMAND &&
+          hci_packet_type_ != PacketType::EVENT &&
+          hci_packet_type_ != PacketType::ISO) {
+        if (!enable_recovery_state_) {
+          LOG_ALWAYS_FATAL("Received invalid packet type 0x%x",
+                           static_cast<unsigned>(packet_type_));
+        }
+        LOG_ERROR("Received invalid packet type 0x%x, entering recovery state",
+                  static_cast<unsigned>(packet_type_));
+        state_ = HCI_RECOVERY;
+        hci_packet_type_ = PacketType::COMMAND;
+        bytes_wanted_ = 1;
+      } else {
+        state_ = HCI_PREAMBLE;
+        bytes_wanted_ = preamble_size[static_cast<size_t>(hci_packet_type_)];
+      }
+      break;
+    case HCI_PREAMBLE:
+      if (bytes_wanted_ == 0) {
+        size_t payload_size =
+            HciGetPacketLengthForType(hci_packet_type_, packet_.data());
+        if (payload_size == 0) {
+          OnPacketReady();
+          state_ = HCI_TYPE;
+        } else {
+          bytes_wanted_ = payload_size;
+          state_ = HCI_PAYLOAD;
+        }
+      }
+      break;
+    case HCI_RECOVERY:
+    case HCI_PAYLOAD:
+      if (bytes_wanted_ == 0) {
+        OnPacketReady();
+        state_ = HCI_TYPE;
+      }
+      break;
+  }
+  return true;
+}
+}  // namespace rootcanal
diff --git a/guest/commands/bt_vhci_forwarder/hci/h4_parser.h b/guest/commands/bt_vhci_forwarder/hci/h4_parser.h
new file mode 100644
index 0000000..825c41a
--- /dev/null
+++ b/guest/commands/bt_vhci_forwarder/hci/h4_parser.h
@@ -0,0 +1,131 @@
+//
+// Copyright 2021 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 <stddef.h>  // for size_t
+
+#include <cstdint>     // for uint8_t, int32_t
+#include <functional>  // for function
+#include <ostream>     // for operator<<, ostream
+#include <vector>      // for vector
+
+#include "hci/h4.h"  // for PacketType
+
+namespace rootcanal {
+
+using PacketReadCallback = std::function<void(const std::vector<uint8_t>&)>;
+using HciPacketReadyCallback = std::function<void(void)>;
+using ClientDisconnectCallback = std::function<void()>;
+
+// An H4 Parser can parse H4 Packets and will invoke the proper callback
+// once a packet has been parsed.
+//
+// You use it as follows:
+//
+// H4Parser h4(....);
+// size_t nr_bytes = h4.BytesRequested();
+// std::vector fill_this_vector_with_at_most_nr_bytes(nr_bytes);
+// h4.Consume(fill_this_vector_with_at_most_nr_bytes.data(), nr_bytes.size());
+//
+// The parser will invoke the proper callbacks once a packet has been parsed.
+// The parser keeps internal state and is not thread safe.
+class H4Parser {
+ public:
+  enum State { HCI_TYPE, HCI_PREAMBLE, HCI_PAYLOAD, HCI_RECOVERY };
+
+  H4Parser(PacketReadCallback command_cb, PacketReadCallback event_cb,
+           PacketReadCallback acl_cb, PacketReadCallback sco_cb,
+           PacketReadCallback iso_cb, bool enable_recovery_state = false);
+
+  // Consumes the given number of bytes, returns true on success.
+  bool Consume(const uint8_t* buffer, int32_t bytes);
+
+  // The maximum number of bytes the parser can consume in the current state.
+  size_t BytesRequested();
+
+  // Resets the parser to the empty, initial state.
+  void Reset();
+
+  State CurrentState() { return state_; };
+
+  void EnableRecovery() { enable_recovery_state_ = true; }
+  void DisableRecovery() { enable_recovery_state_ = false; }
+
+ private:
+  void OnPacketReady();
+
+  // 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
+  static constexpr size_t COMMAND_PREAMBLE_SIZE = 3;
+  static constexpr size_t COMMAND_LENGTH_OFFSET = 2;
+  // 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.2)
+  static constexpr size_t ACL_PREAMBLE_SIZE = 4;
+  static constexpr size_t ACL_LENGTH_OFFSET = 2;
+
+  // 2 bytes for handle, 1 byte for data length (Volume 2, Part E, 5.4.3)
+  static constexpr size_t SCO_PREAMBLE_SIZE = 3;
+  static constexpr size_t SCO_LENGTH_OFFSET = 2;
+
+  // 1 byte for event code, 1 byte for parameter length (Volume 2, Part
+  // E, 5.4.4)
+  static constexpr size_t EVENT_PREAMBLE_SIZE = 2;
+  static constexpr size_t EVENT_LENGTH_OFFSET = 1;
+
+  // 2 bytes for handle and flags, 12 bits for length (Volume 2, Part E, 5.4.5)
+  static constexpr size_t ISO_PREAMBLE_SIZE = 4;
+  static constexpr size_t ISO_LENGTH_OFFSET = 2;
+
+  PacketReadCallback command_cb_;
+  PacketReadCallback event_cb_;
+  PacketReadCallback acl_cb_;
+  PacketReadCallback sco_cb_;
+  PacketReadCallback iso_cb_;
+
+  static size_t HciGetPacketLengthForType(PacketType type,
+                                          const uint8_t* preamble);
+
+  PacketType hci_packet_type_{PacketType::UNKNOWN};
+
+  State state_{HCI_TYPE};
+  uint8_t packet_type_{};
+  std::vector<uint8_t> packet_;
+  size_t bytes_wanted_{0};
+  bool enable_recovery_state_{false};
+};
+
+inline std::ostream& operator<<(std::ostream& os,
+                                H4Parser::State const& state_) {
+  switch (state_) {
+    case H4Parser::State::HCI_TYPE:
+      os << "HCI_TYPE";
+      break;
+    case H4Parser::State::HCI_PREAMBLE:
+      os << "HCI_PREAMBLE";
+      break;
+    case H4Parser::State::HCI_PAYLOAD:
+      os << "HCI_PAYLOAD";
+      break;
+    case H4Parser::State::HCI_RECOVERY:
+      os << "HCI_RECOVERY";
+      break;
+    default:
+      os << "unknown state " << static_cast<int>(state_);
+      break;
+  }
+  return os;
+}
+
+}  // namespace rootcanal
diff --git a/guest/commands/bt_vhci_forwarder/hci/log.h b/guest/commands/bt_vhci_forwarder/hci/log.h
new file mode 100644
index 0000000..f301a32
--- /dev/null
+++ b/guest/commands/bt_vhci_forwarder/hci/log.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 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 <android-base/format.h>
+#include <android-base/logging.h>
+
+// FIXME: remove those shims
+#define LOG_DEBUG(...) LOG(DEBUG) << fmt::sprintf(__VA_ARGS__)
+#define LOG_INFO(...) LOG(INFO) << fmt::sprintf(__VA_ARGS__)
+#define LOG_WARN(...) LOG(WARNING) << fmt::sprintf(__VA_ARGS__)
+#define LOG_ERROR(...) LOG(ERROR) << fmt::sprintf(__VA_ARGS__)
+#define LOG_ALWAYS_FATAL(...) LOG(FATAL) << fmt::sprintf(__VA_ARGS__)
+
+#define ASSERT(cond) CHECK(cond)
+#define ASSERT_LOG(cond, ...) CHECK(cond) << fmt::sprintf(__VA_ARGS__)
diff --git a/guest/commands/bt_vhci_forwarder/main.cpp b/guest/commands/bt_vhci_forwarder/main.cpp
index faf6b55..7c83a5b 100644
--- a/guest/commands/bt_vhci_forwarder/main.cpp
+++ b/guest/commands/bt_vhci_forwarder/main.cpp
@@ -26,7 +26,7 @@
 
 #include "android-base/logging.h"
 
-#include "model/hci/h4_packetizer.h"
+#include "hci/h4_packetizer.h"
 
 // Copied from net/bluetooth/hci.h
 #define HCI_ACLDATA_PKT 0x02