Merge "[Aidl] Add LUT HAL" into main
diff --git a/audio/OWNERS b/audio/OWNERS
index 3671685..80e2765 100644
--- a/audio/OWNERS
+++ b/audio/OWNERS
@@ -2,3 +2,4 @@
elaurent@google.com
mnaganov@google.com
+yaoshunkai@google.com
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 7b8cfb1..5539177 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -242,4 +242,17 @@
LOG(VERBOSE) << __func__ << " : signal client for reopen";
return RetCode::SUCCESS;
}
+
+RetCode EffectContext::enable() {
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::disable() {
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::reset() {
+ return RetCode::SUCCESS;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 7192d97..3e61335 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -246,7 +246,6 @@
startThread();
break;
case CommandId::STOP:
- case CommandId::RESET:
RETURN_OK_IF(mState == State::IDLE);
mState = State::IDLE;
RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
@@ -254,6 +253,13 @@
stopThread();
RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
break;
+ case CommandId::RESET:
+ mState = State::IDLE;
+ RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagNotEmptyFailed");
+ stopThread();
+ RETURN_IF_ASTATUS_NOT_OK(commandImpl(command), "commandImplFailed");
+ break;
default:
LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -266,8 +272,22 @@
ndk::ScopedAStatus EffectImpl::commandImpl(CommandId command) {
RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
- if (command == CommandId::RESET) {
- mImplContext->resetBuffer();
+ switch (command) {
+ case CommandId::START:
+ mImplContext->enable();
+ break;
+ case CommandId::STOP:
+ mImplContext->disable();
+ break;
+ case CommandId::RESET:
+ mImplContext->disable();
+ mImplContext->reset();
+ mImplContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << __func__ << " commandId " << toString(command) << " not supported";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "commandIdNotSupported");
}
return ndk::ScopedAStatus::ok();
}
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 275378e..02a4caa 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -82,6 +82,10 @@
virtual ::android::hardware::EventFlag* getStatusEventFlag();
+ virtual RetCode enable();
+ virtual RetCode disable();
+ virtual RetCode reset();
+
protected:
int mVersion = 0;
size_t mInputFrameSize = 0;
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index cad1195..0fa170f 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -397,10 +397,10 @@
outputBuffer.size(), outputBuffer));
}
+ // Disable the process
ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, outputBuffer));
- // Disable the process
ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
}
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 67eb837..7a43d7b 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -389,10 +389,10 @@
if (isLockoutTimerStarted) isLockoutTimerAborted = true;
}
-void FakeFingerprintEngine::clearLockout(ISessionCallback* cb) {
+void FakeFingerprintEngine::clearLockout(ISessionCallback* cb, bool dueToTimeout) {
Fingerprint::cfg().set<bool>("lockout", false);
cb->onLockoutCleared();
- mLockoutTracker.reset();
+ mLockoutTracker.reset(dueToTimeout);
}
ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*/, int32_t /*x*/,
@@ -536,7 +536,7 @@
void FakeFingerprintEngine::lockoutTimerExpired(ISessionCallback* cb) {
BEGIN_OP(0);
if (!isLockoutTimerAborted) {
- clearLockout(cb);
+ clearLockout(cb, true);
}
isLockoutTimerStarted = false;
isLockoutTimerAborted = false;
diff --git a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
index a056db5..7d46845 100644
--- a/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeLockoutTracker.cpp
@@ -23,8 +23,11 @@
namespace aidl::android::hardware::biometrics::fingerprint {
-void FakeLockoutTracker::reset() {
- mFailedCount = 0;
+void FakeLockoutTracker::reset(bool dueToTimeout) {
+ if (!dueToTimeout) {
+ mFailedCount = 0;
+ }
+ mFailedCountTimed = 0;
mLockoutTimedStart = 0;
mCurrentMode = LockoutMode::kNone;
}
@@ -33,6 +36,7 @@
bool enabled = Fingerprint::cfg().get<bool>("lockout_enable");
if (enabled) {
mFailedCount++;
+ mFailedCountTimed++;
int32_t lockoutTimedThreshold =
Fingerprint::cfg().get<std::int32_t>("lockout_timed_threshold");
int32_t lockoutPermanetThreshold =
@@ -40,7 +44,7 @@
if (mFailedCount >= lockoutPermanetThreshold) {
mCurrentMode = LockoutMode::kPermanent;
Fingerprint::cfg().set<bool>("lockout", true);
- } else if (mFailedCount >= lockoutTimedThreshold) {
+ } else if (mFailedCountTimed >= lockoutTimedThreshold) {
if (mCurrentMode == LockoutMode::kNone) {
mCurrentMode = LockoutMode::kTimed;
mLockoutTimedStart = Util::getSystemNanoTime();
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 0d53575..362d0df 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -110,7 +110,7 @@
std::pair<Error, int32_t> convertError(int32_t code);
int32_t getRandomInRange(int32_t bound1, int32_t bound2);
bool checkSensorLockout(ISessionCallback*);
- void clearLockout(ISessionCallback* cb);
+ void clearLockout(ISessionCallback* cb, bool dueToTimeout = false);
void waitForFingerDown(ISessionCallback* cb, const std::future<void>& cancel);
FakeLockoutTracker mLockoutTracker;
diff --git a/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
index a1b6128..a7f2f8e 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeLockoutTracker.h
@@ -24,12 +24,12 @@
class FakeLockoutTracker {
public:
- FakeLockoutTracker() : mFailedCount(0) {}
+ FakeLockoutTracker() : mFailedCount(0), mFailedCountTimed(0) {}
~FakeLockoutTracker() {}
enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
- void reset();
+ void reset(bool dueToTimeout = false);
LockoutMode getMode();
void addFailedAttempt();
int64_t getLockoutTimeLeft();
@@ -44,6 +44,7 @@
private:
int32_t mFailedCount;
+ int32_t mFailedCountTimed;
int64_t mLockoutTimedStart;
LockoutMode mCurrentMode;
};
diff --git a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
index 3c12b6d..4c1277b 100644
--- a/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
+++ b/biometrics/fingerprint/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -75,7 +75,7 @@
prevTimeLeft = currTimeLeft;
}
ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
- mLockoutTracker.reset();
+ mLockoutTracker.reset(true);
}
TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index d0f2a26..a458c5b 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -139,21 +139,36 @@
<< toString(session_type_);
return;
}
+ } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
} else {
LOG(ERROR) << __func__ << " invalid SessionType ="
<< toString(session_type_);
return;
}
} else {
- if (session_type_ !=
- SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
- session_type_ !=
+ if (session_type_ ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type_ ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
- return;
- }
- if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
- LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
- << toString(session_type_);
+ if (audio_config.getTag() != AudioConfiguration::leAudioConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
+ } else if(session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(ERROR) << __func__ << " invalid audio config type for SessionType ="
+ << toString(session_type_);
+ return;
+ }
+ } else {
+ LOG(ERROR) << __func__
+ << " invalid SessionType =" << toString(session_type_);
return;
}
}
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index f3a3681..125f14c 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -30,6 +30,9 @@
sdk_version: "module_current",
enabled: false,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 82666ae..49c8410 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -52,6 +52,7 @@
#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
+#include <com_android_graphics_libgui_flags.h>
#include <cutils/properties.h>
#include <fmq/MessageQueue.h>
#include <grallocusage/GrallocUsageConversion.h>
@@ -8714,16 +8715,25 @@
ASSERT_NE(nullptr, bufferItemConsumer);
ASSERT_NE(nullptr, bufferHandler);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+ *bufferItemConsumer = new BufferItemConsumer(
+ GraphicBuffer::USAGE_HW_TEXTURE); // Use GLConsumer default usage flags
+#else
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
*bufferItemConsumer = new BufferItemConsumer(consumer,
GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
ASSERT_NE(nullptr, (*bufferItemConsumer).get());
*bufferHandler = new BufferItemHander(*bufferItemConsumer);
ASSERT_NE(nullptr, (*bufferHandler).get());
(*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+ sp<Surface> surface = (*bufferItemConsumer)->getSurface();
+#else
sp<Surface> surface = new Surface(producer);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
auto rc = device->setPreviewWindow(previewCb);
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index c055caa..faad35a 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -28,6 +28,9 @@
cpp: {
enabled: false,
},
+ rust: {
+ enabled: true,
+ },
},
versions_with_info: [
{
diff --git a/common/fmq/aidl/Android.bp b/common/fmq/aidl/Android.bp
index 9c1b45d..4a3658e 100644
--- a/common/fmq/aidl/Android.bp
+++ b/common/fmq/aidl/Android.bp
@@ -35,8 +35,7 @@
ndk: {
apex_available: [
"//apex_available:platform",
- "com.android.btservices",
- "com.android.media.swcodec",
+ "//apex_available:anyapex",
],
min_sdk_version: "29",
},
diff --git a/compatibility_matrices/clear_vars.mk b/compatibility_matrices/clear_vars.mk
index 0e53885..3c62377 100644
--- a/compatibility_matrices/clear_vars.mk
+++ b/compatibility_matrices/clear_vars.mk
@@ -16,10 +16,6 @@
# Clear input variables to BUILD_FRAMEWORK_COMPATIBILITY_MATRIX
LOCAL_ADD_VBMETA_VERSION :=
-LOCAL_ADD_VBMETA_VERSION_OVERRIDE :=
LOCAL_ASSEMBLE_VINTF_ENV_VARS :=
-LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE :=
-LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE :=
LOCAL_ASSEMBLE_VINTF_FLAGS :=
-LOCAL_KERNEL_CONFIG_DATA_PATHS :=
LOCAL_GEN_FILE_DEPENDENCIES :=
diff --git a/compatibility_matrices/compatibility_matrix.mk b/compatibility_matrices/compatibility_matrix.mk
index d22e510..64cd645 100644
--- a/compatibility_matrices/compatibility_matrix.mk
+++ b/compatibility_matrices/compatibility_matrix.mk
@@ -29,11 +29,7 @@
# (corresponds to <avb><vbmeta-version> tag)
# LOCAL_ASSEMBLE_VINTF_ENV_VARS: Add a list of environment variable names from global variables in
# the build system that is lazily evaluated (e.g. PRODUCT_ENFORCE_VINTF_MANIFEST).
-# LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE: Add a list of environment variables that is local to
-# assemble_vintf invocation. Format is "VINTF_ENFORCE_NO_UNUSED_HALS=true".
# LOCAL_ASSEMBLE_VINTF_FLAGS: Add additional command line arguments to assemble_vintf invocation.
-# LOCAL_KERNEL_CONFIG_DATA_PATHS: Paths to search for kernel config requirements. Format for each is
-# <kernel version x.y.z>:<path that contains android-base*.config>.
# LOCAL_GEN_FILE_DEPENDENCIES: A list of additional dependencies for the generated file.
ifndef LOCAL_MODULE
@@ -64,15 +60,11 @@
ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION)))
ifeq (true,$(BOARD_AVB_ENABLE))
$(GEN): $(AVBTOOL)
-# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
-# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
-# is a file, here.
$(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
# Use deferred assignment (=) instead of immediate assignment (:=).
# Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
$(GEN): FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
--print_required_libavb_version \
- $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
$(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
else
$(GEN): FRAMEWORK_VBMETA_VERSION := 0.0
@@ -80,43 +72,17 @@
$(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION
endif # LOCAL_ADD_VBMETA_VERSION
-ifeq (true,$(strip $(LOCAL_ADD_VBMETA_VERSION_OVERRIDE)))
-ifneq ($(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE),)
-$(GEN): FRAMEWORK_VBMETA_VERSION_OVERRIDE := $(BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE)
-$(GEN): PRIVATE_ENV_VARS += FRAMEWORK_VBMETA_VERSION_OVERRIDE
-endif
-endif
-
-ifneq (,$(strip $(LOCAL_KERNEL_CONFIG_DATA_PATHS)))
-$(GEN): PRIVATE_KERNEL_CONFIG_DATA_PATHS := $(LOCAL_KERNEL_CONFIG_DATA_PATHS)
-$(GEN): $(foreach pair,$(LOCAL_KERNEL_CONFIG_DATA_PATHS),\
- $(wildcard $(call word-colon,2,$(pair))/android-base*.config))
-$(GEN): PRIVATE_FLAGS += $(foreach pair,$(PRIVATE_KERNEL_CONFIG_DATA_PATHS),\
- --kernel=$(call word-colon,1,$(pair)):$(call normalize-path-list,\
- $(wildcard $(call word-colon,2,$(pair))/android-base*.config)))
-endif
-
my_matrix_src_files := \
$(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) \
$(LOCAL_GENERATED_SOURCES)
-$(GEN): PRIVATE_ADDITIONAL_ENV_VARS := $(LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE)
-
-ifneq (,$(strip $(LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE)))
-$(GEN): PRIVATE_COMMAND_TAIL := || (echo $(strip $(LOCAL_ASSEMBLE_VINTF_ERROR_MESSAGE)) && false)
-endif
-
$(GEN): PRIVATE_SRC_FILES := $(my_matrix_src_files)
$(GEN): $(my_matrix_src_files) $(HOST_OUT_EXECUTABLES)/assemble_vintf
- $(foreach varname,$(PRIVATE_ENV_VARS),\
- $(if $(findstring $(varname),$(PRIVATE_ADDITIONAL_ENV_VARS)),\
- $(error $(varname) should not be overridden by LOCAL_ASSEMBLE_VINTF_ENV_VARS_OVERRIDE.)))
$(foreach varname,$(PRIVATE_ENV_VARS),$(varname)="$($(varname))") \
- $(PRIVATE_ADDITIONAL_ENV_VARS) \
$(HOST_OUT_EXECUTABLES)/assemble_vintf \
-i $(call normalize-path-list,$(PRIVATE_SRC_FILES)) \
-o $@ \
- $(PRIVATE_FLAGS) $(PRIVATE_COMMAND_TAIL)
+ $(PRIVATE_FLAGS)
LOCAL_PREBUILT_MODULE_FILE := $(GEN)
LOCAL_SRC_FILES :=
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index ba15421..eaf23b5 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1845,7 +1845,7 @@
writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
execute();
const auto errors = mReader.takeErrors();
- EXPECT_EQ(1, errors.size());
+ ASSERT_EQ(1, errors.size());
EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
return;
diff --git a/health/utils/libhealthloop/Android.bp b/health/utils/libhealthloop/Android.bp
index b266f67..4ebc575 100644
--- a/health/utils/libhealthloop/Android.bp
+++ b/health/utils/libhealthloop/Android.bp
@@ -21,6 +21,17 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
+bpf {
+ name: "filterPowerSupplyEvents.o",
+ srcs: ["filterPowerSupplyEvents.c"],
+ // "vendor: true" because all binaries that use this BPF filter are vendor
+ // binaries.
+ vendor: true,
+}
+
+// Since "required" sections are ignored in static library definitions,
+// filterPowerSupplyEvents.o has been added in
+// build/make/target/product/base_vendor.mk.
cc_library_static {
name: "libhealthloop",
vendor_available: true,
@@ -34,6 +45,7 @@
"libcutils",
],
header_libs: [
+ "bpf_headers",
"libbatteryservice_headers",
"libhealthd_headers",
"libutils_headers",
@@ -42,3 +54,30 @@
"include",
],
}
+
+genrule {
+ name: "filterPowerSupplyEvents.h",
+ out: ["filterPowerSupplyEvents.h"],
+ srcs: [":filterPowerSupplyEvents.o"],
+ cmd: "cat $(in) | od -v -tx1 | cut -c9- | grep -v '^$$' | sed 's/^/0x/;s/ /, 0x/g;s/^, //;s/$$/,/' > $(out)",
+}
+
+cc_test_host {
+ name: "filterPowerSupplyEventsTest",
+ team: "trendy_team_pixel_system_sw_storage",
+ srcs: [
+ "filterPowerSupplyEventsTest.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbpf",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
+ generated_headers: [
+ "filterPowerSupplyEvents.h",
+ "libbpf_headers",
+ ],
+ compile_multilib: "64",
+}
diff --git a/health/utils/libhealthloop/HealthLoop.cpp b/health/utils/libhealthloop/HealthLoop.cpp
index 4190769..70b7745 100644
--- a/health/utils/libhealthloop/HealthLoop.cpp
+++ b/health/utils/libhealthloop/HealthLoop.cpp
@@ -20,23 +20,22 @@
#include <health/HealthLoop.h>
#include <errno.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/epoll.h>
+#include <sys/epoll.h> // epoll_create1(), epoll_ctl(), epoll_wait()
#include <sys/timerfd.h>
-#include <unistd.h>
+#include <unistd.h> // read()
#include <android-base/logging.h>
#include <batteryservice/BatteryService.h>
-#include <cutils/klog.h>
+#include <cutils/klog.h> // KLOG_*()
#include <cutils/uevent.h>
#include <healthd/healthd.h>
-#include <utils/Errors.h>
+#include <BpfSyscallWrappers.h>
#include <health/utils.h>
+using android::base::ErrnoError;
+using android::base::Result;
+using android::base::unique_fd;
using namespace android;
using namespace std::chrono_literals;
@@ -57,19 +56,18 @@
int HealthLoop::RegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
CHECK(!reject_event_register_);
- auto* event_handler =
- event_handlers_
- .emplace_back(std::make_unique<EventHandler>(EventHandler{this, fd, func}))
- .get();
+ auto* event_handler = event_handlers_
+ .emplace_back(std::make_unique<EventHandler>(
+ EventHandler{this, fd, std::move(func)}))
+ .get();
- struct epoll_event ev;
-
- ev.events = EPOLLIN;
+ struct epoll_event ev = {
+ .events = EPOLLIN | EPOLLERR,
+ .data.ptr = reinterpret_cast<void*>(event_handler),
+ };
if (wakeup == EVENT_WAKEUP_FD) ev.events |= EPOLLWAKEUP;
- ev.data.ptr = reinterpret_cast<void*>(event_handler);
-
if (epoll_ctl(epollfd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
KLOG_ERROR(LOG_TAG, "epoll_ctl failed; errno=%d\n", errno);
return -1;
@@ -122,11 +120,16 @@
ScheduleBatteryUpdate();
}
-// TODO(b/140330870): Use BPF instead.
#define UEVENT_MSG_LEN 2048
-void HealthLoop::UeventEvent(uint32_t /*epevents*/) {
+void HealthLoop::UeventEvent(uint32_t epevents) {
// No need to lock because uevent_fd_ is guaranteed to be initialized.
+ if (epevents & EPOLLERR) {
+ // The netlink receive buffer overflowed.
+ ScheduleBatteryUpdate();
+ return;
+ }
+
char msg[UEVENT_MSG_LEN + 2];
char* cp;
int n;
@@ -152,8 +155,26 @@
}
}
+// Attach a BPF filter to the @uevent_fd file descriptor. This fails in recovery mode because BPF is
+// not supported in recovery mode. This fails for kernel versions 5.4 and before because the BPF
+// program is rejected by the BPF verifier of older kernels.
+Result<void> HealthLoop::AttachFilter(int uevent_fd) {
+ static const char prg[] =
+ "/sys/fs/bpf/vendor/prog_filterPowerSupplyEvents_skfilter_power_supply";
+ int filter_fd(bpf::retrieveProgram(prg));
+ if (filter_fd < 0) {
+ return ErrnoError() << "failed to load BPF program " << prg;
+ }
+ if (setsockopt(uevent_fd, SOL_SOCKET, SO_ATTACH_BPF, &filter_fd, sizeof(filter_fd)) < 0) {
+ close(filter_fd);
+ return ErrnoError() << "failed to attach BPF program";
+ }
+ close(filter_fd);
+ return {};
+}
+
void HealthLoop::UeventInit(void) {
- uevent_fd_.reset(uevent_open_socket(64 * 1024, true));
+ uevent_fd_.reset(uevent_create_socket(64 * 1024, true));
if (uevent_fd_ < 0) {
KLOG_ERROR(LOG_TAG, "uevent_init: uevent_open_socket failed\n");
@@ -161,8 +182,25 @@
}
fcntl(uevent_fd_, F_SETFL, O_NONBLOCK);
+
+ Result<void> attach_result = AttachFilter(uevent_fd_);
+ if (!attach_result.ok()) {
+ std::string error_msg = attach_result.error().message();
+ error_msg +=
+ ". This is expected in recovery mode and also for kernel versions before 5.10.";
+ KLOG_WARNING(LOG_TAG, "%s", error_msg.c_str());
+ } else {
+ KLOG_INFO(LOG_TAG, "Successfully attached the BPF filter to the uevent socket");
+ }
+
if (RegisterEvent(uevent_fd_, &HealthLoop::UeventEvent, EVENT_WAKEUP_FD))
KLOG_ERROR(LOG_TAG, "register for uevent events failed\n");
+
+ if (uevent_bind(uevent_fd_.get()) < 0) {
+ uevent_fd_.reset();
+ KLOG_ERROR(LOG_TAG, "uevent_init: binding socket failed\n");
+ return;
+ }
}
void HealthLoop::WakeAlarmEvent(uint32_t /*epevents*/) {
diff --git a/health/utils/libhealthloop/filterPowerSupplyEvents.c b/health/utils/libhealthloop/filterPowerSupplyEvents.c
new file mode 100644
index 0000000..5296993
--- /dev/null
+++ b/health/utils/libhealthloop/filterPowerSupplyEvents.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include <bpf_helpers.h> // load_word()
+#include <linux/bpf.h> // struct __sk_buff
+#include <linux/netlink.h> // struct nlmsghdr
+#include <stdint.h> // uint32_t
+
+// M4: match 4 bytes. Returns 0 if all bytes match.
+static inline uint32_t M4(struct __sk_buff* skb, unsigned int offset, uint8_t c0, uint8_t c1,
+ uint8_t c2, uint8_t c3) {
+ return load_word(skb, offset) ^ ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
+}
+
+// M2: match 2 bytes. Returns 0 if all bytes match.
+static inline uint16_t M2(struct __sk_buff* skb, unsigned int offset, uint8_t c0, uint8_t c1) {
+ return load_half(skb, offset) ^ ((c0 << 8) | c1);
+}
+
+// M1: match 1 byte. Returns 0 in case of a match.
+static inline uint8_t M1(struct __sk_buff* skb, unsigned int offset, uint8_t c0) {
+ return load_byte(skb, offset) ^ c0;
+}
+
+// Match "\0SUBSYSTEM=". Returns 0 in case of a match.
+#define MATCH_SUBSYSTEM_LENGTH 11
+static inline uint32_t match_subsystem(struct __sk_buff* skb, unsigned int offset) {
+ return M4(skb, offset + 0, '\0', 'S', 'U', 'B') | M4(skb, offset + 4, 'S', 'Y', 'S', 'T') |
+ M2(skb, offset + 8, 'E', 'M') | M1(skb, offset + 10, '=');
+}
+
+// Match "power_supply\0". Returns 0 in case of a match.
+#define MATCH_POWER_SUPPLY_LENGTH 13
+static inline uint32_t match_power_supply(struct __sk_buff* skb, unsigned int offset) {
+ return M4(skb, offset + 0, 'p', 'o', 'w', 'e') | M4(skb, offset + 4, 'r', '_', 's', 'u') |
+ M4(skb, offset + 8, 'p', 'p', 'l', 'y') | M1(skb, offset + 12, '\0');
+}
+
+// The Linux kernel 5.4 BPF verifier rejects this program, probably because of its size. Hence the
+// restriction that the kernel version must be at least 5.10.
+DEFINE_BPF_PROG_KVER("skfilter/power_supply", AID_ROOT, AID_SYSTEM, filterPowerSupplyEvents,
+ KVER(5, 10, 0))
+(struct __sk_buff* skb) {
+ uint32_t i;
+
+ // The first character matched by match_subsystem() is a '\0'. Starting
+ // right past the netlink message header is fine since the SUBSYSTEM= text
+ // never occurs at the start. See also the kobject_uevent_env() implementation:
+ // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/lib/kobject_uevent.c?#n473
+ // The upper bound of this loop has been chosen not to exceed the maximum
+ // number of instructions in a BPF program (BPF loops are unrolled).
+ for (i = sizeof(struct nlmsghdr); i < 256; ++i) {
+ if (i + MATCH_SUBSYSTEM_LENGTH > skb->len) {
+ break;
+ }
+ if (match_subsystem(skb, i) == 0) {
+ goto found_subsystem;
+ }
+ }
+
+ // The SUBSYSTEM= text has not been found in the bytes that have been
+ // examined: let the user space software perform filtering.
+ return skb->len;
+
+found_subsystem:
+ i += MATCH_SUBSYSTEM_LENGTH;
+ if (i + MATCH_POWER_SUPPLY_LENGTH <= skb->len && match_power_supply(skb, i) == 0) {
+ return skb->len;
+ }
+ return 0;
+}
+
+LICENSE("Apache 2.0");
+CRITICAL("healthd");
diff --git a/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
new file mode 100644
index 0000000..e885f0b
--- /dev/null
+++ b/health/utils/libhealthloop/filterPowerSupplyEventsTest.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include <android-base/unique_fd.h>
+#include <bpf/libbpf.h>
+#include <gtest/gtest.h>
+#include <linux/bpf.h> // SO_ATTACH_BPF
+#include <linux/netlink.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <string>
+#include <string_view>
+
+#define ASSERT_UNIX_OK(e) ASSERT_GE(e, 0) << strerror(errno)
+
+// TODO(bvanassche): remove the code below. See also b/357099095.
+#ifndef SO_ATTACH_BPF
+#define SO_ATTACH_BPF 50 // From <asm-generic/socket.h>.
+#endif
+
+using ::android::base::unique_fd;
+using ::testing::ScopedTrace;
+
+struct test_data {
+ bool discarded;
+ std::string_view str;
+};
+
+static const uint8_t binary_bpf_prog[] = {
+#include "filterPowerSupplyEvents.h"
+};
+
+static std::vector<std::unique_ptr<ScopedTrace>>* msg_vec;
+
+std::ostream& operator<<(std::ostream& os, const test_data& td) {
+ os << "{.discarded=" << td.discarded << ", .str=";
+ for (auto c : td.str) {
+ if (isprint(c)) {
+ os << c;
+ } else {
+ os << ".";
+ }
+ }
+ return os << '}';
+}
+
+#define RECORD_ERR_MSG(fmt, ...) \
+ do { \
+ char* str; \
+ if (asprintf(&str, fmt, ##__VA_ARGS__) < 0) break; \
+ auto st = std::make_unique<ScopedTrace>(__FILE__, __LINE__, str); \
+ msg_vec->emplace_back(std::move(st)); \
+ free(str); \
+ } while (0)
+
+int libbpf_print_fn(enum libbpf_print_level, const char* fmt, va_list args) {
+ char* str;
+ if (vasprintf(&str, fmt, args) < 0) {
+ return 0;
+ }
+ msg_vec->emplace_back(std::make_unique<ScopedTrace>(__FILE__, -1, str));
+ free(str);
+ return 0;
+}
+
+static void record_libbpf_output() {
+ libbpf_set_print(libbpf_print_fn);
+}
+
+class filterPseTest : public testing::TestWithParam<test_data> {};
+
+struct ConnectedSockets {
+ unique_fd write_fd;
+ unique_fd read_fd;
+};
+
+// socketpair() only supports AF_UNIX sockets. AF_UNIX sockets do not
+// support BPF filters. Hence connect two TCP sockets with each other.
+static ConnectedSockets ConnectSockets(int domain, int type, int protocol) {
+ int _server_fd = socket(domain, type, protocol);
+ if (_server_fd < 0) {
+ return {};
+ }
+ unique_fd server_fd(_server_fd);
+
+ int _write_fd = socket(domain, type, protocol);
+ if (_write_fd < 0) {
+ RECORD_ERR_MSG("socket: %s", strerror(errno));
+ return {};
+ }
+ unique_fd write_fd(_write_fd);
+
+ struct sockaddr_in sa = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY};
+ if (bind(_server_fd, (const struct sockaddr*)&sa, sizeof(sa)) < 0) {
+ RECORD_ERR_MSG("bind: %s", strerror(errno));
+ return {};
+ }
+ if (listen(_server_fd, 1) < 0) {
+ RECORD_ERR_MSG("listen: %s", strerror(errno));
+ return {};
+ }
+ socklen_t addr_len = sizeof(sa);
+ if (getsockname(_server_fd, (struct sockaddr*)&sa, &addr_len) < 0) {
+ RECORD_ERR_MSG("getsockname: %s", strerror(errno));
+ return {};
+ }
+ errno = 0;
+ if (connect(_write_fd, (const struct sockaddr*)&sa, sizeof(sa)) < 0 && errno != EINPROGRESS) {
+ RECORD_ERR_MSG("connect: %s", strerror(errno));
+ return {};
+ }
+ int _read_fd = accept(_server_fd, NULL, NULL);
+ if (_read_fd < 0) {
+ RECORD_ERR_MSG("accept: %s", strerror(errno));
+ return {};
+ }
+ unique_fd read_fd(_read_fd);
+
+ return {.write_fd = std::move(write_fd), .read_fd = std::move(read_fd)};
+}
+
+TEST_P(filterPseTest, filterPse) {
+ if (getuid() != 0) {
+ GTEST_SKIP() << "Must be run as root.";
+ return;
+ }
+ if (!msg_vec) {
+ msg_vec = new typeof(*msg_vec);
+ }
+ std::unique_ptr<int, void (*)(int*)> clear_msg_vec_at_end_of_scope(new int, [](int* p) {
+ msg_vec->clear();
+ delete p;
+ });
+ record_libbpf_output();
+
+ auto connected_sockets = ConnectSockets(AF_INET, SOCK_STREAM, 0);
+ unique_fd write_fd = std::move(connected_sockets.write_fd);
+ unique_fd read_fd = std::move(connected_sockets.read_fd);
+
+ ASSERT_UNIX_OK(fcntl(read_fd, F_SETFL, O_NONBLOCK));
+
+ bpf_object* obj = bpf_object__open_mem(binary_bpf_prog, sizeof(binary_bpf_prog), NULL);
+ ASSERT_TRUE(obj) << "bpf_object__open() failed" << strerror(errno);
+
+ // Find the BPF program within the object.
+ bpf_program* prog = bpf_object__find_program_by_name(obj, "filterPowerSupplyEvents");
+ ASSERT_TRUE(prog);
+
+ ASSERT_UNIX_OK(bpf_program__set_type(prog, BPF_PROG_TYPE_SOCKET_FILTER));
+
+ ASSERT_UNIX_OK(bpf_object__load(obj));
+
+ int filter_fd = bpf_program__fd(prog);
+ ASSERT_UNIX_OK(filter_fd);
+
+ int setsockopt_result =
+ setsockopt(read_fd, SOL_SOCKET, SO_ATTACH_BPF, &filter_fd, sizeof(filter_fd));
+ ASSERT_UNIX_OK(setsockopt_result);
+
+ const test_data param = GetParam();
+ const std::string header(sizeof(struct nlmsghdr), '\0');
+ ASSERT_EQ(header.length(), sizeof(struct nlmsghdr));
+ const std::string data = header + std::string(param.str);
+ const size_t len = data.length();
+ std::cerr.write(data.data(), data.length());
+ std::cerr << ")\n";
+ ASSERT_EQ(write(write_fd, data.data(), len), len);
+ std::array<uint8_t, 512> read_buf;
+ int bytes_read = read(read_fd, read_buf.data(), read_buf.size());
+ if (bytes_read < 0) {
+ ASSERT_EQ(errno, EAGAIN);
+ bytes_read = 0;
+ } else {
+ ASSERT_LT(bytes_read, read_buf.size());
+ }
+ EXPECT_EQ(bytes_read, param.discarded ? 0 : len);
+
+ bpf_object__close(obj);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ filterPse, filterPseTest,
+ testing::Values(test_data{false, "a"},
+ test_data{true, std::string_view("abc\0SUBSYSTEM=block\0", 20)},
+ test_data{true, std::string_view("\0SUBSYSTEM=block", 16)},
+ test_data{true, std::string_view("\0SUBSYSTEM=power_supply", 23)},
+ test_data{false, std::string_view("\0SUBSYSTEM=power_supply\0", 24)},
+ test_data{
+ false,
+ "012345678901234567890123456789012345678901234567890123456789012345"
+ "678901234567890123456789012345678901234567890123456789012345678901"
+ "234567890123456789012345678901234567890123456789012345678901234567"
+ "890123456789012345678901234567890123456789\0SUBSYSTEM=block\0"}));
diff --git a/health/utils/libhealthloop/include/health/HealthLoop.h b/health/utils/libhealthloop/include/health/HealthLoop.h
index fc3066e..1af7274 100644
--- a/health/utils/libhealthloop/include/health/HealthLoop.h
+++ b/health/utils/libhealthloop/include/health/HealthLoop.h
@@ -20,6 +20,7 @@
#include <mutex>
#include <vector>
+#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <healthd/healthd.h>
@@ -87,6 +88,7 @@
};
int InitInternal();
+ static android::base::Result<void> AttachFilter(int uevent_fd);
void MainLoop();
void WakeAlarmInit();
void WakeAlarmEvent(uint32_t);
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index 2fc9e65..6d4936b 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -108,7 +108,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -118,7 +118,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_GE(6ul, res.args->last_data_.size());
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
if (res.args->last_data_.size() == 6) {
@@ -127,7 +127,7 @@
EXPECT_EQ(4ul, res.args->last_data_.size());
nci_version = NCI_VERSION_2;
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
}
/*
@@ -137,14 +137,14 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -153,7 +153,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -186,7 +186,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
/* The response/notification format for CORE_RESET_CMD differs
* with NCI 1.0 and 2.0. */
@@ -200,7 +200,7 @@
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
// Check if reset trigger was due to CORE_RESET_CMD
EXPECT_LE(8ul, res.args->last_data_.size());
EXPECT_EQ(2ul, res.args->last_data_[3]);
@@ -221,7 +221,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
/* The response/notification format for CORE_RESET_CMD differs
* with NCI 1.0 and 2.0. */
@@ -235,7 +235,7 @@
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
// Check if reset trigger was due to CORE_RESET_CMD
EXPECT_LE(8ul, res.args->last_data_.size());
EXPECT_EQ(2ul, res.args->last_data_[3]);
@@ -257,7 +257,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(4ul, res.args->last_data_.size());
EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
}
@@ -277,14 +277,14 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
/* NCI 2.0 sends CORE_RESET_NTF everytime. */
if (nci_version == NCI_VERSION_2) {
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
cmd = CORE_INIT_CMD_NCI20;
} else {
cmd = CORE_INIT_CMD;
@@ -294,7 +294,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_INIT_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
// Send an Error Data Packet
cmd = INVALID_COMMAND;
@@ -307,7 +307,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for response with SYNTAX_ERROR
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(4ul, res.args->last_data_.size());
EXPECT_EQ(SYNTAX_ERROR, res.args->last_data_[3]);
}
@@ -317,7 +317,7 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_CONN_CREATE_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(7ul, res.args->last_data_.size());
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
}
@@ -335,14 +335,14 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_RESET_RSP
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
/* NCI 2.0 sends CORE_RESET_NTF everytime. */
if (nci_version == NCI_VERSION_2) {
// Wait for CORE_RESET_NTF
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
cmd = CORE_INIT_CMD_NCI20;
} else {
cmd = CORE_INIT_CMD;
@@ -352,15 +352,15 @@
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_INIT_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
cmd = CORE_CONN_CREATE_CMD;
data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
// Wait for CORE_CONN_CREATE_RSP
res = nfc_cb_->WaitForCallback(kCallbackNameSendData);
- EXPECT_TRUE(res.no_timeout);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(7ul, res.args->last_data_.size());
EXPECT_EQ((int)NfcStatus::OK, res.args->last_data_[3]);
uint8_t conn_id = res.args->last_data_[6];
@@ -414,7 +414,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
// Wait for NfcEvent.OPEN_CPLT
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -428,7 +428,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -437,7 +437,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -464,7 +464,7 @@
EXPECT_EQ(NfcStatus::OK, status);
// Wait for NfcEvent.POST_INIT_CPLT
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::POST_INIT_CPLT, res.args->last_event_);
}
}
@@ -487,7 +487,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -496,7 +496,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -518,7 +518,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -527,7 +527,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -541,7 +541,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::CLOSE_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
@@ -550,7 +550,7 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
@@ -564,14 +564,14 @@
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
// Wait for OPEN_CPLT event
res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
- EXPECT_TRUE(res.no_timeout);
+ ASSERT_TRUE(res.no_timeout);
EXPECT_EQ(NfcEvent::OPEN_CPLT, res.args->last_event_);
EXPECT_EQ(NfcStatus::OK, res.args->last_status_);
}
diff --git a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
index 3c43238..40cf685 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
+++ b/security/rkp/aidl/android/hardware/security/keymint/generateCertificateRequestV2.cddl
@@ -62,9 +62,13 @@
SignerName = tstr
UdsCertChain = [
- 2* X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed
- ; cert, "Leaf" contains UDS_Public. There may also be
- ; intermediate certificates between Root and Leaf.
+ + X509Certificate ; Root -> ... -> Leaf. "Root" is the vendor self-signed
+ ; cert, "Leaf" contains UDS_Public. It's recommended to
+ ; have at least 3 certificates in the chain.
+ ; The Root certificate is recommended to be generated in an air-gapped,
+ ; HSM-based secure environment. The intermediate signing keys may be
+ ; online, and should be rotated regularly (e.g. annually). Additionally,
+ ; the intermediate certificates may contain product family identifiers.
]
; A bstr containing a DER-encoded X.509 certificate (RSA, NIST P-curve, or EdDSA)
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index 82a76e0..51e5c25 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -90,10 +90,20 @@
installable: false,
}
+filegroup {
+ name: "com.android.hardware.threadnetwork_manifest",
+ srcs: ["manifest.json"],
+}
+
+filegroup {
+ name: "com.android.hardware.threadnetwork_file_contexts",
+ srcs: ["file_contexts"],
+}
+
apex {
name: "com.android.hardware.threadnetwork",
- manifest: "manifest.json",
- file_contexts: "file_contexts",
+ manifest: ":com.android.hardware.threadnetwork_manifest",
+ file_contexts: ":com.android.hardware.threadnetwork_file_contexts",
key: "com.android.hardware.key",
certificate: ":com.android.hardware.certificate",
updatable: false,
@@ -110,3 +120,21 @@
"android.hardware.thread_network.prebuilt.xml", // permission
],
}
+
+prebuilt_etc {
+ name: "threadnetwork-service-simulation-rcp.rc",
+ src: "threadnetwork-service-simulation-rcp.rc",
+ installable: false,
+}
+
+// Thread HAL service which uses a simulation RCP (i.e. ot-rcp),
+// typically used in emulator devices.
+override_apex {
+ name: "com.android.hardware.threadnetwork-simulation-rcp",
+ base: "com.android.hardware.threadnetwork",
+ prebuilts: [
+ "threadnetwork-service-simulation-rcp.rc",
+ "threadnetwork-default.xml",
+ "android.hardware.thread_network.prebuilt.xml",
+ ],
+}
diff --git a/threadnetwork/aidl/default/threadnetwork-service-simulation-rcp.rc b/threadnetwork/aidl/default/threadnetwork-service-simulation-rcp.rc
new file mode 100644
index 0000000..3b889eb
--- /dev/null
+++ b/threadnetwork/aidl/default/threadnetwork-service-simulation-rcp.rc
@@ -0,0 +1,3 @@
+service vendor.threadnetwork_hal /apex/com.android.hardware.threadnetwork/bin/hw/android.hardware.threadnetwork-service spinel+hdlc+forkpty:///apex/com.android.hardware.threadnetwork/bin/ot-rcp?forkpty-arg=1
+ class hal
+ user thread_network