Merge "VtsHalAudioEffectTargetTest: Fix crash issue" into main
diff --git a/audio/aidl/default/CapEngineConfigXmlConverter.cpp b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
index 20fbca4..14d27f2 100644
--- a/audio/aidl/default/CapEngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/CapEngineConfigXmlConverter.cpp
@@ -52,6 +52,7 @@
static constexpr const char* gOutputDevicesParameter = "selected_output_devices";
static constexpr const char* gOutputDeviceAddressParameter = "device_address";
static constexpr const char* gStrategyPrefix = "vx_";
+static constexpr const char* gLegacyStrategyPrefix = "STRATEGY_";
static constexpr const char* gLegacyOutputDevicePrefix = "AUDIO_DEVICE_OUT_";
static constexpr const char* gLegacyInputDevicePrefix = "AUDIO_DEVICE_IN_";
static constexpr const char* gLegacyStreamPrefix = "AUDIO_STREAM_";
@@ -159,6 +160,17 @@
}
return strategyId;
}
+ pos = stringToken.find(gLegacyStrategyPrefix);
+ if (pos != std::string::npos) {
+ std::string legacyStrategyIdLiteral = stringToken.substr(pos);
+ const auto legacyStrategies = getLegacyProductStrategyMap();
+ if (const auto& it = legacyStrategies.find(legacyStrategyIdLiteral);
+ it != legacyStrategies.end()) {
+ return it->second;
+ }
+ LOG(ERROR) << "Invalid legacy strategy " << stringToken << " from path " << path;
+ return unexpected(BAD_VALUE);
+ }
}
return unexpected(BAD_VALUE);
}
diff --git a/audio/aidl/default/EngineConfigXmlConverter.cpp b/audio/aidl/default/EngineConfigXmlConverter.cpp
index d945b17..78deb64 100644
--- a/audio/aidl/default/EngineConfigXmlConverter.cpp
+++ b/audio/aidl/default/EngineConfigXmlConverter.cpp
@@ -59,20 +59,6 @@
static constexpr char kCapEngineConfigFileName[] =
"/parameter-framework/Settings/Policy/PolicyConfigurableDomains.xml";
-void EngineConfigXmlConverter::initProductStrategyMap() {
-#define STRATEGY_ENTRY(name) {"STRATEGY_" #name, static_cast<int>(AudioProductStrategyType::name)}
-
- mProductStrategyMap = {STRATEGY_ENTRY(MEDIA),
- STRATEGY_ENTRY(PHONE),
- STRATEGY_ENTRY(SONIFICATION),
- STRATEGY_ENTRY(SONIFICATION_RESPECTFUL),
- STRATEGY_ENTRY(DTMF),
- STRATEGY_ENTRY(ENFORCED_AUDIBLE),
- STRATEGY_ENTRY(TRANSMITTED_THROUGH_SPEAKER),
- STRATEGY_ENTRY(ACCESSIBILITY)};
-#undef STRATEGY_ENTRY
-}
-
ConversionResult<int> EngineConfigXmlConverter::convertProductStrategyNameToAidl(
const std::string& xsdcProductStrategyName) {
const auto [it, success] = mProductStrategyMap.insert(
@@ -242,7 +228,7 @@
}
void EngineConfigXmlConverter::init() {
- initProductStrategyMap();
+ mProductStrategyMap = getLegacyProductStrategyMap();
if (getXsdcConfig()->hasProductStrategies()) {
mAidlEngineConfig.productStrategies = VALUE_OR_FATAL(
(convertWrappedCollectionToAidl<eng_xsd::ProductStrategies,
diff --git a/audio/aidl/default/XsdcConversion.cpp b/audio/aidl/default/XsdcConversion.cpp
index b42d7f5..5845903 100644
--- a/audio/aidl/default/XsdcConversion.cpp
+++ b/audio/aidl/default/XsdcConversion.cpp
@@ -816,4 +816,23 @@
}
return aidlCurvePoint;
}
+
+/**
+ * The hard coded id must be in sync with policy.h definition of legacy strategy ids.
+ */
+std::unordered_map<std::string, int> getLegacyProductStrategyMap() {
+#define STRATEGY_ENTRY(name, id) {"STRATEGY_" #name, static_cast<int>(id)}
+
+ return {STRATEGY_ENTRY(MEDIA, 5),
+ STRATEGY_ENTRY(PHONE, 0),
+ STRATEGY_ENTRY(SONIFICATION, 1),
+ STRATEGY_ENTRY(SONIFICATION_RESPECTFUL, 4),
+ STRATEGY_ENTRY(DTMF, 6),
+ STRATEGY_ENTRY(ENFORCED_AUDIBLE, 2),
+ STRATEGY_ENTRY(CALL_ASSISTANT, 7),
+ STRATEGY_ENTRY(TRANSMITTED_THROUGH_SPEAKER,8),
+ STRATEGY_ENTRY(ACCESSIBILITY, 3)};
+#undef STRATEGY_ENTRY
+}
+
} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/default/include/core-impl/XsdcConversion.h b/audio/aidl/default/include/core-impl/XsdcConversion.h
index f00206b..b298eee 100644
--- a/audio/aidl/default/include/core-impl/XsdcConversion.h
+++ b/audio/aidl/default/include/core-impl/XsdcConversion.h
@@ -64,4 +64,5 @@
const engineconfiguration::Stream& xsdStreamType);
ConversionResult<int32_t> convertAudioFlagsToAidl(
const std::vector<engineconfiguration::FlagType>& xsdcFlagTypeVec);
+std::unordered_map<std::string, int> getLegacyProductStrategyMap();
} // namespace aidl::android::hardware::audio::core::internal
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 5f0a608..14e70ef 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -31,6 +31,7 @@
],
header_libs: [
"libaudioaidl_headers",
+ "libaudioutils_headers",
"libexpectedutils_headers",
],
cflags: [
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index f6098ca..0dd5e9f 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -223,7 +223,8 @@
return status;
}
- const SetValueResult& result = getSetValueResults().back();
+ std::vector<SetValueResult> resultVector = getSetValueResults();
+ const SetValueResult& result = resultVector.back();
if (result.requestId != 0) {
ALOGE("request ID mismatch, got %" PRId64 ", expect 0", result.requestId);
@@ -245,7 +246,8 @@
return unexpected(status);
}
- const GetValueResult& result = getGetValueResults().back();
+ std::vector<GetValueResult> resultVector = getGetValueResults();
+ const GetValueResult& result = resultVector.back();
if (result.requestId != 0) {
ALOGE("request ID mismatch, got %" PRId64 ", expect 0", result.requestId);
return unexpected(StatusCode::INTERNAL_ERROR);
@@ -277,7 +279,7 @@
mCv.notify_all();
}
- const std::vector<SetValueResult>& getSetValueResults() {
+ std::vector<SetValueResult> getSetValueResults() {
std::scoped_lock<std::mutex> lockGuard(mLock);
return mSetValueResults;
}
@@ -291,7 +293,7 @@
mCv.notify_all();
}
- const std::vector<GetValueResult>& getGetValueResults() {
+ std::vector<GetValueResult> getGetValueResults() {
std::scoped_lock<std::mutex> lockGuard(mLock);
return mGetValueResults;
}
@@ -309,7 +311,7 @@
mCv.notify_all();
}
- const std::vector<VehiclePropValue>& getChangedProperties() {
+ std::vector<VehiclePropValue> getChangedProperties() {
std::scoped_lock<std::mutex> lockGuard(mLock);
return mChangedProperties;
}
diff --git a/bluetooth/aidl/Android.bp b/bluetooth/aidl/Android.bp
index 0daecf7..4ee2f49 100644
--- a/bluetooth/aidl/Android.bp
+++ b/bluetooth/aidl/Android.bp
@@ -16,13 +16,6 @@
srcs: ["android/hardware/bluetooth/*.aidl"],
stability: "vintf",
backend: {
- cpp: {
- // FIXME should this be disabled?
- // prefer NDK backend which can be used anywhere
- // If you disable this, you also need to delete the C++
- // translate code.
- enabled: true,
- },
rust: {
enabled: true,
},
@@ -44,5 +37,4 @@
},
],
frozen: true,
-
}
diff --git a/bluetooth/aidl/default/Android.bp b/bluetooth/aidl/default/Android.bp
index 3f4ba99..d3f6364 100644
--- a/bluetooth/aidl/default/Android.bp
+++ b/bluetooth/aidl/default/Android.bp
@@ -2,81 +2,62 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-cc_defaults {
- name: "android.hardware.bluetooth-service-build-defaults",
- cflags: [
- "-Wall",
- "-Wextra",
- ],
- shared_libs: [
- "android.hardware.bluetooth-V1-ndk",
- "libbase",
- "libbinder_ndk",
- "libcutils",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
- static_libs: [
- "android.hardware.bluetooth.async",
- "android.hardware.bluetooth.hci",
- ],
-}
-
cc_library_static {
name: "libbluetoothhcihalimpl",
vendor_available: true,
host_supported: true,
- defaults: ["android.hardware.bluetooth-service-build-defaults"],
srcs: [
"BluetoothHci.cpp",
"net_bluetooth_mgmt.cpp",
],
-}
-
-cc_binary {
- name: "android.hardware.bluetooth-service.default",
- relative_install_path: "hw",
- init_rc: ["bluetooth-service-default.rc"],
- vintf_fragments: [":manifest_android.hardware.bluetooth-service.default.xml"],
- vendor: true,
- defaults: ["android.hardware.bluetooth-service-build-defaults"],
- srcs: [
- "service.cpp",
+ cflags: [
+ "-Wall",
+ "-Wextra",
],
- shared_libs: [
- "android.hardware.bluetooth-V1-ndk",
- "libbase",
- "libbinder_ndk",
- "libhidlbase",
- "libutils",
- "liblog",
- ],
- static_libs: [
- "libbluetoothhcihalimpl",
- ],
-}
-
-cc_fuzz {
- name: "android.hardware.bluetooth-service.default_fuzzer",
- host_supported: true,
- defaults: ["service_fuzzer_defaults"],
- srcs: [
- "test/fuzzer.cpp",
+ header_libs: [
+ "libbluetooth_offload_hal_headers",
],
static_libs: [
"android.hardware.bluetooth.async",
"android.hardware.bluetooth.hci",
- "android.hardware.bluetooth-V1-ndk",
- "libbluetoothhcihalimpl",
- "liblog",
],
- fuzz_config: {
- componentid: 27441,
- cc: [
- "mylesgw@google.com",
- ],
- },
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+}
+
+rust_binary {
+ name: "android.hardware.bluetooth-service.default",
+ crate_name: "bluetooth_hci_hal_server",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth-service.default.xml"],
+ vendor: true,
+ prefer_rlib: true,
+ srcs: ["main.rs"],
+ rustlibs: [
+ "android.hardware.bluetooth-V1-rust",
+ "libbluetooth_offload_hal",
+ "libbluetooth_offload_leaudio_hci",
+ "libbinder_rs",
+ "liblogger",
+ "liblog_rust",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.async",
+ "android.hardware.bluetooth.hci",
+ "libbluetoothhcihalimpl",
+ ],
+ shared_libs: [
+ "libbase",
+ "libc++",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
}
filegroup {
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp
index a247cb0..bcdb67e 100644
--- a/bluetooth/aidl/default/BluetoothHci.cpp
+++ b/bluetooth/aidl/default/BluetoothHci.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * 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.
@@ -16,18 +16,20 @@
#define LOG_TAG "android.hardware.bluetooth.service.default"
-#include "BluetoothHci.h"
-
#include <cutils/properties.h>
#include <fcntl.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <poll.h>
+#include <hal/ffi.h>
#include <string.h>
-#include <sys/uio.h>
#include <termios.h>
+#include <future>
+#include <memory>
+#include <vector>
+
+#include "async_fd_watcher.h"
+#include "h4_protocol.h"
#include "log/log.h"
+#include "net_bluetooth_mgmt.h"
namespace {
int SetTerminalRaw(int fd) {
@@ -44,12 +46,9 @@
using namespace ::android::hardware::bluetooth::hci;
using namespace ::android::hardware::bluetooth::async;
-using aidl::android::hardware::bluetooth::Status;
namespace aidl::android::hardware::bluetooth::impl {
-void OnDeath(void* cookie);
-
std::optional<std::string> GetSystemProperty(const std::string& property) {
std::array<char, PROPERTY_VALUE_MAX> value_array{0};
auto value_len = property_get(property.c_str(), value_array.data(), nullptr);
@@ -63,302 +62,298 @@
return str.compare(0, prefix.length(), prefix) == 0;
}
-class BluetoothDeathRecipient {
+class Hal {
public:
- BluetoothDeathRecipient(BluetoothHci* hci) : mHci(hci) {}
-
- void LinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
- mCb = cb;
- clientDeathRecipient_ = AIBinder_DeathRecipient_new(OnDeath);
- auto linkToDeathReturnStatus = AIBinder_linkToDeath(
- mCb->asBinder().get(), clientDeathRecipient_, this /* cookie */);
- LOG_ALWAYS_FATAL_IF(linkToDeathReturnStatus != STATUS_OK,
- "Unable to link to death recipient");
+ Hal(const std::string& dev_path = "/dev/hvc5") {
+ char property_bytes[PROPERTY_VALUE_MAX];
+ property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
+ mDevPath = std::string(property_bytes);
}
- void UnlinkToDeath(const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
- LOG_ALWAYS_FATAL_IF(cb != mCb, "Unable to unlink mismatched pointers");
+ static void Initialize(void* instance,
+ const struct hal_callbacks* callbacks) {
+ static_cast<Hal*>(instance)->Initialize(callbacks);
}
- void serviceDied() {
- if (mCb != nullptr && !AIBinder_isAlive(mCb->asBinder().get())) {
- ALOGE("Bluetooth remote service has died");
- } else {
- ALOGE("BluetoothDeathRecipient::serviceDied called but service not dead");
- return;
- }
- {
- std::lock_guard<std::mutex> guard(mHasDiedMutex);
- has_died_ = true;
- }
- mHci->close();
+ static void Close(void* instance) { static_cast<Hal*>(instance)->Close(); }
+
+ static void SendCommand(void* instance, const uint8_t* data, size_t len) {
+ static_cast<Hal*>(instance)->SendCommand(
+ std::vector<uint8_t>(data, data + len));
}
- BluetoothHci* mHci;
- std::shared_ptr<IBluetoothHciCallbacks> mCb;
- AIBinder_DeathRecipient* clientDeathRecipient_;
- bool getHasDied() {
- std::lock_guard<std::mutex> guard(mHasDiedMutex);
- return has_died_;
+
+ static void SendAcl(void* instance, const uint8_t* data, size_t len) {
+ static_cast<Hal*>(instance)->SendAcl(
+ std::vector<uint8_t>(data, data + len));
+ }
+
+ static void SendSco(void* instance, const uint8_t* data, size_t len) {
+ static_cast<Hal*>(instance)->SendSco(
+ std::vector<uint8_t>(data, data + len));
+ }
+
+ static void SendIso(void* instance, const uint8_t* data, size_t len) {
+ static_cast<Hal*>(instance)->SendIso(
+ std::vector<uint8_t>(data, data + len));
}
private:
- std::mutex mHasDiedMutex;
- bool has_died_{false};
-};
-
-void OnDeath(void* cookie) {
- auto* death_recipient = static_cast<BluetoothDeathRecipient*>(cookie);
- death_recipient->serviceDied();
-}
-
-BluetoothHci::BluetoothHci(const std::string& dev_path) {
- char property_bytes[PROPERTY_VALUE_MAX];
- property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
- mDevPath = std::string(property_bytes);
- mDeathRecipient = std::make_shared<BluetoothDeathRecipient>(this);
-}
-
-int BluetoothHci::getFdFromDevPath() {
- int fd = open(mDevPath.c_str(), O_RDWR);
- if (fd < 0) {
- ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
- strerror(errno));
+ int getFdFromDevPath() {
+ int fd = open(mDevPath.c_str(), O_RDWR);
+ if (fd < 0) {
+ ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
+ strerror(errno));
+ return fd;
+ }
+ if (int ret = SetTerminalRaw(fd) < 0) {
+ ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
+ strerror(errno));
+ }
return fd;
}
- if (int ret = SetTerminalRaw(fd) < 0) {
- ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
- strerror(errno));
- }
- return fd;
-}
-void BluetoothHci::reset() {
- // Send a reset command and wait until the command complete comes back.
+ void reset() {
+ // Send a reset command and wait until the command complete comes back.
- std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
+ std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
- auto resetPromise = std::make_shared<std::promise<void>>();
- auto resetFuture = resetPromise->get_future();
+ auto resetPromise = std::make_shared<std::promise<void>>();
+ auto resetFuture = resetPromise->get_future();
- mH4 = std::make_shared<H4Protocol>(
- mFd,
- [](const std::vector<uint8_t>& raw_command) {
- ALOGI("Discarding %d bytes with command type",
- static_cast<int>(raw_command.size()));
- },
- [](const std::vector<uint8_t>& raw_acl) {
- ALOGI("Discarding %d bytes with acl type",
- static_cast<int>(raw_acl.size()));
- },
- [](const std::vector<uint8_t>& raw_sco) {
- ALOGI("Discarding %d bytes with sco type",
- static_cast<int>(raw_sco.size()));
- },
- [resetPromise](const std::vector<uint8_t>& raw_event) {
- std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
- 0x03, 0x0c, 0x00};
- bool valid = raw_event.size() == 6 &&
- raw_event[0] == reset_complete[0] &&
- raw_event[1] == reset_complete[1] &&
- // Don't compare the number of packets field.
- raw_event[3] == reset_complete[3] &&
- raw_event[4] == reset_complete[4] &&
- raw_event[5] == reset_complete[5];
- if (valid) {
- resetPromise->set_value();
- } else {
- ALOGI("Discarding %d bytes with event type",
- static_cast<int>(raw_event.size()));
- }
- },
- [](const std::vector<uint8_t>& raw_iso) {
- ALOGI("Discarding %d bytes with iso type",
- static_cast<int>(raw_iso.size()));
- },
- [this]() {
- ALOGI("HCI socket device disconnected while waiting for reset");
- mFdWatcher.StopWatchingFileDescriptors();
- });
- mFdWatcher.WatchFdForNonBlockingReads(mFd,
- [this](int) { mH4->OnDataReady(); });
+ mH4 = std::make_shared<H4Protocol>(
+ mFd,
+ [](const std::vector<uint8_t>& raw_command) {
+ ALOGI("Discarding %d bytes with command type",
+ static_cast<int>(raw_command.size()));
+ },
+ [](const std::vector<uint8_t>& raw_acl) {
+ ALOGI("Discarding %d bytes with acl type",
+ static_cast<int>(raw_acl.size()));
+ },
+ [](const std::vector<uint8_t>& raw_sco) {
+ ALOGI("Discarding %d bytes with sco type",
+ static_cast<int>(raw_sco.size()));
+ },
+ [resetPromise](const std::vector<uint8_t>& raw_event) {
+ std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
+ 0x03, 0x0c, 0x00};
+ bool valid = raw_event.size() == 6 &&
+ raw_event[0] == reset_complete[0] &&
+ raw_event[1] == reset_complete[1] &&
+ // Don't compare the number of packets field.
+ raw_event[3] == reset_complete[3] &&
+ raw_event[4] == reset_complete[4] &&
+ raw_event[5] == reset_complete[5];
+ if (valid) {
+ resetPromise->set_value();
+ } else {
+ ALOGI("Discarding %d bytes with event type",
+ static_cast<int>(raw_event.size()));
+ }
+ },
+ [](const std::vector<uint8_t>& raw_iso) {
+ ALOGI("Discarding %d bytes with iso type",
+ static_cast<int>(raw_iso.size()));
+ },
+ [this]() {
+ ALOGI("HCI socket device disconnected while waiting for reset");
+ mFdWatcher.StopWatchingFileDescriptors();
+ });
+ mFdWatcher.WatchFdForNonBlockingReads(mFd,
+ [this](int) { mH4->OnDataReady(); });
- ndk::ScopedAStatus result = send(PacketType::COMMAND, reset);
- if (!result.isOk()) {
- ALOGE("Error sending reset command");
- }
- auto status = resetFuture.wait_for(std::chrono::seconds(1));
- mFdWatcher.StopWatchingFileDescriptors();
- if (status == std::future_status::ready) {
- ALOGI("HCI Reset successful");
- } else {
- ALOGE("HCI Reset Response not received in one second");
- }
-
- resetPromise.reset();
-}
-
-ndk::ScopedAStatus BluetoothHci::initialize(
- const std::shared_ptr<IBluetoothHciCallbacks>& cb) {
- ALOGI(__func__);
-
- if (cb == nullptr) {
- ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
- return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE);
- }
-
- HalState old_state = HalState::READY;
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- if (mState != HalState::READY) {
- old_state = mState;
+ if (!send(PacketType::COMMAND, reset)) {
+ ALOGE("Error sending reset command");
+ }
+ auto status = resetFuture.wait_for(std::chrono::seconds(1));
+ mFdWatcher.StopWatchingFileDescriptors();
+ if (status == std::future_status::ready) {
+ ALOGI("HCI Reset successful");
} else {
- mState = HalState::INITIALIZING;
+ ALOGE("HCI Reset Response not received in one second");
}
+
+ resetPromise.reset();
}
- if (old_state != HalState::READY) {
- ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
- close();
- cb->initializationComplete(Status::ALREADY_INITIALIZED);
- return ndk::ScopedAStatus::ok();
- }
+ void Initialize(const struct hal_callbacks* callbacks) {
+ ALOGI(__func__);
- mCb = cb;
- management_.reset(new NetBluetoothMgmt);
- mFd = management_->openHci();
- if (mFd < 0) {
- management_.reset();
+ HalState old_state = HalState::READY;
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ if (mState != HalState::READY) {
+ old_state = mState;
+ } else {
+ mState = HalState::INITIALIZING;
+ }
+ }
- ALOGI("Unable to open Linux interface, trying default path.");
- mFd = getFdFromDevPath();
+ if (old_state != HalState::READY) {
+ ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
+ Close();
+ callbacks->initialization_complete(callbacks->handle,
+ STATUS_ALREADY_INITIALIZED);
+ return;
+ }
+
+ mCallbacks = std::make_unique<struct hal_callbacks>(*callbacks);
+ management_.reset(new NetBluetoothMgmt);
+ mFd = management_->openHci();
if (mFd < 0) {
+ management_.reset();
+
+ ALOGI("Unable to open Linux interface, trying default path.");
+ mFd = getFdFromDevPath();
+ if (mFd < 0) {
+ mState = HalState::READY;
+ mCallbacks->initialization_complete(mCallbacks->handle,
+ STATUS_UNABLE_TO_OPEN_INTERFACE);
+ return;
+ }
+ }
+
+ // TODO: HCI Reset on emulators since the bluetooth controller
+ // cannot be powered on/off during the HAL setup; and the stack
+ // might received spurious packets/events during boottime.
+ // Proper solution would be to use bt-virtio or vsock to better
+ // control the link to rootcanal and the controller lifetime.
+ const std::string kBoardProperty = "ro.product.board";
+ const std::string kCuttlefishBoard = "cutf";
+ auto board_name = GetSystemProperty(kBoardProperty);
+ if (board_name.has_value() &&
+ (starts_with(board_name.value(), "cutf") ||
+ starts_with(board_name.value(), "goldfish"))) {
+ reset();
+ }
+
+ mH4 = std::make_shared<H4Protocol>(
+ mFd,
+ [](const std::vector<uint8_t>& /* raw_command */) {
+ LOG_ALWAYS_FATAL("Unexpected command!");
+ },
+ [this](const std::vector<uint8_t>& raw_acl) {
+ mCallbacks->acl_received(mCallbacks->handle, raw_acl.data(),
+ raw_acl.size());
+ },
+ [this](const std::vector<uint8_t>& raw_sco) {
+ mCallbacks->sco_received(mCallbacks->handle, raw_sco.data(),
+ raw_sco.size());
+ },
+ [this](const std::vector<uint8_t>& raw_event) {
+ mCallbacks->event_received(mCallbacks->handle, raw_event.data(),
+ raw_event.size());
+ },
+ [this](const std::vector<uint8_t>& raw_iso) {
+ mCallbacks->iso_received(mCallbacks->handle, raw_iso.data(),
+ raw_iso.size());
+ },
+ [this]() {
+ ALOGI("HCI socket device disconnected");
+ mFdWatcher.StopWatchingFileDescriptors();
+ });
+ mFdWatcher.WatchFdForNonBlockingReads(mFd,
+ [this](int) { mH4->OnDataReady(); });
+
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ mState = HalState::ONE_CLIENT;
+ }
+
+ ALOGI("initialization complete");
+ mCallbacks->initialization_complete(mCallbacks->handle, STATUS_SUCCESS);
+ }
+
+ void Close() {
+ ALOGI(__func__);
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
+ if (mState != HalState::ONE_CLIENT) {
+ LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
+ "mState is INITIALIZING");
+ ALOGI("Already closed");
+ return;
+ }
+ mCallbacks.reset();
+ mState = HalState::CLOSING;
+ }
+
+ mFdWatcher.StopWatchingFileDescriptors();
+
+ if (management_) {
+ management_->closeHci();
+ } else {
+ ::close(mFd);
+ }
+
+ {
+ std::lock_guard<std::mutex> guard(mStateMutex);
mState = HalState::READY;
- cb->initializationComplete(Status::UNABLE_TO_OPEN_INTERFACE);
- return ndk::ScopedAStatus::ok();
+ mH4 = nullptr;
}
}
- mDeathRecipient->LinkToDeath(mCb);
-
- // TODO: HCI Reset on emulators since the bluetooth controller
- // cannot be powered on/off during the HAL setup; and the stack
- // might received spurious packets/events during boottime.
- // Proper solution would be to use bt-virtio or vsock to better
- // control the link to rootcanal and the controller lifetime.
- const std::string kBoardProperty = "ro.product.board";
- const std::string kCuttlefishBoard = "cutf";
- auto board_name = GetSystemProperty(kBoardProperty);
- if (board_name.has_value() && (
- starts_with(board_name.value(), "cutf") ||
- starts_with(board_name.value(), "goldfish"))) {
- reset();
+ void SendCommand(const std::vector<uint8_t>& data) {
+ send(PacketType::COMMAND, data);
+ }
+ void SendAcl(const std::vector<uint8_t>& data) {
+ send(PacketType::ACL_DATA, data);
+ }
+ void SendSco(const std::vector<uint8_t>& data) {
+ send(PacketType::SCO_DATA, data);
+ }
+ void SendIso(const std::vector<uint8_t>& data) {
+ send(PacketType::ISO_DATA, data);
}
- mH4 = std::make_shared<H4Protocol>(
- mFd,
- [](const std::vector<uint8_t>& /* raw_command */) {
- LOG_ALWAYS_FATAL("Unexpected command!");
- },
- [this](const std::vector<uint8_t>& raw_acl) {
- mCb->aclDataReceived(raw_acl);
- },
- [this](const std::vector<uint8_t>& raw_sco) {
- mCb->scoDataReceived(raw_sco);
- },
- [this](const std::vector<uint8_t>& raw_event) {
- mCb->hciEventReceived(raw_event);
- },
- [this](const std::vector<uint8_t>& raw_iso) {
- mCb->isoDataReceived(raw_iso);
- },
- [this]() {
- ALOGI("HCI socket device disconnected");
- mFdWatcher.StopWatchingFileDescriptors();
- });
- mFdWatcher.WatchFdForNonBlockingReads(mFd,
- [this](int) { mH4->OnDataReady(); });
-
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- mState = HalState::ONE_CLIENT;
- }
- ALOGI("initialization complete");
- auto status = mCb->initializationComplete(Status::SUCCESS);
- if (!status.isOk()) {
- if (!mDeathRecipient->getHasDied()) {
- ALOGE("Error sending init callback, but no death notification");
+ bool send(PacketType type, const std::vector<uint8_t>& v) {
+ if (v.empty()) {
+ ALOGE("Packet is empty, no data was found to be sent");
+ return false;
}
- close();
- return ndk::ScopedAStatus::fromServiceSpecificError(
- STATUS_FAILED_TRANSACTION);
- }
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus BluetoothHci::close() {
- ALOGI(__func__);
- {
std::lock_guard<std::mutex> guard(mStateMutex);
- if (mState != HalState::ONE_CLIENT) {
- LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
- "mState is INITIALIZING");
- ALOGI("Already closed");
- return ndk::ScopedAStatus::ok();
+ if (mH4 == nullptr) {
+ ALOGE("Illegal State");
+ return false;
}
- mState = HalState::CLOSING;
+
+ mH4->Send(type, v);
+ return true;
}
- mFdWatcher.StopWatchingFileDescriptors();
+ std::unique_ptr<struct hal_callbacks> mCallbacks;
+ std::string mDevPath;
+ int mFd{-1};
+ ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
+ std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
+ std::unique_ptr<NetBluetoothMgmt> management_{};
- if (management_) {
- management_->closeHci();
- } else {
- ::close(mFd);
- }
-
- {
- std::lock_guard<std::mutex> guard(mStateMutex);
- mState = HalState::READY;
- mH4 = nullptr;
- }
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus BluetoothHci::sendHciCommand(
- const std::vector<uint8_t>& packet) {
- return send(PacketType::COMMAND, packet);
-}
-
-ndk::ScopedAStatus BluetoothHci::sendAclData(
- const std::vector<uint8_t>& packet) {
- return send(PacketType::ACL_DATA, packet);
-}
-
-ndk::ScopedAStatus BluetoothHci::sendScoData(
- const std::vector<uint8_t>& packet) {
- return send(PacketType::SCO_DATA, packet);
-}
-
-ndk::ScopedAStatus BluetoothHci::sendIsoData(
- const std::vector<uint8_t>& packet) {
- return send(PacketType::ISO_DATA, packet);
-}
-
-ndk::ScopedAStatus BluetoothHci::send(PacketType type,
- const std::vector<uint8_t>& v) {
- if (v.empty()) {
- ALOGE("Packet is empty, no data was found to be sent");
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
-
- std::lock_guard<std::mutex> guard(mStateMutex);
- if (mH4 == nullptr) {
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
- }
-
- mH4->Send(type, v);
- return ndk::ScopedAStatus::ok();
-}
+ // Don't close twice or open before close is complete
+ std::mutex mStateMutex;
+ enum class HalState {
+ READY,
+ INITIALIZING,
+ ONE_CLIENT,
+ CLOSING,
+ } mState{HalState::READY};
+};
} // namespace aidl::android::hardware::bluetooth::impl
+
+extern "C" {
+
+using namespace aidl::android::hardware::bluetooth::impl;
+
+struct hal_interface hal_new() {
+ return (struct hal_interface){
+ .handle = new Hal(),
+ .initialize = &Hal::Initialize,
+ .close = &Hal::Close,
+ .send_command = &Hal::SendCommand,
+ .send_acl = &Hal::SendAcl,
+ .send_sco = &Hal::SendSco,
+ .send_iso = &Hal::SendIso,
+ };
+}
+}
diff --git a/bluetooth/aidl/default/BluetoothHci.h b/bluetooth/aidl/default/BluetoothHci.h
deleted file mode 100644
index 477cc5c..0000000
--- a/bluetooth/aidl/default/BluetoothHci.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 <aidl/android/hardware/bluetooth/BnBluetoothHci.h>
-#include <aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.h>
-
-#include <future>
-#include <string>
-
-#include "async_fd_watcher.h"
-#include "h4_protocol.h"
-#include "net_bluetooth_mgmt.h"
-
-namespace aidl::android::hardware::bluetooth::impl {
-
-class BluetoothDeathRecipient;
-
-// This Bluetooth HAL implementation connects with a serial port at dev_path_.
-class BluetoothHci : public BnBluetoothHci {
- public:
- BluetoothHci(const std::string& dev_path = "/dev/hvc5");
-
- ndk::ScopedAStatus initialize(
- const std::shared_ptr<IBluetoothHciCallbacks>& cb) override;
-
- ndk::ScopedAStatus sendHciCommand(
- const std::vector<uint8_t>& packet) override;
-
- ndk::ScopedAStatus sendAclData(const std::vector<uint8_t>& packet) override;
-
- ndk::ScopedAStatus sendScoData(const std::vector<uint8_t>& packet) override;
-
- ndk::ScopedAStatus sendIsoData(const std::vector<uint8_t>& packet) override;
-
- ndk::ScopedAStatus close() override;
-
- static void OnPacketReady();
-
- static BluetoothHci* get();
-
- private:
- int mFd{-1};
- std::shared_ptr<IBluetoothHciCallbacks> mCb = nullptr;
-
- std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
-
- std::shared_ptr<BluetoothDeathRecipient> mDeathRecipient;
-
- std::string mDevPath;
-
- ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
-
- int getFdFromDevPath();
- [[nodiscard]] ndk::ScopedAStatus send(
- ::android::hardware::bluetooth::hci::PacketType type,
- const std::vector<uint8_t>& packet);
- std::unique_ptr<NetBluetoothMgmt> management_{};
-
- // Send a reset command and discard all packets until a reset is received.
- void reset();
-
- // Don't close twice or open before close is complete
- std::mutex mStateMutex;
- enum class HalState {
- READY,
- INITIALIZING,
- ONE_CLIENT,
- CLOSING,
- } mState{HalState::READY};
-};
-
-} // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/main.rs b/bluetooth/aidl/default/main.rs
new file mode 100644
index 0000000..b30162a
--- /dev/null
+++ b/bluetooth/aidl/default/main.rs
@@ -0,0 +1,58 @@
+// 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.
+
+use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHci::{
+ self,
+ IBluetoothHci as _
+};
+use android_hardware_bluetooth::binder;
+use bluetooth_offload_hal::{ HciHalProxy, CInterface };
+use bluetooth_offload_leaudio_hci::LeAudioModuleBuilder;
+use log;
+use std::panic;
+
+fn new_hal() -> CInterface {
+ extern "C" { fn hal_new() -> CInterface; }
+ unsafe { hal_new() }
+}
+
+fn main() {
+ logger::init(
+ logger::Config::default()
+ .with_max_level(log::LevelFilter::Debug)
+ .with_tag_on_device("android.hardware.bluetooth"),
+ );
+
+ panic::set_hook(Box::new(|panic_info| {
+ log::error!("{}", panic_info);
+ }));
+
+ log::info!("Bluetooth HAL starting up");
+
+ binder::ProcessState::set_thread_pool_max_thread_count(0);
+ binder::ProcessState::start_thread_pool();
+
+ binder::add_service(
+ &format!("{}/default", IBluetoothHci::BpBluetoothHci::get_descriptor()),
+ IBluetoothHci::BnBluetoothHci::new_binder(
+ HciHalProxy::new(
+ vec![ Box::new(LeAudioModuleBuilder {}) ],
+ new_hal()
+ ),
+ binder::BinderFeatures::default(),
+ ).as_binder()
+ ).expect("Failed to register service");
+
+ binder::ProcessState::join_thread_pool();
+}
diff --git a/bluetooth/aidl/default/service.cpp b/bluetooth/aidl/default/service.cpp
deleted file mode 100644
index ef4b884..0000000
--- a/bluetooth/aidl/default/service.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "aidl.android.hardware.bluetooth.service.default"
-
-#include <aidl/android/hardware/bluetooth/IBluetoothHci.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-
-#include "BluetoothHci.h"
-
-using ::aidl::android::hardware::bluetooth::impl::BluetoothHci;
-using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::joinRpcThreadpool;
-
-int main(int /* argc */, char** /* argv */) {
- ALOGI("Bluetooth HAL starting");
- if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
- ALOGI("failed to set thread pool max thread count");
- return 1;
- }
-
- std::shared_ptr<BluetoothHci> service =
- ndk::SharedRefBase::make<BluetoothHci>();
- std::string instance = std::string() + BluetoothHci::descriptor + "/default";
- auto result =
- AServiceManager_addService(service->asBinder().get(), instance.c_str());
- if (result == STATUS_OK) {
- ABinderProcess_joinThreadPool();
- } else {
- ALOGE("Could not register as a service!");
- }
- return 0;
-}
diff --git a/bluetooth/aidl/default/test/fuzzer.cpp b/bluetooth/aidl/default/test/fuzzer.cpp
deleted file mode 100644
index e7a1eef..0000000
--- a/bluetooth/aidl/default/test/fuzzer.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.
- */
-
-#include <fuzzbinder/libbinder_ndk_driver.h>
-#include <fuzzer/FuzzedDataProvider.h>
-
-#include "BluetoothHci.h"
-
-using aidl::android::hardware::bluetooth::impl::BluetoothHci;
-using android::fuzzService;
-using ndk::SharedRefBase;
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- auto service = SharedRefBase::make<BluetoothHci>();
-
- fuzzService(service->asBinder().get(), FuzzedDataProvider(data, size));
-
- return 0;
-}
diff --git a/compatibility_matrices/bump.py b/compatibility_matrices/bump.py
index 91f58d4..bbc4a11 100755
--- a/compatibility_matrices/bump.py
+++ b/compatibility_matrices/bump.py
@@ -14,9 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-"""
-Creates the next compatibility matrix.
-"""
+"""Creates the next compatibility matrix."""
import argparse
import os
@@ -27,177 +25,354 @@
def check_call(*args, **kwargs):
- print(args)
- subprocess.check_call(*args, **kwargs)
+ print(args)
+ subprocess.check_call(*args, **kwargs)
def check_output(*args, **kwargs):
- print(args)
- return subprocess.check_output(*args, **kwargs)
+ print(args)
+ return subprocess.check_output(*args, **kwargs)
class Bump(object):
- def __init__(self, cmdline_args):
- self.top = pathlib.Path(os.environ["ANDROID_BUILD_TOP"])
- self.interfaces_dir = self.top / "hardware/interfaces"
+ def __init__(self, cmdline_args):
+ self.top = pathlib.Path(os.environ["ANDROID_BUILD_TOP"])
+ self.interfaces_dir = self.top / "hardware/interfaces"
- self.current_level = cmdline_args.current_level
- self.current_letter = cmdline_args.current_letter
- self.current_version = cmdline_args.platform_version
- self.next_version = cmdline_args.next_platform_version
- self.current_module_name = f"framework_compatibility_matrix.{self.current_level}.xml"
- self.current_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.current_level}.xml"
- self.device_module_name = "framework_compatibility_matrix.device.xml"
+ self.current_level = cmdline_args.current_level
+ self.current_letter = cmdline_args.current_letter
+ self.current_version = cmdline_args.platform_version
+ self.next_version = cmdline_args.next_platform_version
+ self.current_module_name = (
+ f"framework_compatibility_matrix.{self.current_level}.xml"
+ )
+ self.current_xml = (
+ self.interfaces_dir
+ / f"compatibility_matrices/compatibility_matrix.{self.current_level}.xml"
+ )
+ self.device_module_name = "framework_compatibility_matrix.device.xml"
- self.next_level = cmdline_args.next_level
- self.next_letter = cmdline_args.next_letter
- self.next_module_name = f"framework_compatibility_matrix.{self.next_level}.xml"
- self.next_xml = self.interfaces_dir / f"compatibility_matrices/compatibility_matrix.{self.next_level}.xml"
+ self.next_level = cmdline_args.next_level
+ self.next_letter = cmdline_args.next_letter
+ self.current_sdk = cmdline_args.current_sdk
+ self.next_sdk = cmdline_args.next_sdk
+ self.next_module_name = (
+ f"framework_compatibility_matrix.{self.next_level}.xml"
+ )
+ self.next_xml = (
+ self.interfaces_dir
+ / f"compatibility_matrices/compatibility_matrix.{self.next_level}.xml"
+ )
- def run(self):
- self.bump_kernel_configs()
- self.copy_matrix()
- self.edit_android_bp()
- self.bump_libvintf()
+ def run(self):
+ self.bump_kernel_configs()
+ self.copy_matrix()
+ self.edit_android_bp()
+ self.bump_libvintf()
+ self.bump_libvts_vintf()
+ self.bump_cuttlefish()
- def bump_kernel_configs(self):
- check_call([
- self.top / "kernel/configs/tools/bump.py",
- self.current_letter.lower(),
- self.next_letter.lower(),
- ])
+ def bump_kernel_configs(self):
+ check_call([
+ self.top / "kernel/configs/tools/bump.py",
+ self.current_letter.lower(),
+ self.next_letter.lower(),
+ ])
- def copy_matrix(self):
- with open(self.current_xml) as f_current, open(self.next_xml, "w") as f_next:
- f_next.write(f_current.read().replace(f"level=\"{self.current_level}\"", f"level=\"{self.next_level}\""))
+ def copy_matrix(self):
+ with open(self.current_xml) as f_current, open(
+ self.next_xml, "w"
+ ) as f_next:
+ f_next.write(
+ f_current.read().replace(
+ f'level="{self.current_level}"', f'level="{self.next_level}"'
+ )
+ )
- def edit_android_bp(self):
- android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp"
+ def edit_android_bp(self):
+ android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp"
- with open(android_bp, "r+") as f:
- if self.next_module_name not in f.read():
- f.seek(0, 2) # end of file
- f.write("\n")
- f.write(
- textwrap.dedent(f"""\
+ with open(android_bp, "r+") as f:
+ if self.next_module_name not in f.read():
+ f.seek(0, 2) # end of file
+ f.write("\n")
+ f.write(textwrap.dedent(f"""\
vintf_compatibility_matrix {{
name: "{self.next_module_name}",
}}
"""))
- next_kernel_configs = check_output(
- """grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""",
- cwd=self.top / "kernel/configs" /
- self.next_letter.lower(),
- text=True,
- shell=True,
- ).splitlines()
- print(next_kernel_configs)
+ next_kernel_configs = check_output(
+ """grep -rh name: | sed -E 's/^.*"(.*)".*/\\1/g'""",
+ cwd=self.top / "kernel/configs" / self.next_letter.lower(),
+ text=True,
+ shell=True,
+ ).splitlines()
+ print(next_kernel_configs)
- check_call([
- "bpmodify", "-w", "-m", self.next_module_name, "-property", "stem",
- "-str", self.next_xml.name, android_bp
- ])
+ check_call([
+ "bpmodify",
+ "-w",
+ "-m",
+ self.next_module_name,
+ "-property",
+ "stem",
+ "-str",
+ self.next_xml.name,
+ android_bp,
+ ])
- check_call([
- "bpmodify", "-w", "-m", self.next_module_name, "-property", "srcs",
- "-a",
- self.next_xml.relative_to(android_bp.parent), android_bp
- ])
+ check_call([
+ "bpmodify",
+ "-w",
+ "-m",
+ self.next_module_name,
+ "-property",
+ "srcs",
+ "-a",
+ self.next_xml.relative_to(android_bp.parent),
+ android_bp,
+ ])
- check_call([
- "bpmodify", "-w", "-m", self.next_module_name, "-property",
- "kernel_configs", "-a", " ".join(next_kernel_configs), android_bp
- ])
+ check_call([
+ "bpmodify",
+ "-w",
+ "-m",
+ self.next_module_name,
+ "-property",
+ "kernel_configs",
+ "-a",
+ " ".join(next_kernel_configs),
+ android_bp,
+ ])
- # update the SYSTEM_MATRIX_DEPS variable and the phony module's
- # product_variables entry.
- lines = []
- with open(android_bp) as f:
- for line in f:
- if f" \"{self.device_module_name}\",\n" in line:
- lines.append(f" \"{self.current_module_name}\",\n")
+ # Replace the phony module's product_variables entry to add the new FCM
+ # to the development targets (trunk* configs).
+ lines = []
+ with open(android_bp) as f:
+ for line in f:
+ if f' "{self.current_module_name}",\n' in line:
+ lines.append(f' "{self.next_module_name}",\n')
+ else:
+ lines.append(line)
- if f" \"{self.current_module_name}\",\n" in line:
- lines.append(f" \"{self.next_module_name}\",\n")
- else:
- lines.append(line)
+ with open(android_bp, "w") as f:
+ f.write("".join(lines))
- with open(android_bp, "w") as f:
- f.write("".join(lines))
-
- def bump_libvintf(self):
- if not self.current_version:
- print("Skip libvintf update...")
- return
- try:
- check_call(["grep", "-h",
- f"{self.next_letter.upper()} = {self.next_level}",
- f"{self.top}/system/libvintf/include/vintf/Level.h"])
- except subprocess.CalledProcessError:
- print("Adding new API level to libvintf")
- add_lines_above(f"{self.top}/system/libvintf/analyze_matrix/analyze_matrix.cpp",
- " case Level::UNSPECIFIED:",
- textwrap.indent(textwrap.dedent(f"""\
+ def bump_libvintf(self):
+ if not self.current_version:
+ print("Skip libvintf update...")
+ return
+ try:
+ check_call([
+ "grep",
+ "-h",
+ f"{self.next_letter.upper()} = {self.next_level}",
+ f"{self.top}/system/libvintf/include/vintf/Level.h",
+ ])
+ except subprocess.CalledProcessError:
+ print("Adding new API level to libvintf")
+ add_lines_above(
+ f"{self.top}/system/libvintf/analyze_matrix/analyze_matrix.cpp",
+ " case Level::UNSPECIFIED:",
+ textwrap.indent(
+ textwrap.dedent(
+ f"""\
case Level::{self.next_letter.upper()}:
- return "Android {self.next_version} ({self.next_letter.upper()})";"""),
- " "*2))
- add_lines_above(f"{self.top}/system/libvintf/include/vintf/Level.h",
- " // To add new values:",
- f" {self.next_letter.upper()} = {self.next_level},")
- add_lines_above(f"{self.top}/system/libvintf/include/vintf/Level.h",
- " Level::UNSPECIFIED,",
- f" Level::{self.next_letter.upper()},")
- add_lines_above(f"{self.top}/system/libvintf/RuntimeInfo.cpp",
- " // Add more levels above this line.",
- textwrap.indent(textwrap.dedent(f"""\
+ return "Android {self.next_version} ({self.next_letter.upper()})";"""
+ ),
+ " " * 2,
+ ),
+ )
+ add_lines_above(
+ f"{self.top}/system/libvintf/include/vintf/Level.h",
+ " // To add new values:",
+ f" {self.next_letter.upper()} = {self.next_level},",
+ )
+ add_lines_above(
+ f"{self.top}/system/libvintf/include/vintf/Level.h",
+ " Level::UNSPECIFIED,",
+ f" Level::{self.next_letter.upper()},",
+ )
+ add_lines_above(
+ f"{self.top}/system/libvintf/RuntimeInfo.cpp",
+ " // Add more levels above this line.",
+ textwrap.indent(
+ textwrap.dedent(f"""\
case {self.next_version}: {{
ret = Level::{self.next_letter.upper()};
}} break;"""),
- " "*3))
+ " " * 3,
+ ),
+ )
+
+ def bump_libvts_vintf(self):
+ if not self.current_version:
+ print("Skip libvts_vintf update...")
+ return
+ try:
+ check_call([
+ "grep",
+ "-h",
+ f"{self.next_level}, Level::{self.next_letter.upper()}",
+ f"{self.top}/test/vts-testcase/hal/treble/vintf/libvts_vintf_test_common/common.cpp",
+ ])
+ print("libvts_vintf is already up-to-date")
+ except subprocess.CalledProcessError:
+ print("Adding new API level to libvts_vintf")
+ add_lines_below(
+ f"{self.top}/test/vts-testcase/hal/treble/vintf/libvts_vintf_test_common/common.cpp",
+ f" {{{self.current_level},"
+ f" Level::{self.current_letter.upper()}}},",
+ f" {{{self.next_level},"
+ f" Level::{self.next_letter.upper()}}},\n",
+ )
+
+ def bump_cuttlefish(self):
+ if not self.next_sdk:
+ print("Skip Cuttlefish update...")
+ return
+ cf_mk_file = f"{self.top}/device/google/cuttlefish/shared/device.mk"
+ try:
+ check_call([
+ "grep",
+ "-h",
+ f"PRODUCT_SHIPPING_API_LEVEL := {self.next_sdk}",
+ cf_mk_file,
+ ])
+ print("Cuttlefish is already up-to-date")
+ except subprocess.CalledProcessError:
+ print("Bumping Cuttlefish to the next SHIPPING_API_LEVEL")
+ final_lines = []
+ with open(cf_mk_file, "r+") as f:
+ for line in f:
+ if f"PRODUCT_SHIPPING_API_LEVEL := {self.current_sdk}" in line:
+ final_lines.append(
+ f"PRODUCT_SHIPPING_API_LEVEL := {self.next_sdk}\n"
+ )
+ elif line.startswith("PRODUCT_SHIPPING_API_LEVEL :="):
+ # this is the previous SDK level.
+ final_lines.append(
+ f"PRODUCT_SHIPPING_API_LEVEL := {self.current_sdk}\n"
+ )
+ else:
+ final_lines.append(line)
+ f.seek(0)
+ f.write("".join(final_lines))
+ f.truncate()
+ final_lines = []
+ with open(
+ f"{self.top}/device/google/cuttlefish/shared/config/previous_manifest.xml",
+ "r+",
+ ) as f:
+ for line in f:
+ if "target-level=" in line:
+ final_lines.append(
+ '<manifest version="1.0" type="device"'
+ f' target-level="{self.current_level}">\n'
+ )
+ else:
+ final_lines.append(line)
+ f.seek(0)
+ f.write("".join(final_lines))
+ f.truncate()
+
+ final_lines = []
+ with open(
+ f"{self.top}/device/google/cuttlefish/shared/config/manifest.xml", "r+"
+ ) as f:
+ for line in f:
+ if "target-level=" in line:
+ final_lines.append(
+ '<manifest version="1.0" type="device"'
+ f' target-level="{self.next_level}">\n'
+ )
+ else:
+ final_lines.append(line)
+ f.seek(0)
+ f.write("".join(final_lines))
+ f.truncate()
def add_lines_above(file, pattern, lines):
- with open(file, 'r+') as f:
- text = f.read()
- split_text = re.split(rf"\n{pattern}\n", text)
- if len(split_text) != 2:
- # Only one pattern must be found, otherwise the source must be
- # changed unexpectedly.
- raise Exception(
- f'Pattern "{pattern}" not found or multiple patterns found in {file}')
- f.seek(0)
- f.write(f"\n{lines}\n{pattern}\n".join(split_text))
- f.truncate()
+ with open(file, "r+") as f:
+ text = f.read()
+ split_text = re.split(rf"\n{pattern}\n", text)
+ if len(split_text) != 2:
+ # Only one pattern must be found, otherwise the source must be
+ # changed unexpectedly.
+ raise Exception(
+ f'Pattern "{pattern}" not found or multiple patterns found in {file}'
+ )
+ f.seek(0)
+ f.write(f"\n{lines}\n{pattern}\n".join(split_text))
+ f.truncate()
+
+
+def add_lines_below(file, pattern, lines):
+ final_lines = []
+ with open(file, "r+") as f:
+ for line in f:
+ final_lines.append(line)
+ if pattern in line:
+ final_lines.append(lines)
+ f.seek(0)
+ f.write("".join(final_lines))
+ f.truncate()
def main():
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument("current_level",
- type=str,
- help="VINTF level of the current version (e.g. 202404)")
- parser.add_argument("next_level",
- type=str,
- help="VINTF level of the next version (e.g. 202504)")
- parser.add_argument("current_letter",
- type=str,
- help="Letter of the API level of the current version (e.g. b)")
- parser.add_argument("next_letter",
- type=str,
- help="Letter of the API level of the next version (e.g. c)")
- parser.add_argument("platform_version",
- type=str,
- nargs="?",
- help="Current Android release version number (e.g. 16)")
- parser.add_argument("next_platform_version",
- type=str,
- nargs="?",
- help="Next Android release version number number (e.g. 17)")
- cmdline_args = parser.parse_args()
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "current_level",
+ type=str,
+ help="VINTF level of the current version (e.g. 202404)",
+ )
+ parser.add_argument(
+ "next_level",
+ type=str,
+ help="VINTF level of the next version (e.g. 202504)",
+ )
+ parser.add_argument(
+ "current_letter",
+ type=str,
+ help="Letter of the API level of the current version (e.g. b)",
+ )
+ parser.add_argument(
+ "next_letter",
+ type=str,
+ help="Letter of the API level of the next version (e.g. c)",
+ )
+ parser.add_argument(
+ "platform_version",
+ type=str,
+ nargs="?",
+ help="Current Android release version number (e.g. 16)",
+ )
+ parser.add_argument(
+ "next_platform_version",
+ type=str,
+ nargs="?",
+ help="Next Android release version number number (e.g. 17)",
+ )
+ parser.add_argument(
+ "current_sdk",
+ type=str,
+ nargs="?",
+ help="Version of the current SDK API level (e.g. 36)",
+ )
+ parser.add_argument(
+ "next_sdk",
+ type=str,
+ nargs="?",
+ help="Version of the next SDK API level(e.g. 37)",
+ )
- Bump(cmdline_args).run()
+ cmdline_args = parser.parse_args()
+
+ Bump(cmdline_args).run()
if __name__ == "__main__":
- main()
+ main()
diff --git a/compatibility_matrices/finalize.py b/compatibility_matrices/finalize.py
new file mode 100755
index 0000000..1938278
--- /dev/null
+++ b/compatibility_matrices/finalize.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2025 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.
+#
+"""Finalizes the current compatibility matrix and allows `next` targets to
+
+use the new FCM.
+"""
+
+import argparse
+import os
+import pathlib
+import re
+import subprocess
+import textwrap
+
+
+def check_call(*args, **kwargs):
+ print(args)
+ subprocess.check_call(*args, **kwargs)
+
+
+def check_output(*args, **kwargs):
+ print(args)
+ return subprocess.check_output(*args, **kwargs)
+
+
+class Bump(object):
+
+ def __init__(self, cmdline_args):
+ self.top = pathlib.Path(os.environ["ANDROID_BUILD_TOP"])
+ self.interfaces_dir = self.top / "hardware/interfaces"
+
+ self.current_level = cmdline_args.current_level
+ self.current_module_name = (
+ f"framework_compatibility_matrix.{self.current_level}.xml"
+ )
+ self.device_module_name = "framework_compatibility_matrix.device.xml"
+
+ def run(self):
+ self.edit_android_bp()
+
+ def edit_android_bp(self):
+ android_bp = self.interfaces_dir / "compatibility_matrices/Android.bp"
+
+ # update the SYSTEM_MATRIX_DEPS variable to unconditionally include the
+ # latests FCM. This adds the file to `next` configs so releasing devices
+ # can use the latest interfaces.
+ lines = []
+ with open(android_bp) as f:
+ for line in f:
+ if f' "{self.device_module_name}",\n' in line:
+ lines.append(f' "{self.current_module_name}",\n')
+
+ lines.append(line)
+
+ with open(android_bp, "w") as f:
+ f.write("".join(lines))
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "current_level",
+ type=str,
+ help="VINTF level of the current version (e.g. 202404)",
+ )
+ cmdline_args = parser.parse_args()
+
+ Bump(cmdline_args).run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 7ef445e..9d90440 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -270,13 +270,9 @@
*/
// @VsrTest = 7.1-003.001
TEST(NonParameterizedTests, equalUdsPubInDiceCertChainForRkpVmAndPrimaryKeyMintInstances) {
- int vendorApiLevel = get_vendor_api_level();
- if (vendorApiLevel < 202504 && !AServiceManager_isDeclared(RKPVM_INSTANCE_NAME.c_str())) {
+ if (!AServiceManager_isDeclared(RKPVM_INSTANCE_NAME.c_str())) {
GTEST_SKIP() << "The RKP VM (" << RKPVM_INSTANCE_NAME << ") is not present on this device.";
}
- if (vendorApiLevel >= 202504) {
- ASSERT_TRUE(AServiceManager_isDeclared(RKPVM_INSTANCE_NAME.c_str()));
- }
auto rkpVmRpc = getHandle<IRemotelyProvisionedComponent>(RKPVM_INSTANCE_NAME);
ASSERT_NE(rkpVmRpc, nullptr) << "The RKP VM (" << RKPVM_INSTANCE_NAME