Merge "Remove access to unlabeled vsock_socket"
diff --git a/agl_services_build/CMakeLists.txt b/agl_services_build/CMakeLists.txt
index 5676fbe..a59b5ad 100644
--- a/agl_services_build/CMakeLists.txt
+++ b/agl_services_build/CMakeLists.txt
@@ -24,6 +24,7 @@
# ========== vehicle hal server build settings ===================
set(trout_ANDROID_SYSCORE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/android/system_core)
set(trout_FMTLIB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmtlib)
+ set(trout_GOOGLETEST_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest)
set(trout_GRPC_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/grpc-grpc)
set(trout_JSONCPP_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/jsoncpp)
set(trout_NATIVE_VHAL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/default_native_vehicle_hal)
@@ -33,7 +34,7 @@
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/vehicle_hal_server/agl_build)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/watchdog_test_server)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/vehicle_hal_server/garage_mode_helper)
- add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/audiocontrol/agl_build)
+ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/audiocontrol/aidl/1.0/agl_build)
else()
# ========== grpc host tools ===================
diff --git a/agl_services_build/build.sh b/agl_services_build/build.sh
index 69efc6e..155b132 100755
--- a/agl_services_build/build.sh
+++ b/agl_services_build/build.sh
@@ -48,6 +48,7 @@
build_agl_service android_audio_controller
build_agl_service android_audio_controller_test
build_agl_service dumpstate_grpc_server
+build_agl_service dumpstate_tests
build_agl_service garage_mode_helper
build_agl_service vehicle_hal_grpc_server
build_agl_service watchdog_test_service
diff --git a/agl_services_build/cmake/default_native_vhal.cmake b/agl_services_build/cmake/default_native_vhal.cmake
index 14af169..4de5e20 100644
--- a/agl_services_build/cmake/default_native_vhal.cmake
+++ b/agl_services_build/cmake/default_native_vhal.cmake
@@ -6,6 +6,7 @@
set(trout_NAVTIVE_VHAL_LIBRARIES "vhal_default_impl_lib")
set(trout_NAVTIVE_VHAL_COMMON_INCLUDE_DIRS
+ "${trout_NATIVE_VHAL_ROOT_DIR}"
"${trout_NATIVE_VHAL_ROOT_DIR}/common/include"
"${trout_NATIVE_VHAL_ROOT_DIR}/common/include/vhal_v2_0")
set(trout_NAVTIVE_VHAL_IMPL_INCLUDE_DIRS "${trout_NATIVE_VHAL_ROOT_DIR}/impl")
diff --git a/agl_services_build/cmake/googletest.cmake b/agl_services_build/cmake/googletest.cmake
new file mode 100644
index 0000000..d2e0ee7
--- /dev/null
+++ b/agl_services_build/cmake/googletest.cmake
@@ -0,0 +1,16 @@
+if(NOT trout_GOOGLETEST_ROOT_DIR)
+ set(trout_GOOGLETEST_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest)
+endif()
+
+if(EXISTS "${trout_GOOGLETEST_ROOT_DIR}/CMakeLists.txt")
+ if(TARGET ${_trout_GOOGLETEST_LIBRARY_NAME})
+ set(trout_GOOGLETEST_LIBRARIES ${_trout_GOOGLETEST_LIBRARY_NAME})
+ else()
+ set(trout_GOOGLETEST_LIBRARIES "gtest")
+ endif()
+ if (NOT TARGET ${trout_GOOGLETEST_LIBRARIES})
+ add_subdirectory(${trout_GOOGLETEST_ROOT_DIR} third_party/googletest)
+ endif()
+else()
+ message(FATAL_ERROR "${trout_GOOGLETEST_ROOT_DIR}/CMakeLists.txt not found")
+endif()
diff --git a/agl_services_build/newrepo.sh b/agl_services_build/newrepo.sh
index 524b541..1dd54c0 100755
--- a/agl_services_build/newrepo.sh
+++ b/agl_services_build/newrepo.sh
@@ -16,7 +16,7 @@
#
bash_src_dir=$(realpath $(dirname ${BASH_SOURCE[0]}))
-dest_dir=$(realpath "$1")
+dest_dir=$(realpath "${1:-$PWD}")
echo Initializing an AGL Server build at "${dest_dir}"
mkdir -p "${dest_dir}/manifest"
diff --git a/agl_services_build/repo_manifest.xml b/agl_services_build/repo_manifest.xml
index bb533d1..a99e31f 100644
--- a/agl_services_build/repo_manifest.xml
+++ b/agl_services_build/repo_manifest.xml
@@ -14,12 +14,12 @@
<manifest-server url="http://android-smartsync.corp.google.com/googleplex-android.googlesource.com/manifestserver" />
- <project path="device/google/trout" name="device/google/trout" groups="device,trout,gull" remote="goog-and-upload-partner" dest-branch="rvc-dev" revision="mirror-partner-rvc-dev">
+ <project path="device/google/trout" name="device/google/trout" groups="device,trout,gull" remote="goog-and-upload-partner" dest-branch="master" revision="mirror-partner-master">
<linkfile src="agl_services_build/build.sh" dest="build.sh" />
<linkfile src="agl_services_build/CMakeLists.txt" dest="CMakeLists.txt" />
<linkfile src="agl_services_build/cmake" dest="cmake" />
<linkfile src="agl_services_build/toolchain" dest="toolchain" />
- <linkfile src="hal/audiocontrol/2.0" dest="audiocontrol" />
+ <linkfile src="hal/audiocontrol/aidl/1.0" dest="audiocontrol" />
<linkfile src="hal/dumpstate/1.1" dest="dumpstate_server" />
<linkfile src="hal/vehicle/2.0" dest="vehicle_hal_server" />
<linkfile src="hal/common/agl/watchdog" dest="watchdog_test_server" />
@@ -37,5 +37,6 @@
<project path="third_party/boringssl" name="boringssl" remote="boringssl" groups="pdk" revision="0b710a305b42b67522003a314dea3e3868485665" />
<project path="third_party/gflags" name="gflags/gflags" remote="github" groups="pdk" revision="28f50e0fed19872e0fd50dd23ce2ee8cd759338e" />
<project path="third_party/zlib" name="madler/zlib" remote="github" groups="pdk" revision="cacf7f1d4e3d44d871b605da3b647f07d718623f" />
+ <project path="third_party/googletest" name="google/googletest" remote="github" groups="pdk" revision="1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7" />
</manifest>
diff --git a/agl_services_build/yocto-layer/meta-google/recipes-trout/agl-services/sources.inc b/agl_services_build/yocto-layer/meta-google/recipes-trout/agl-services/sources.inc
index 1495ef1..7eb418e 100644
--- a/agl_services_build/yocto-layer/meta-google/recipes-trout/agl-services/sources.inc
+++ b/agl_services_build/yocto-layer/meta-google/recipes-trout/agl-services/sources.inc
@@ -43,7 +43,7 @@
device/google/trout/agl_services_build/CMakeLists.txt:CMakeLists.txt \
device/google/trout/agl_services_build/cmake:cmake \
device/google/trout/agl_services_build/toolchain:toolchain \
- device/google/trout/hal/audiocontrol/2.0:audiocontrol \
+ device/google/trout/hal/audiocontrol/aidl/1.0:audiocontrol \
device/google/trout/hal/dumpstate/1.1:dumpstate_server \
device/google/trout/hal/vehicle/2.0:vehicle_hal_server \
device/google/trout/hal/common/agl/watchdog:watchdog_test_server \
diff --git a/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/dumpstate_grpc_server.service b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/dumpstate_grpc_server.service
new file mode 100644
index 0000000..72289fb
--- /dev/null
+++ b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/dumpstate_grpc_server.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Android Dumpstate GRPC Server
+
+Wants=coqos-virtio-vsock.service
+After=coqos-virtio-vsock.service
+
+[Service]
+ExecStart=/usr/bin/dumpstate_grpc_server -server_addr vsock:2:9310
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/multi-user.target.wants/dumpstate_grpc_server.service b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/multi-user.target.wants/dumpstate_grpc_server.service
new file mode 120000
index 0000000..e2a37ae
--- /dev/null
+++ b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/multi-user.target.wants/dumpstate_grpc_server.service
@@ -0,0 +1 @@
+/etc/systemd/system/dumpstate_grpc_server.service
\ No newline at end of file
diff --git a/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/multi-user.target.wants/vehicle_hal_grpc_server.service b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/multi-user.target.wants/vehicle_hal_grpc_server.service
new file mode 120000
index 0000000..533ed97
--- /dev/null
+++ b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/multi-user.target.wants/vehicle_hal_grpc_server.service
@@ -0,0 +1 @@
+/etc/systemd/system/vehicle_hal_grpc_server.service
\ No newline at end of file
diff --git a/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/vehicle_hal_grpc_server.service b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/vehicle_hal_grpc_server.service
new file mode 100644
index 0000000..64d950f
--- /dev/null
+++ b/agl_services_build/yocto-layer/meta-google/recipes-trout/images/machine-image/sa81x5/google-overlay/etc/systemd/system/vehicle_hal_grpc_server.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Android Vehicle HAL GRPC Server
+
+Wants=coqos-virtio-vsock.service
+After=coqos-virtio-vsock.service
+
+[Service]
+ExecStart=/usr/bin/vehicle_hal_grpc_server -server_cid 2 -server_port 9210 -power_state_file /tmp/power_state_marker -power_state_socket /tmp/power_state_socket
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
diff --git a/aosp_trout_arm64.mk b/aosp_trout_arm64.mk
index e7d0bef..1f04a33 100644
--- a/aosp_trout_arm64.mk
+++ b/aosp_trout_arm64.mk
@@ -14,7 +14,10 @@
# limitations under the License.
#
-$(call inherit-product, device/google/cuttlefish/vsoc_arm64/auto/aosp_cf.mk)
+$(call inherit-product, device/google/cuttlefish/vsoc_arm64_only/auto/aosp_cf.mk)
+
+# Package ramdisk.img in target package
+BOARD_IMG_USE_RAMDISK := true
# Audio HAL
TARGET_USES_CUTTLEFISH_AUDIO ?= false
diff --git a/aosp_trout_common.mk b/aosp_trout_common.mk
index 1ff308d..565a255 100644
--- a/aosp_trout_common.mk
+++ b/aosp_trout_common.mk
@@ -46,10 +46,10 @@
endif
# Audio Control HAL
-LOCAL_AUDIOCONTROL_HAL_PRODUCT_PACKAGE ?= android.hardware.audiocontrol@2.0-service.trout
+LOCAL_AUDIOCONTROL_HAL_PRODUCT_PACKAGE ?= android.hardware.automotive.audiocontrol-service.trout
# Dumpstate HAL
-LOCAL_DUMPSTATE_PRODUCT_PACKAGE ?= android.hardware.dumpstate@1.1-service.trout
+LOCAL_DUMPSTATE_PRODUCT_PACKAGE ?= android.hardware.automotive.dumpstate-service.trout
LOCAL_DUMPSTATE_PROPERTIES ?= \
ro.vendor.dumpstate.server.cid=2 \
ro.vendor.dumpstate.server.port=9310 \
@@ -59,16 +59,12 @@
LOCAL_VHAL_PRODUCT_PACKAGE ?= android.hardware.automotive.vehicle@2.0-virtualization-service
# EVS HAL
-LOCAL_EVS_PRODUCT_PACKAGE ?= \
- android.automotive.evs.manager@1.1 \
- android.frameworks.automotive.display@1.0-service \
- android.hardware.automotive.evs@1.1-sample \
- evs_app \
-
LOCAL_EVS_PRODUCT_COPY_FILES ?= \
device/google/trout/product_files/etc/automotive/evs/config_override.json:${TARGET_COPY_OUT_SYSTEM}/etc/automotive/evs/config_override.json \
device/google/trout/product_files/vendor/etc/automotive/evs/evs_configuration_override.xml:$(TARGET_COPY_OUT_VENDOR)/etc/automotive/evs/evs_configuration_override.xml \
+ENABLE_EVS_SAMPLE := true
+
BOARD_SEPOLICY_DIRS += device/google/trout/sepolicy/vendor/google
# Disable Vulkan feature flag as it is not supported on trout
@@ -80,6 +76,8 @@
${LOCAL_AUDIOCONTROL_PROPERTIES} \
${LOCAL_DUMPSTATE_PROPERTIES}
+PRODUCT_CHARACTERISTICS := nosdcard,automotive
+
TARGET_BOARD_INFO_FILE ?= device/google/trout/board-info.txt
# Keymaster HAL
@@ -88,18 +86,25 @@
# Gatekeeper HAL
LOCAL_GATEKEEPER_PRODUCT_PACKAGE ?= android.hardware.gatekeeper@1.0-service.software
-PRODUCT_PACKAGES += \
- tinyplay \
- ${LOCAL_EVS_PRODUCT_PACKAGE} \
+PRODUCT_PACKAGES += tinyplay
PRODUCT_COPY_FILES += \
${LOCAL_EVS_PRODUCT_COPY_FILES} \
-# TODO(b/162901005): Include computepipe once this project points to main.
-# include packages/services/Car/cpp/computepipe/products/computepipe.mk
+PRODUCT_COPY_FILES += \
+ ${LOCAL_EVS_PRODUCT_COPY_FILES} \
+
+include packages/services/Car/cpp/computepipe/products/computepipe.mk
# Trout fstab (workaround b/182190949)
PRODUCT_COPY_FILES += \
device/google/trout/product_files/fstab.trout:$(TARGET_COPY_OUT_RAMDISK)/fstab.trout \
device/google/trout/product_files/fstab.trout:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.trout \
device/google/trout/product_files/fstab.trout:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.trout
+
+# User HAL support
+TARGET_SUPPORTS_USER_HAL ?= true
+
+ifeq ($(TARGET_SUPPORTS_USER_HAL),true)
+PRODUCT_SYSTEM_DEFAULT_PROPERTIES += android.car.user_hal_enabled=true
+endif
diff --git a/aosp_trout_x86.mk b/aosp_trout_x86.mk
index b302f1c..93fe775 100644
--- a/aosp_trout_x86.mk
+++ b/aosp_trout_x86.mk
@@ -14,7 +14,10 @@
# limitations under the License.
#
-$(call inherit-product, device/google/cuttlefish/vsoc_x86/auto/device.mk)
+$(call inherit-product, device/google/cuttlefish/vsoc_x86/auto/aosp_cf.mk)
+
+# Audio HAL
+TARGET_USES_CUTTLEFISH_AUDIO ?= true
# Audio Control HAL
# TODO (chenhaosjtuacm, egranata): move them to kernel command line
@@ -28,9 +31,8 @@
DEVICE_MATRIX_FILE += device/google/trout/compatibility_matrix.xml
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE := device/google/trout/framework_compatibility_matrix.xml
-# TODO(b/162901005): Include computepipe once this project points to main.
-# PRODUCT_COPY_FILES += \
-# packages/services/Car/cpp/computepipe/products/init.computepipe.rc:$(TARGET_COPY_OUT_SYSTEM)/etc/init/computepipe.rc
+PRODUCT_COPY_FILES += \
+ packages/services/Car/cpp/computepipe/products/init.computepipe.rc:$(TARGET_COPY_OUT_SYSTEM)/etc/init/computepipe.rc
PRODUCT_NAME := aosp_trout_x86
PRODUCT_DEVICE := trout_x86
diff --git a/hal/audio/6.0/Android.bp b/hal/audio/6.0/Android.bp
index afe36ca..4e32c5f 100644
--- a/hal/audio/6.0/Android.bp
+++ b/hal/audio/6.0/Android.bp
@@ -22,7 +22,7 @@
cc_library_shared {
vendor: true,
- // vintf_fragments: ["android.hardware.audio@6.0-trout-impl.xml"],
+ vintf_fragments: ["android.hardware.audio@6.0-trout-impl.xml"],
name: "audio.primary.trout",
relative_install_path: "hw",
diff --git a/hal/audiocontrol/2.0/Android.bp b/hal/audiocontrol/2.0/Android.bp
deleted file mode 100644
index 4d1ec1a..0000000
--- a/hal/audiocontrol/2.0/Android.bp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-cc_defaults {
- name: "audio_control_hal_v2_0_default_trout",
- defaults: [
- "hidl_defaults",
- ],
- shared_libs: [
- "android.hardware.automotive.audiocontrol@2.0",
- "libbase",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
-}
-
-genrule {
- name: "AudioFocusControlProtoStub_h",
- tools: [
- "aprotoc",
- "protoc-gen-grpc-cpp-plugin",
- ],
- cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
- srcs: [
- "proto/AudioFocusControl.proto",
- ],
- out: [
- "AudioFocusControl.pb.h",
- "AudioFocusControl.grpc.pb.h",
- ],
-}
-
-genrule {
- name: "AudioFocusControlProtoStub_cc",
- tools: [
- "aprotoc",
- "protoc-gen-grpc-cpp-plugin",
- ],
- cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
- srcs: [
- "proto/AudioFocusControl.proto",
- ],
- out: [
- "AudioFocusControl.pb.cc",
- "AudioFocusControl.grpc.pb.cc",
- ],
-}
-
-cc_library {
- name: "android.hardware.audiocontrol@2.0-service-audio-control-grpc-server",
- vendor: true,
- defaults: ["audio_control_hal_v2_0_default_trout"],
- srcs: [
- "AudioControlServer.cpp",
- ],
- generated_headers: [
- "AudioFocusControlProtoStub_h",
- ],
- generated_sources: [
- "AudioFocusControlProtoStub_cc",
- ],
- shared_libs: [
- "libgrpc++",
- "libprotobuf-cpp-full",
- ],
- cflags: [
- "-Wno-unused-parameter",
- ],
-}
-
-cc_binary {
- name: "android.hardware.audiocontrol@2.0-service.trout",
- defaults: ["audio_control_hal_v2_0_default_trout"],
- vendor: true,
- relative_install_path: "hw",
- srcs: [
- "AudioControl.cpp",
- "CloseHandle.cpp",
- "service.cpp",
- "WatchdogClient.cpp"
- ],
- init_rc: ["android.hardware.audiocontrol@2.0-service.trout.rc"],
- static_libs: [
- "android.hardware.automotive.utils.vsockinfo",
- ],
- shared_libs: [
- "android.hardware.audiocontrol@2.0-service-audio-control-grpc-server",
- "android.hardware.automotive.utils.watchdog",
- "carwatchdog_aidl_interface-V2-ndk",
- "libbinder_ndk",
- "libcutils",
- ],
- vintf_fragments: ["manifest_android.hardware.audiocontrol@2.0-service.trout.xml"],
-}
diff --git a/hal/audiocontrol/2.0/AudioControl.cpp b/hal/audiocontrol/2.0/AudioControl.cpp
deleted file mode 100644
index 9c926fb..0000000
--- a/hal/audiocontrol/2.0/AudioControl.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2020 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 "trout.audiocontrol@2.0"
-
-#include "AudioControl.h"
-
-#include <android-base/logging.h>
-#include <hidl/HidlTransportSupport.h>
-
-#include "CloseHandle.h"
-
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
-
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_string;
-
-AudioControl::AudioControl(const std::string& audio_control_server_addr)
- : mAudioControlServer(MakeAudioControlServer(audio_control_server_addr)) {}
-
-Return<sp<ICloseHandle>> AudioControl::registerFocusListener(const sp<IFocusListener>& listener) {
- LOG(DEBUG) << "registering focus listener";
- sp<ICloseHandle> closeHandle(nullptr);
-
- if (listener) {
- closeHandle = new CloseHandle(mAudioControlServer->RegisterFocusListener(listener));
- } else {
- LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op.";
- }
-
- return closeHandle;
-}
-
-Return<void> AudioControl::setBalanceTowardRight(float) {
- return Void();
-}
-
-Return<void> AudioControl::setFadeTowardFront(float) {
- return Void();
-}
-
-Return<void> AudioControl::onAudioFocusChange(hidl_bitfield<AudioUsage> usage, int zoneId,
- hidl_bitfield<AudioFocusChange> focusChange) {
- LOG(INFO) << "Focus changed: " << toString(static_cast<AudioUsage>(focusChange))
- << " for usage " << toString(static_cast<AudioFocusChange>(usage)) << " in zone "
- << zoneId;
- return Void();
-}
-
-Return<void> AudioControl::debug(const hidl_handle&, const hidl_vec<hidl_string>&) {
- return Void();
-}
-
-bool AudioControl::isHealthy() {
- // TODO(egranata, chenhaosjtuacm): fill this in with a real check
- // e.g. add a heartbeat message to remote side
- return true;
-}
-
-void AudioControl::ServerStart() {
- mAudioControlServer->Start();
-}
-
-void AudioControl::ServerJoin() {
- mAudioControlServer->Join();
-}
-
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
diff --git a/hal/audiocontrol/2.0/AudioControl.h b/hal/audiocontrol/2.0/AudioControl.h
deleted file mode 100644
index a0c718e..0000000
--- a/hal/audiocontrol/2.0/AudioControl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android/hardware/audio/common/6.0/types.h>
-#include <android/hardware/automotive/audiocontrol/2.0/IAudioControl.h>
-#include <android/hardware/automotive/audiocontrol/2.0/ICloseHandle.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include "AudioControlServer.h"
-
-using android::hardware::audio::common::V6_0::AudioUsage;
-
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
-
-class AudioControl : public IAudioControl {
- public:
- explicit AudioControl(const std::string& audio_control_server_addr);
-
- bool isHealthy();
-
- void ServerStart();
-
- void ServerJoin();
-
- // Methods from ::android::hardware::automotive::audiocontrol::V2_0::IAudioControl follow.
- Return<sp<ICloseHandle>> registerFocusListener(const sp<IFocusListener>& listener);
- Return<void> onAudioFocusChange(hidl_bitfield<AudioUsage> usage, int zoneId,
- hidl_bitfield<AudioFocusChange> focusChange);
- Return<void> setBalanceTowardRight(float value) override;
- Return<void> setFadeTowardFront(float value) override;
- Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
-
- private:
- std::unique_ptr<AudioControlServer> mAudioControlServer;
-};
-
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
diff --git a/hal/audiocontrol/2.0/CloseHandle.cpp b/hal/audiocontrol/2.0/CloseHandle.cpp
deleted file mode 100644
index bc47931..0000000
--- a/hal/audiocontrol/2.0/CloseHandle.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2020 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 "CloseHandle.h"
-
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
-
-CloseHandle::CloseHandle(Callback callback) : mCallback(callback) {}
-
-CloseHandle::~CloseHandle() {
- close();
-}
-
-Return<void> CloseHandle::close() {
- const auto wasClosed = mIsClosed.exchange(true);
- if (wasClosed) return {};
-
- if (mCallback) mCallback();
- return {};
-}
-
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
diff --git a/hal/audiocontrol/2.0/CloseHandle.h b/hal/audiocontrol/2.0/CloseHandle.h
deleted file mode 100644
index 2378dea..0000000
--- a/hal/audiocontrol/2.0/CloseHandle.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <android-base/macros.h>
-#include <android/hardware/automotive/audiocontrol/2.0/ICloseHandle.h>
-
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
-
-/** Generic ICloseHandle implementation ignoring double-close events. */
-class CloseHandle : public ICloseHandle {
- public:
- using Callback = std::function<void()>;
-
- /**
- * Create a handle with a callback.
- *
- * The callback is guaranteed to be called exactly once.
- *
- * \param callback Called on the first close() call, or on destruction of the handle
- */
- explicit CloseHandle(Callback callback = nullptr);
- virtual ~CloseHandle();
-
- Return<void> close() override;
-
- private:
- const Callback mCallback;
- std::atomic<bool> mIsClosed = false;
-
- DISALLOW_COPY_AND_ASSIGN(CloseHandle);
-};
-
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
diff --git a/hal/audiocontrol/2.0/android.hardware.audiocontrol@2.0-service.trout.rc b/hal/audiocontrol/2.0/android.hardware.audiocontrol@2.0-service.trout.rc
deleted file mode 100644
index 0a91d83..0000000
--- a/hal/audiocontrol/2.0/android.hardware.audiocontrol@2.0-service.trout.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service vendor.audiocontrol-hal-2.0 /vendor/bin/hw/android.hardware.audiocontrol@2.0-service.trout
- class hal
- user audioserver
- group system
diff --git a/hal/audiocontrol/2.0/manifest_android.hardware.audiocontrol@2.0-service.trout.xml b/hal/audiocontrol/2.0/manifest_android.hardware.audiocontrol@2.0-service.trout.xml
index ace234a..2569d85 100644
--- a/hal/audiocontrol/2.0/manifest_android.hardware.audiocontrol@2.0-service.trout.xml
+++ b/hal/audiocontrol/2.0/manifest_android.hardware.audiocontrol@2.0-service.trout.xml
@@ -18,4 +18,4 @@
<instance>default</instance>
</interface>
</hal>
-</manifest>
+</manifest>
\ No newline at end of file
diff --git a/hal/audiocontrol/2.0/service.cpp b/hal/audiocontrol/2.0/service.cpp
deleted file mode 100644
index 0fe6605..0000000
--- a/hal/audiocontrol/2.0/service.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2020 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 <unistd.h>
-
-#include <android-base/logging.h>
-#include <android/binder_process.h>
-#include <hidl/HidlTransportSupport.h>
-#include <utils/Errors.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
-
-#include "AudioControl.h"
-#include "WatchdogClient.h"
-#include "vsockinfo.h"
-
-// libhidl:
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
-
-// Generated HIDL files
-using android::hardware::automotive::audiocontrol::V2_0::IAudioControl;
-
-using android::Looper;
-using android::OK;
-using android::hardware::automotive::audiocontrol::V2_0::implementation::AudioControl;
-using android::hardware::automotive::audiocontrol::V2_0::implementation::WatchdogClient;
-using android::hardware::automotive::utils::VsockConnectionInfo;
-
-// Main service entry point
-int main() {
- const auto si = VsockConnectionInfo::fromRoPropertyStore(
- {
- "ro.boot.vendor.audiocontrol.server.cid",
- "ro.vendor.audiocontrol.server.cid",
- },
- {
- "ro.boot.vendor.audiocontrol.server.port",
- "ro.vendor.audiocontrol.server.port",
- });
-
- if (!si) {
- LOG(ERROR) << "failed to get server connection cid/port; audio control server disabled.";
- } else {
- LOG(INFO) << "Creating audio control server at " << si->str();
- }
-
- // Create an instance of our service class
- android::sp<AudioControl> service = new AudioControl(si ? si->str() : "");
- configureRpcThreadpool(4, false /*callerWillJoin*/);
-
- if (service->registerAsService() != OK) {
- LOG(ERROR) << "registerAsService failed";
- return 1;
- }
-
- // Start audio control server
- service->ServerStart();
-
- // Setup a binder thread pool to be a car watchdog client.
- ABinderProcess_setThreadPoolMaxThreadCount(1);
- ABinderProcess_startThreadPool();
- android::sp<Looper> looper(Looper::prepare(0 /* opts */));
- std::shared_ptr<WatchdogClient> watchdogClient =
- ndk::SharedRefBase::make<WatchdogClient>(looper, service.get());
- if (!watchdogClient->initialize()) {
- ALOGE("Failed to initialize car watchdog client");
- return 1;
- }
-
- while (true) {
- looper->pollAll(-1 /* timeoutMillis */);
- }
- service->ServerJoin();
-
- // We don't ever actually expect to return, so return an error if we do get here
- return 2;
-}
diff --git a/hal/audiocontrol/aidl/1.0/Android.bp b/hal/audiocontrol/aidl/1.0/Android.bp
new file mode 100644
index 0000000..093a8eb
--- /dev/null
+++ b/hal/audiocontrol/aidl/1.0/Android.bp
@@ -0,0 +1,126 @@
+// Copyright (C) 2020 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.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+ name: "audiocontrol_hal_default_trout",
+ defaults: [
+ "hidl_defaults",
+ ],
+ shared_libs: [
+ "android.hardware.automotive.audiocontrol@2.0",
+ "libbase",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+}
+
+genrule {
+ name: "AudioFocusControlProtoStub_h",
+ tools: [
+ "aprotoc",
+ "protoc-gen-grpc-cpp-plugin",
+ ],
+ cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+ srcs: [
+ "proto/AudioFocusControl.proto",
+ ],
+ out: [
+ "AudioFocusControl.pb.h",
+ "AudioFocusControl.grpc.pb.h",
+ ],
+}
+
+genrule {
+ name: "AudioFocusControlProtoStub_cc",
+ tools: [
+ "aprotoc",
+ "protoc-gen-grpc-cpp-plugin",
+ ],
+ cmd: "$(location aprotoc) -I$$(dirname $(in)) -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+ srcs: [
+ "proto/AudioFocusControl.proto",
+ ],
+ out: [
+ "AudioFocusControl.pb.cc",
+ "AudioFocusControl.grpc.pb.cc",
+ ],
+}
+
+cc_library {
+ name: "android.hardware.automotive.audiocontrol-server.trout",
+ vendor: true,
+ defaults: ["audiocontrol_hal_default_trout"],
+ srcs: [
+ "AudioControlServer.cpp",
+ ],
+ generated_headers: [
+ "AudioFocusControlProtoStub_h",
+ "audio_policy_configuration_V7_0",
+ ],
+ generated_sources: [
+ "AudioFocusControlProtoStub_cc",
+ "audio_policy_configuration_V7_0",
+ ],
+ header_libs: ["libxsdc-utils"],
+ shared_libs: [
+ "android.hardware.automotive.audiocontrol-V1-ndk",
+ "libgrpc++",
+ "libprotobuf-cpp-full",
+ "libbase",
+ "libbinder_ndk",
+ "libutils",
+ "liblog",
+ "libcutils",
+ "libxml2",
+ ],
+ cflags: [
+ "-Wno-unused-parameter",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.automotive.audiocontrol-service.trout",
+ relative_install_path: "hw",
+ init_rc: ["audiocontrol-trout.rc"],
+ vintf_fragments: ["audiocontrol-trout.xml"],
+ vendor: true,
+ generated_headers: ["audio_policy_configuration_V7_0"],
+ generated_sources: ["audio_policy_configuration_V7_0"],
+ header_libs: ["libxsdc-utils"],
+ shared_libs: [
+ "android.hardware.automotive.audiocontrol-server.trout",
+ "android.hardware.automotive.audiocontrol-V1-ndk",
+ "android.hardware.automotive.utils.watchdog",
+ "android.automotive.watchdog-V2-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libutils",
+ "liblog",
+ "libcutils",
+ "libxml2",
+ ],
+ srcs: [
+ "AudioControl.cpp",
+ "main.cpp",
+ "WatchdogClient.cpp"
+ ],
+ static_libs: [
+ "android.hardware.automotive.utils.vsockinfo",
+ ],
+}
diff --git a/hal/audiocontrol/aidl/1.0/AudioControl.cpp b/hal/audiocontrol/aidl/1.0/AudioControl.cpp
new file mode 100644
index 0000000..6f26714
--- /dev/null
+++ b/hal/audiocontrol/aidl/1.0/AudioControl.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioControl.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
+#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
+#include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
+
+#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+#include <android_audio_policy_configuration_V7_0.h>
+#include <private/android_filesystem_config.h>
+
+#include <stdio.h>
+
+namespace aidl::android::hardware::automotive::audiocontrol {
+
+using ::android::base::EqualsIgnoreCase;
+using ::android::base::ParseInt;
+using ::std::string;
+
+namespace xsd {
+using namespace ::android::audio::policy::configuration::V7_0;
+}
+
+AudioControl::AudioControl(const std::string& audio_control_server_addr)
+ : mAudioControlServer(MakeAudioControlServer(audio_control_server_addr)) {}
+
+ndk::ScopedAStatus AudioControl::registerFocusListener(
+ const shared_ptr<IFocusListener>& in_listener) {
+ LOG(DEBUG) << "registering focus listener";
+
+ if (in_listener) {
+ mAudioControlServer->RegisterFocusListener(mFocusListener = in_listener);
+ } else {
+ LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op.";
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::setBalanceTowardRight(float value) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::setFadeTowardFront(float value) {
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::onAudioFocusChange(const string& in_usage, int32_t in_zoneId,
+ AudioFocusChange in_focusChange) {
+ LOG(INFO) << "Focus changed: " << toString(in_focusChange).c_str() << " for usage "
+ << in_usage.c_str() << " in zone " << in_zoneId;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::onDevicesToDuckChange(
+ const std::vector<DuckingInfo>& in_duckingInfos) {
+ LOG(INFO) << "AudioControl::onDevicesToDuckChange";
+ for (const DuckingInfo& duckingInfo : in_duckingInfos) {
+ LOG(INFO) << "zone: " << duckingInfo.zoneId;
+ LOG(INFO) << "Devices to duck:";
+ for (const auto& addressToDuck : duckingInfo.deviceAddressesToDuck) {
+ LOG(INFO) << addressToDuck;
+ }
+ LOG(INFO) << "Devices to unduck:";
+ for (const auto& addressToUnduck : duckingInfo.deviceAddressesToUnduck) {
+ LOG(INFO) << addressToUnduck;
+ }
+ LOG(INFO) << "Usages holding focus:";
+ for (const auto& usage : duckingInfo.usagesHoldingFocus) {
+ LOG(INFO) << usage;
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::onDevicesToMuteChange(
+ const std::vector<MutingInfo>& in_mutingInfos) {
+ LOG(INFO) << "AudioControl::onDevicesToMuteChange";
+ for (const MutingInfo& mutingInfo : in_mutingInfos) {
+ LOG(INFO) << "zone: " << mutingInfo.zoneId;
+ LOG(INFO) << "Devices to mute:";
+ for (const auto& addressToMute : mutingInfo.deviceAddressesToMute) {
+ LOG(INFO) << addressToMute;
+ }
+ LOG(INFO) << "Devices to unmute:";
+ for (const auto& addressToUnmute : mutingInfo.deviceAddressesToUnmute) {
+ LOG(INFO) << addressToUnmute;
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) {
+ return STATUS_BAD_VALUE;
+}
+
+bool AudioControl::isHealthy() {
+ // TODO(egranata, chenhaosjtuacm): fill this in with a real check
+ // e.g. add a heartbeat message to remote side
+ return true;
+}
+
+} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/hal/audiocontrol/aidl/1.0/AudioControl.h b/hal/audiocontrol/aidl/1.0/AudioControl.h
new file mode 100644
index 0000000..d3c10f9
--- /dev/null
+++ b/hal/audiocontrol/aidl/1.0/AudioControl.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
+#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
+
+#include "AudioControlServer.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
+#include <aidl/android/hardware/automotive/audiocontrol/BnAudioControl.h>
+#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
+
+namespace aidl::android::hardware::automotive::audiocontrol {
+
+using ::std::shared_ptr;
+using ::std::unique_ptr;
+
+class AudioControl : public BnAudioControl {
+ public:
+ explicit AudioControl(const std::string& audio_control_server_addr);
+
+ ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId,
+ AudioFocusChange in_focusChange) override;
+ ndk::ScopedAStatus onDevicesToDuckChange(
+ const std::vector<DuckingInfo>& in_duckingInfos) override;
+ ndk::ScopedAStatus onDevicesToMuteChange(
+ const std::vector<MutingInfo>& in_mutingInfos) override;
+ ndk::ScopedAStatus registerFocusListener(
+ const shared_ptr<IFocusListener>& in_listener) override;
+ ndk::ScopedAStatus setBalanceTowardRight(float in_value) override;
+ ndk::ScopedAStatus setFadeTowardFront(float in_value) override;
+ binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+ bool isHealthy();
+
+ private:
+ // This focus listener will only be used by this HAL instance to communicate with
+ // a single instance of CarAudioService. As such, it doesn't have explicit serialization.
+ // If a different AudioControl implementation were to have multiple threads leveraging this
+ // listener, then it should also include mutexes or make the listener atomic.
+ shared_ptr<IFocusListener> mFocusListener;
+ unique_ptr<AudioControlServer> mAudioControlServer;
+};
+
+} // namespace aidl::android::hardware::automotive::audiocontrol
+
+#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
diff --git a/hal/audiocontrol/2.0/AudioControlServer.cpp b/hal/audiocontrol/aidl/1.0/AudioControlServer.cpp
similarity index 86%
rename from hal/audiocontrol/2.0/AudioControlServer.cpp
rename to hal/audiocontrol/aidl/1.0/AudioControlServer.cpp
index 37a5d7e..6339c5b 100644
--- a/hal/audiocontrol/2.0/AudioControlServer.cpp
+++ b/hal/audiocontrol/aidl/1.0/AudioControlServer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,16 +21,30 @@
#include <thread>
#include <android-base/logging.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
#include <grpc++/grpc++.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
+#include <aidl/android/hardware/automotive/audiocontrol/BnAudioControl.h>
+#include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
+#include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
+
+#include <android_audio_policy_configuration_V7_0.h>
+
#include "AudioFocusControl.grpc.pb.h"
#include "AudioFocusControl.pb.h"
#include "libandroid_audio_controller/utils.h"
-using android::hardware::audio::common::V6_0::AudioUsage;
using std::literals::chrono_literals::operator""s;
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
+namespace xsd {
+using namespace ::android::audio::policy::configuration::V7_0;
+}
+
+using xsd::AudioUsage;
+
+namespace aidl::android::hardware::automotive::audiocontrol {
class AudioControlServerImpl : public AudioControlServer,
audio_focus_control_proto::AudioFocusControlServer::Service {
@@ -39,7 +53,17 @@
~AudioControlServerImpl();
- close_handle_func_t RegisterFocusListener(const sp<IFocusListener>& focusListener) override;
+ close_handle_func_t RegisterFocusListener(std::shared_ptr<IFocusListener> focusListener) override {
+ std::lock_guard<std::mutex> lock(mFocusListenerMutex);
+ mFocusListener = focusListener;
+
+ return [this, focusListener]() {
+ std::lock_guard<std::mutex> lock(mFocusListenerMutex);
+ if (mFocusListener == focusListener) {
+ mFocusListener = nullptr;
+ }
+ };
+ }
grpc::Status AudioRequests(::grpc::ServerContext* context,
const audio_focus_control_proto::AudioFocusControlMessage* message,
@@ -63,7 +87,7 @@
void HandleReleasing(aafc_session_id_t release_session);
void RequestAudioFocus(aafc_audio_usage_t usage, aafc_zone_id_t zone,
- hidl_bitfield<AudioFocusChange> focus_change);
+ AudioFocusChange focus_change);
void AbandonAudioFocus(aafc_audio_usage_t usage, aafc_zone_id_t zone);
@@ -75,7 +99,7 @@
std::chrono::steady_clock::time_point mLastHeartbeat;
focus_listener_request_key_t GetRequestKey() const;
- hidl_bitfield<AudioFocusChange> GetFocusChange() const;
+ AudioFocusChange GetFocusChange() const;
};
using session_pool_t = std::map<aafc_session_id_t, AudioFocusSession>;
@@ -84,7 +108,7 @@
std::string mServiceAddr;
std::unique_ptr<::grpc::Server> mGrpcServer;
- sp<IFocusListener> mFocusListener{nullptr};
+ std::shared_ptr<IFocusListener> mFocusListener{nullptr};
// grpc request queue
std::deque<grpc_request_t> mRequestQueue;
@@ -123,19 +147,6 @@
}
}
-AudioControlServer::close_handle_func_t AudioControlServerImpl::RegisterFocusListener(
- const sp<IFocusListener>& focusListener) {
- std::lock_guard<std::mutex> lock(mFocusListenerMutex);
- mFocusListener = focusListener;
-
- return [this, focusListener]() {
- std::lock_guard<std::mutex> lock(mFocusListenerMutex);
- if (mFocusListener == focusListener) {
- mFocusListener = nullptr;
- }
- };
-}
-
void AudioControlServerImpl::Start() {
if (mGrpcServer) {
LOG(WARNING) << __func__ << ": GRPC Server is running.";
@@ -244,7 +255,7 @@
const auto ref_count_search = mAudioFocusCount.find(request_key);
const auto& [audio_usage, zone_id] = request_key;
LOG(DEBUG) << __func__ << ": acquiring: " << toString(static_cast<AudioUsage>(audio_usage))
- << " " << zone_id << " " << focus_change;
+ << " " << zone_id << " " << toString(focus_change);
const bool not_found = ref_count_search == mAudioFocusCount.end();
const bool count_zero = !not_found && ref_count_search->second == 0;
@@ -288,31 +299,33 @@
}
void AudioControlServerImpl::RequestAudioFocus(aafc_audio_usage_t usage, aafc_zone_id_t zone,
- hidl_bitfield<AudioFocusChange> focus_change) {
+ AudioFocusChange focus_change) {
std::lock_guard<std::mutex> lock(mFocusListenerMutex);
auto listener = mFocusListener;
+ const auto audio_usage = static_cast<AudioUsage>(usage);
LOG(DEBUG) << __func__
- << ": requesting focus, usage: " << toString(static_cast<AudioUsage>(usage))
+ << ": requesting focus, usage: " << toString(audio_usage)
<< ", zone: " << zone
<< ", focus change: " << toString(static_cast<AudioFocusChange>(focus_change));
if (!listener) {
LOG(ERROR) << __func__ << ": audio focus listener has not been registered.";
return;
}
- listener->requestAudioFocus(usage, zone, focus_change);
+ listener->requestAudioFocus(toString(audio_usage), zone, focus_change);
}
void AudioControlServerImpl::AbandonAudioFocus(aafc_audio_usage_t usage, aafc_zone_id_t zone) {
std::lock_guard<std::mutex> lock(mFocusListenerMutex);
auto listener = mFocusListener;
+ const auto audio_usage = static_cast<AudioUsage>(usage);
LOG(DEBUG) << __func__
- << ": abandoning focus, usage: " << toString(static_cast<AudioUsage>(usage))
+ << ": abandoning focus, usage: " << toString(audio_usage)
<< ", zone: " << zone;
if (!listener) {
LOG(ERROR) << __func__ << ": audio focus listener has not been registered.";
return;
}
- listener->abandonAudioFocus(usage, zone);
+ listener->abandonAudioFocus(toString(audio_usage), zone);
}
void AudioControlServerImpl::CheckSessionHeartbeats(
@@ -356,9 +369,9 @@
return {mRequest.audio_usage(), mRequest.zone_id()};
}
-hidl_bitfield<AudioFocusChange> AudioControlServerImpl::AudioFocusSession::GetFocusChange() const {
+AudioFocusChange AudioControlServerImpl::AudioFocusSession::GetFocusChange() const {
constexpr auto cast_to_bitfield = [](auto&& focus_change) {
- return static_cast<hidl_bitfield<AudioFocusChange>>(focus_change);
+ return static_cast<AudioFocusChange>(focus_change);
};
if (!mRequest.is_transient()) {
return cast_to_bitfield(AudioFocusChange::GAIN);
@@ -376,4 +389,4 @@
return std::make_unique<AudioControlServerImpl>(addr);
}
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
+} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/hal/audiocontrol/2.0/AudioControlServer.h b/hal/audiocontrol/aidl/1.0/AudioControlServer.h
similarity index 70%
rename from hal/audiocontrol/2.0/AudioControlServer.h
rename to hal/audiocontrol/aidl/1.0/AudioControlServer.h
index b0cc60b..18ec138 100644
--- a/hal/audiocontrol/2.0/AudioControlServer.h
+++ b/hal/audiocontrol/aidl/1.0/AudioControlServer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,9 +20,9 @@
#include <memory>
#include <string>
-#include <android/hardware/automotive/audiocontrol/2.0/IFocusListener.h>
+#include <aidl/android/hardware/automotive/audiocontrol/BnAudioControl.h>
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
+namespace aidl::android::hardware::automotive::audiocontrol {
class AudioControlServer {
public:
@@ -30,7 +30,8 @@
virtual ~AudioControlServer() = default;
- virtual close_handle_func_t RegisterFocusListener(const sp<IFocusListener>& focusListener) = 0;
+ virtual close_handle_func_t RegisterFocusListener(
+ std::shared_ptr<IFocusListener> focusListener) = 0;
virtual void Start() = 0;
@@ -39,4 +40,4 @@
std::unique_ptr<AudioControlServer> MakeAudioControlServer(const std::string& addr);
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
+} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/hal/audiocontrol/2.0/WatchdogClient.cpp b/hal/audiocontrol/aidl/1.0/WatchdogClient.cpp
similarity index 82%
rename from hal/audiocontrol/2.0/WatchdogClient.cpp
rename to hal/audiocontrol/aidl/1.0/WatchdogClient.cpp
index 742a5ac..0a38343 100644
--- a/hal/audiocontrol/2.0/WatchdogClient.cpp
+++ b/hal/audiocontrol/aidl/1.0/WatchdogClient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,8 @@
using aidl::android::automotive::watchdog::ICarWatchdog;
using aidl::android::automotive::watchdog::TimeoutLength;
+using ::android::Looper;
+using ::android::sp;
namespace {
@@ -29,7 +31,7 @@
} // namespace
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
+namespace aidl::android::hardware::automotive::audiocontrol {
WatchdogClient::WatchdogClient(const sp<Looper>& handlerLooper, AudioControl* audioCtrl)
: BaseWatchdogClient(handlerLooper), mAudioControl(audioCtrl) {}
@@ -38,4 +40,4 @@
return mAudioControl->isHealthy();
}
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
+} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/hal/audiocontrol/2.0/WatchdogClient.h b/hal/audiocontrol/aidl/1.0/WatchdogClient.h
similarity index 77%
rename from hal/audiocontrol/2.0/WatchdogClient.h
rename to hal/audiocontrol/aidl/1.0/WatchdogClient.h
index 79a3a77..251dda2 100644
--- a/hal/audiocontrol/2.0/WatchdogClient.h
+++ b/hal/audiocontrol/aidl/1.0/WatchdogClient.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,9 +24,9 @@
#include <utils/Looper.h>
#include <utils/Mutex.h>
-namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
+namespace aidl::android::hardware::automotive::audiocontrol {
-class WatchdogClient : public android::hardware::automotive::utils::BaseWatchdogClient {
+class WatchdogClient : public ::android::hardware::automotive::utils::BaseWatchdogClient {
public:
WatchdogClient(const ::android::sp<::android::Looper>& handlerLooper, AudioControl* audioCtrl);
@@ -37,4 +37,4 @@
AudioControl* mAudioControl;
};
-} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
+} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/hal/audiocontrol/2.0/agl_build/CMakeLists.txt b/hal/audiocontrol/aidl/1.0/agl_build/CMakeLists.txt
similarity index 100%
rename from hal/audiocontrol/2.0/agl_build/CMakeLists.txt
rename to hal/audiocontrol/aidl/1.0/agl_build/CMakeLists.txt
diff --git a/hal/audiocontrol/aidl/1.0/audiocontrol-trout.rc b/hal/audiocontrol/aidl/1.0/audiocontrol-trout.rc
new file mode 100644
index 0000000..53dda85
--- /dev/null
+++ b/hal/audiocontrol/aidl/1.0/audiocontrol-trout.rc
@@ -0,0 +1,4 @@
+service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.audiocontrol-service.trout
+ class hal
+ user audioserver
+ group system
diff --git a/hal/audiocontrol/aidl/1.0/audiocontrol-trout.xml b/hal/audiocontrol/aidl/1.0/audiocontrol-trout.xml
new file mode 100644
index 0000000..f95d05f
--- /dev/null
+++ b/hal/audiocontrol/aidl/1.0/audiocontrol-trout.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.automotive.audiocontrol</name>
+ <fqname>IAudioControl/default</fqname>
+ </hal>
+</manifest>
diff --git a/hal/audiocontrol/2.0/libandroid_audio_controller/android_audio_controller.cpp b/hal/audiocontrol/aidl/1.0/libandroid_audio_controller/android_audio_controller.cpp
similarity index 100%
rename from hal/audiocontrol/2.0/libandroid_audio_controller/android_audio_controller.cpp
rename to hal/audiocontrol/aidl/1.0/libandroid_audio_controller/android_audio_controller.cpp
diff --git a/hal/audiocontrol/2.0/libandroid_audio_controller/android_audio_controller.h b/hal/audiocontrol/aidl/1.0/libandroid_audio_controller/android_audio_controller.h
similarity index 100%
rename from hal/audiocontrol/2.0/libandroid_audio_controller/android_audio_controller.h
rename to hal/audiocontrol/aidl/1.0/libandroid_audio_controller/android_audio_controller.h
diff --git a/hal/audiocontrol/2.0/libandroid_audio_controller/utils.h b/hal/audiocontrol/aidl/1.0/libandroid_audio_controller/utils.h
similarity index 100%
rename from hal/audiocontrol/2.0/libandroid_audio_controller/utils.h
rename to hal/audiocontrol/aidl/1.0/libandroid_audio_controller/utils.h
diff --git a/hal/audiocontrol/2.0/libandroid_audio_controller_test/main.cpp b/hal/audiocontrol/aidl/1.0/libandroid_audio_controller_test/main.cpp
similarity index 100%
rename from hal/audiocontrol/2.0/libandroid_audio_controller_test/main.cpp
rename to hal/audiocontrol/aidl/1.0/libandroid_audio_controller_test/main.cpp
diff --git a/hal/audiocontrol/aidl/1.0/main.cpp b/hal/audiocontrol/aidl/1.0/main.cpp
new file mode 100644
index 0000000..6368b4f
--- /dev/null
+++ b/hal/audiocontrol/aidl/1.0/main.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AudioControl.h"
+#include "vsockinfo.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using aidl::android::hardware::automotive::audiocontrol::AudioControl;
+using android::hardware::automotive::utils::VsockConnectionInfo;
+
+int main() {
+ const auto si = VsockConnectionInfo::fromRoPropertyStore(
+ {
+ "ro.boot.vendor.audiocontrol.server.cid",
+ "ro.vendor.audiocontrol.server.cid",
+ },
+ {
+ "ro.boot.vendor.audiocontrol.server.port",
+ "ro.vendor.audiocontrol.server.port",
+ });
+
+ if (!si) {
+ LOG(ERROR) << "failed to get server connection cid/port; audio control server disabled.";
+ } else {
+ LOG(INFO) << "Creating audio control server at " << si->str();
+ }
+
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ // Create an instance of our service class
+ std::shared_ptr<AudioControl> audioControl = ndk::SharedRefBase::make<AudioControl>(si ? si->str() : "");
+
+ const std::string instance = std::string() + AudioControl::descriptor + "/default";
+ binder_status_t status =
+ AServiceManager_addService(audioControl->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/hal/audiocontrol/2.0/proto/AudioFocusControl.proto b/hal/audiocontrol/aidl/1.0/proto/AudioFocusControl.proto
similarity index 100%
rename from hal/audiocontrol/2.0/proto/AudioFocusControl.proto
rename to hal/audiocontrol/aidl/1.0/proto/AudioFocusControl.proto
diff --git a/hal/common/android/watchdog/Android.bp b/hal/common/android/watchdog/Android.bp
index bdcbd71..32236b4 100644
--- a/hal/common/android/watchdog/Android.bp
+++ b/hal/common/android/watchdog/Android.bp
@@ -27,7 +27,7 @@
],
export_include_dirs: ["."],
shared_libs: [
- "carwatchdog_aidl_interface-V2-ndk",
+ "android.automotive.watchdog-V2-ndk",
"libbase",
"libbinder_ndk",
"libhidlbase",
diff --git a/hal/dumpstate/1.1/DumpstateDevice.h b/hal/dumpstate/1.1/DumpstateDevice.h
deleted file mode 100644
index 0b40a11..0000000
--- a/hal/dumpstate/1.1/DumpstateDevice.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <android/hardware/dumpstate/1.1/IDumpstateDevice.h>
-
-#include <automotive/filesystem>
-#include <functional>
-
-#include <grpc++/grpc++.h>
-
-#include "DumpstateServer.grpc.pb.h"
-#include "DumpstateServer.pb.h"
-
-namespace android::hardware::dumpstate::V1_1::implementation {
-
-namespace fs = android::hardware::automotive::filesystem;
-
-class DumpstateDevice : public IDumpstateDevice {
- public:
- explicit DumpstateDevice(const std::string& addr);
-
- // Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
- Return<void> dumpstateBoard(const hidl_handle& h) override;
-
- // Methods from ::android::hardware::dumpstate::V1_1::IDumpstateDevice follow.
- Return<DumpstateStatus> dumpstateBoard_1_1(const hidl_handle& h, const DumpstateMode mode,
- const uint64_t timeoutMillis) override;
- Return<void> setVerboseLoggingEnabled(const bool enable) override;
- Return<bool> getVerboseLoggingEnabled() override;
-
- bool isHealthy();
-
- Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options);
-
- private:
- bool dumpRemoteLogs(::grpc::ClientReaderInterface<dumpstate_proto::DumpstateBuffer>* reader,
- const fs::path& dumpPath);
-
- bool dumpHelperSystem(int textFd, int binFd);
-
- void debugDumpServices(std::function<void(std::string)> f);
-
- std::vector<std::string> getAvailableServices();
-
- std::string mServiceAddr;
- std::shared_ptr<::grpc::Channel> mGrpcChannel;
- std::unique_ptr<dumpstate_proto::DumpstateServer::Stub> mGrpcStub;
-};
-
-sp<DumpstateDevice> makeVirtualizationDumpstateDevice(const std::string& addr);
-
-} // namespace android::hardware::dumpstate::V1_1::implementation
diff --git a/hal/dumpstate/1.1/DumpstateGrpcServer.cpp b/hal/dumpstate/1.1/DumpstateGrpcServer.cpp
deleted file mode 100644
index 83530c6..0000000
--- a/hal/dumpstate/1.1/DumpstateGrpcServer.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2020 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 "DumpstateGrpcServer.h"
-
-#include <array>
-#include <iostream>
-#include <unordered_set>
-
-#include <grpc++/grpc++.h>
-
-// clang-format off
-static const std::unordered_set<std::string> kAvailableServices{
- "coqos-virtio-blk",
- "coqos-virtio-net",
- "coqos-virtio-video",
- "coqos-virtio-console",
- "coqos-virtio-rng",
- "coqos-virtio-vsock",
- "coqos-virtio-gpu-virgl",
- "coqos-virtio-scmi",
- "coqos-virtio-input",
- "coqos-virtio-snd",
- "dumpstate_grpc_server",
- "systemd",
- "vehicle_hal_grpc_server",
-};
-// clang-format on
-
-static std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
- // TODO(chenhaosjtuacm): get secured credentials here
- return ::grpc::InsecureServerCredentials();
-}
-
-grpc::Status DumpstateGrpcServer::GetSystemLogs(
- ::grpc::ServerContext*, const ::google::protobuf::Empty*,
- ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>* stream) {
- return GetCommandOutput("/bin/dmesg -kuPT", stream);
-}
-
-grpc::Status DumpstateGrpcServer::GetAvailableServices(
- ::grpc::ServerContext*, const ::google::protobuf::Empty*,
- dumpstate_proto::ServiceNameList* serviceList) {
- static const dumpstate_proto::ServiceNameList kProtoAvailableServices = []() {
- dumpstate_proto::ServiceNameList serviceNameList;
- for (auto& serviceName : kAvailableServices) {
- serviceNameList.add_service_names(serviceName);
- }
- return serviceNameList;
- }();
-
- *serviceList = kProtoAvailableServices;
- return ::grpc::Status::OK;
-}
-
-grpc::Status DumpstateGrpcServer::GetServiceLogs(
- ::grpc::ServerContext*, const dumpstate_proto::ServiceLogRequest* request,
- ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>* stream) {
- const auto& serviceName = request->service_name();
- if (serviceName.empty()) {
- return ::grpc::Status::OK;
- }
- if (kAvailableServices.find(serviceName) == kAvailableServices.end()) {
- return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT,
- std::string("Bad service name: ") + serviceName);
- }
- return GetCommandOutput(std::string("/bin/journalctl --no-pager -t ") + serviceName, stream);
-}
-
-grpc::Status DumpstateGrpcServer::GetCommandOutput(
- const std::string& command,
- ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>* stream) {
- int commandExitStatus = 0;
- auto pipeStreamDeleter = [&commandExitStatus](std::FILE* fp) {
- commandExitStatus = pclose(fp);
- };
- std::unique_ptr<std::FILE, decltype(pipeStreamDeleter)> pipeStream(popen(command.c_str(), "r"),
- pipeStreamDeleter);
-
- if (!pipeStream) {
- return ::grpc::Status(::grpc::StatusCode::INTERNAL,
- std::string("Failed to execute ") + command + ", " + strerror(errno));
- }
-
- std::array<char, 65536> buffer;
- while (!std::feof(pipeStream.get())) {
- auto readLen = fread(buffer.data(), 1, buffer.size(), pipeStream.get());
- dumpstate_proto::DumpstateBuffer dumpstateBuffer;
- dumpstateBuffer.set_buffer(buffer.data(), readLen);
- stream->Write(dumpstateBuffer);
- }
-
- pipeStream.reset();
-
- if (commandExitStatus == 0) {
- return ::grpc::Status::OK;
- } else if (commandExitStatus < 0) {
- return ::grpc::Status(
- ::grpc::StatusCode::INTERNAL,
- std::string("Failed when pclose ") + command + ", " + strerror(errno));
- } else {
- return ::grpc::Status(::grpc::StatusCode::INTERNAL,
- std::string("Error when executing ") + command +
- ", exit code: " + std::to_string(commandExitStatus));
- }
-}
-
-void DumpstateGrpcServer::Start() {
- ::grpc::ServerBuilder builder;
- builder.RegisterService(this);
- builder.AddListeningPort(mServiceAddr, getServerCredentials());
- std::unique_ptr<::grpc::Server> server(builder.BuildAndStart());
-
- if (!server) {
- std::cerr << __func__ << ": failed to create the GRPC server, "
- << "please make sure the configuration and permissions are correct" << std::endl;
- std::abort();
- }
-
- server->Wait();
-}
diff --git a/hal/dumpstate/1.1/agl_build/CMakeLists.txt b/hal/dumpstate/1.1/agl_build/CMakeLists.txt
deleted file mode 100644
index 05da17a..0000000
--- a/hal/dumpstate/1.1/agl_build/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-set(_dumpstate_CXX_FLAGS -Wall -Werror -std=c++17)
-
-include(${trout_SRC_ROOT}/cmake/grpc.cmake)
-include(${trout_SRC_ROOT}/cmake/protobuf.cmake)
-include(${trout_SRC_ROOT}/cmake/utils/grpc_cpp_generator.cmake)
-
-get_filename_component(dumpstate_SRC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE)
-
-if (NOT trout_GENS_DIR)
- set(trout_GENS_DIR ${PROJECT_BINARY_DIR}/gens)
-endif()
-
-trout_generate_grpc_cpp_from_proto(
- SRCS
- ${dumpstate_SRC_ROOT}/proto/DumpstateServer.proto)
-
-# ========== Protobuf generated code ==================
-
-add_library(dumpstate_protobuf_gen
- ${trout_GENS_DIR}/DumpstateServer.pb.cc
- ${trout_GENS_DIR}/DumpstateServer.grpc.pb.cc
-)
-
-target_link_libraries(dumpstate_protobuf_gen
- ${trout_GRPCXX_LIBRARIES}
-)
-
-target_compile_options(dumpstate_protobuf_gen PRIVATE ${_dumpstate_CXX_FLAGS} -Wno-array-bounds)
-
-# ========== dumpstate_grpc_server ==============
-
-add_executable(dumpstate_grpc_server
- ${dumpstate_SRC_ROOT}/DumpstateGrpcServer.cpp
- ${dumpstate_SRC_ROOT}/server_main.cpp
-)
-
-target_include_directories(dumpstate_grpc_server
- PRIVATE ${trout_GENS_DIR}
-)
-
-target_link_libraries(dumpstate_grpc_server
- dumpstate_protobuf_gen
-)
-
-target_compile_options(dumpstate_grpc_server PRIVATE ${_dumpstate_CXX_FLAGS})
diff --git a/hal/dumpstate/1.1/android.hardware.dumpstate@1.1-service.trout.rc b/hal/dumpstate/1.1/android.hardware.dumpstate@1.1-service.trout.rc
deleted file mode 100644
index cfa750f..0000000
--- a/hal/dumpstate/1.1/android.hardware.dumpstate@1.1-service.trout.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service dumpstate-1-1 /vendor/bin/hw/android.hardware.dumpstate@1.1-service.trout
- class hal
- user system
- group system shell
diff --git a/hal/dumpstate/1.1/server_main.cpp b/hal/dumpstate/1.1/server_main.cpp
deleted file mode 100644
index 0aa55c9..0000000
--- a/hal/dumpstate/1.1/server_main.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 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 "DumpstateGrpcServer.h"
-
-#include <getopt.h>
-
-#include <iostream>
-#include <string>
-
-int main(int argc, char** argv) {
- std::string serverAddr;
-
- // unique values to identify the options
- constexpr int OPT_SERVER_ADDR = 1001;
-
- struct option longOptions[] = {
- {"server_addr", 1, 0, OPT_SERVER_ADDR},
- {},
- };
-
- int optValue;
- while ((optValue = getopt_long_only(argc, argv, ":", longOptions, 0)) != -1) {
- switch (optValue) {
- case OPT_SERVER_ADDR:
- serverAddr = optarg;
- break;
- default:
- // ignore other options
- break;
- }
- }
-
- if (serverAddr.empty()) {
- std::cerr << "Dumpstate server addreess is missing" << std::endl;
- return 1;
- } else {
- std::cerr << "Dumpstate server addreess: " << serverAddr << std::endl;
- }
-
- DumpstateGrpcServer server(serverAddr);
- server.Start();
- return 0;
-}
diff --git a/hal/dumpstate/1.1/service.cpp b/hal/dumpstate/1.1/service.cpp
deleted file mode 100644
index 5c0f08a..0000000
--- a/hal/dumpstate/1.1/service.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2020 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/binder_process.h>
-
-#include <cutils/properties.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-
-#include <utils/Errors.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
-
-#include <sstream>
-
-#include "DumpstateDevice.h"
-#include "WatchdogClient.h"
-
-#include <vsockinfo.h>
-
-using android::Looper;
-using ::android::OK;
-using ::android::sp;
-using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::joinRpcThreadpool;
-using ::android::hardware::automotive::utils::VsockConnectionInfo;
-using ::android::hardware::dumpstate::V1_1::IDumpstateDevice;
-using ::android::hardware::dumpstate::V1_1::implementation::makeVirtualizationDumpstateDevice;
-using ::android::hardware::dumpstate::V1_1::implementation::WatchdogClient;
-
-int main() {
- const auto si = VsockConnectionInfo::fromRoPropertyStore(
- {
- "ro.boot.vendor.dumpstate.server.cid",
- "ro.vendor.dumpstate.server.cid",
- },
- {
- "ro.boot.vendor.dumpstate.server.port",
- "ro.vendor.dumpstate.server.port",
- });
-
- if (!si) {
- ALOGE("failed to get server connection cid/port; configure and try again.");
- return 1;
- } else {
- ALOGI("Connecting to vsock server at %s", si->str().c_str());
- }
-
- auto dumpstate = makeVirtualizationDumpstateDevice(si->str());
- // This method MUST be called before interacting with any HIDL interfaces.
- configureRpcThreadpool(2, true);
- if (dumpstate->registerAsService() != OK) {
- ALOGE("Could not register service.");
- return 1;
- }
-
- // Setup a binder thread pool to be a car watchdog client.
- ABinderProcess_setThreadPoolMaxThreadCount(1);
- ABinderProcess_startThreadPool();
- android::sp<Looper> looper(Looper::prepare(0 /* opts */));
- auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, dumpstate.get());
- if (!watchdogClient->initialize()) {
- ALOGE("Failed to initialize car watchdog client");
- return 1;
- }
-
- while (true) {
- looper->pollAll(-1 /* timeoutMillis */);
- }
-}
diff --git a/hal/dumpstate/1.1/Android.bp b/hal/dumpstate/aidl/1.0/Android.bp
similarity index 83%
rename from hal/dumpstate/1.1/Android.bp
rename to hal/dumpstate/aidl/1.0/Android.bp
index 2b08104..5b80ae0 100644
--- a/hal/dumpstate/1.1/Android.bp
+++ b/hal/dumpstate/aidl/1.0/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 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.
@@ -51,27 +51,24 @@
}
cc_binary {
- name: "android.hardware.dumpstate@1.1-service.trout",
- srcs: [
- "DumpstateDevice.cpp",
- "service.cpp",
- "WatchdogClient.cpp",
- ],
+ name: "android.hardware.automotive.dumpstate-service.trout",
+ relative_install_path: "hw",
+ init_rc: ["dumpstate-trout.rc"],
+ vintf_fragments: ["dumpstate-trout.xml"],
+ vendor: true,
generated_headers: [
+ "dumpstate_hal_configuration_V1_0",
"DumpstateServerProtoStub_h",
],
generated_sources: [
+ "dumpstate_hal_configuration_V1_0",
"DumpstateServerProtoStub_cc",
],
- static_libs: [
- "android.hardware.automotive@libc++fs",
- "android.hardware.automotive.utils.vsockinfo",
- ],
+ header_libs: ["libxsdc-utils"],
shared_libs: [
"android.hardware.automotive.utils.watchdog",
- "android.hardware.dumpstate@1.0",
- "android.hardware.dumpstate@1.1",
- "carwatchdog_aidl_interface-V2-ndk",
+ "android.automotive.watchdog-V2-ndk",
+ "android.hardware.dumpstate-V1-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
@@ -82,13 +79,18 @@
"libprotobuf-cpp-full",
"libutils",
],
+ srcs: [
+ "DumpstateDevice.cpp",
+ "service.cpp",
+ "WatchdogClient.cpp",
+ ],
+ static_libs: [
+ "android.hardware.automotive@libc++fs",
+ "android.hardware.automotive.utils.vsockinfo",
+ "libxml2",
+ ],
cflags: [
"-Wno-unused-parameter",
],
- relative_install_path: "hw",
- init_rc: [
- "android.hardware.dumpstate@1.1-service.trout.rc",
- ],
defaults: ["cuttlefish_guest_only"],
- vintf_fragments: ["manifest_android.hardware.dumpstate@1.1-service.trout.xml"],
}
diff --git a/hal/dumpstate/1.1/DumpstateDevice.cpp b/hal/dumpstate/aidl/1.0/DumpstateDevice.cpp
similarity index 76%
rename from hal/dumpstate/1.1/DumpstateDevice.cpp
rename to hal/dumpstate/aidl/1.0/DumpstateDevice.cpp
index 5e419fe..679d649 100644
--- a/hal/dumpstate/1.1/DumpstateDevice.cpp
+++ b/hal/dumpstate/aidl/1.0/DumpstateDevice.cpp
@@ -38,7 +38,7 @@
static constexpr const char* VENDOR_HELPER_SYSTEM_LOG_LOC_PROPERTY =
"ro.vendor.helpersystem.log_loc";
-namespace android::hardware::dumpstate::V1_1::implementation {
+namespace aidl::android::hardware::dumpstate::implementation {
static std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
// TODO(chenhaosjtuacm): get secured credentials here
@@ -121,7 +121,7 @@
bool DumpstateDevice::dumpHelperSystem(int textFd, int binFd) {
std::string helperSystemLogDir =
- android::base::GetProperty(VENDOR_HELPER_SYSTEM_LOG_LOC_PROPERTY, "");
+ ::android::base::GetProperty(VENDOR_HELPER_SYSTEM_LOG_LOC_PROPERTY, "");
if (helperSystemLogDir.empty()) {
LOG(ERROR) << "Helper system log location '" << VENDOR_HELPER_SYSTEM_LOG_LOC_PROPERTY
@@ -212,63 +212,37 @@
mGrpcChannel(::grpc::CreateChannel(mServiceAddr, getChannelCredentials())),
mGrpcStub(dumpstate_proto::DumpstateServer::NewStub(mGrpcChannel)) {}
-// Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
-Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle& handle) {
- // Ignore return value, just return an empty status.
- dumpstateBoard_1_1(handle, DumpstateMode::DEFAULT, 30 * 1000 /* timeoutMillis */);
- return Void();
-}
-
-// Methods from ::android::hardware::dumpstate::V1_1::IDumpstateDevice follow.
-Return<DumpstateStatus> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& handle,
- const DumpstateMode /* mode */,
- const uint64_t /* timeoutMillis */) {
- if (handle == nullptr || handle->numFds < 1) {
- LOG(ERROR) << "No FDs";
- return DumpstateStatus::ILLEGAL_ARGUMENT;
+::ndk::ScopedAStatus DumpstateDevice::dumpstateBoard(
+ const std::vector<::ndk::ScopedFileDescriptor>& in_fds,
+ IDumpstateDevice::DumpstateMode in_mode, int64_t in_timeoutMillis) {
+ if (in_fds.size() < 1) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "No file descriptor");
}
- const int textFd = handle->data[0];
- const int binFd = handle->numFds >= 2 ? handle->data[1] : -1;
+ const int textFd = in_fds[0].get();
+ const int binFd = in_fds.size() >= 2 ? in_fds[1].get() : -1;
if (!dumpHelperSystem(textFd, binFd)) {
- return DumpstateStatus::DEVICE_LOGGING_NOT_ENABLED;
+ // TODO(egranata,chenhaosjtuacm): provide more helpful info here
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_UNSUPPORTED_OPERATION, "Host system unable to gather required logs");
}
- return DumpstateStatus::OK;
+ return ndk::ScopedAStatus::ok();
}
-Return<void> DumpstateDevice::setVerboseLoggingEnabled(const bool enable) {
- android::base::SetProperty(VENDOR_VERBOSE_LOGGING_ENABLED_PROPERTY, enable ? "true" : "false");
- return Void();
+::ndk::ScopedAStatus DumpstateDevice::getVerboseLoggingEnabled(bool* _aidl_return) {
+ if (_aidl_return)
+ *_aidl_return =
+ ::android::base::GetBoolProperty(VENDOR_VERBOSE_LOGGING_ENABLED_PROPERTY, false);
+ return ndk::ScopedAStatus::ok();
}
-Return<bool> DumpstateDevice::getVerboseLoggingEnabled() {
- return android::base::GetBoolProperty(VENDOR_VERBOSE_LOGGING_ENABLED_PROPERTY, false);
+::ndk::ScopedAStatus DumpstateDevice::setVerboseLoggingEnabled(bool in_enable) {
+ ::android::base::SetProperty(VENDOR_VERBOSE_LOGGING_ENABLED_PROPERTY,
+ in_enable ? "true" : "false");
+ return ndk::ScopedAStatus::ok();
}
-Return<void> DumpstateDevice::debug(const hidl_handle& h, const hidl_vec<hidl_string>& options) {
- if (h.getNativeHandle() == nullptr || h->numFds == 0) {
- LOG(ERROR) << "Invalid FD passed to debug() function";
- return Void();
- }
-
- const int fd = h->data[0];
- auto pf = [fd](std::string s) -> void { dprintf(fd, "%s\n", s.c_str()); };
- debugDumpServices(pf);
-
- return Void();
-}
-
-void DumpstateDevice::debugDumpServices(std::function<void(std::string)> f) {
- f("Available services for Dumpstate:");
- for (const auto& svc : getAvailableServices()) {
- f(" " + svc);
- }
-}
-
-sp<DumpstateDevice> makeVirtualizationDumpstateDevice(const std::string& addr) {
- return new DumpstateDevice(addr);
-}
-
-} // namespace android::hardware::dumpstate::V1_1::implementation
+} // namespace aidl::android::hardware::dumpstate::implementation
diff --git a/hal/dumpstate/aidl/1.0/DumpstateDevice.h b/hal/dumpstate/aidl/1.0/DumpstateDevice.h
new file mode 100644
index 0000000..7df0669
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/DumpstateDevice.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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/dumpstate/BnDumpstateDevice.h>
+#include <aidl/android/hardware/dumpstate/IDumpstateDevice.h>
+#include <android/binder_status.h>
+
+#include <automotive/filesystem>
+#include <functional>
+
+#include <grpc++/grpc++.h>
+
+#include "DumpstateServer.grpc.pb.h"
+#include "DumpstateServer.pb.h"
+
+namespace aidl::android::hardware::dumpstate::implementation {
+
+namespace fs = ::android::hardware::automotive::filesystem;
+
+class DumpstateDevice : public BnDumpstateDevice {
+ public:
+ explicit DumpstateDevice(const std::string& addr);
+
+ ::ndk::ScopedAStatus dumpstateBoard(const std::vector<::ndk::ScopedFileDescriptor>& in_fds,
+ IDumpstateDevice::DumpstateMode in_mode,
+ int64_t in_timeoutMillis) override;
+
+ ::ndk::ScopedAStatus getVerboseLoggingEnabled(bool* _aidl_return) override;
+ ::ndk::ScopedAStatus setVerboseLoggingEnabled(bool in_enable) override;
+
+ bool isHealthy();
+
+ private:
+ bool dumpRemoteLogs(::grpc::ClientReaderInterface<dumpstate_proto::DumpstateBuffer>* reader,
+ const fs::path& dumpPath);
+
+ bool dumpHelperSystem(int textFd, int binFd);
+
+ std::vector<std::string> getAvailableServices();
+
+ std::string mServiceAddr;
+ std::shared_ptr<::grpc::Channel> mGrpcChannel;
+ std::unique_ptr<dumpstate_proto::DumpstateServer::Stub> mGrpcStub;
+};
+
+} // namespace aidl::android::hardware::dumpstate::implementation
diff --git a/hal/dumpstate/aidl/1.0/DumpstateGrpcServer.cpp b/hal/dumpstate/aidl/1.0/DumpstateGrpcServer.cpp
new file mode 100644
index 0000000..a7626aa
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/DumpstateGrpcServer.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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 "DumpstateGrpcServer.h"
+#include "ServiceDescriptor.h"
+
+#include <array>
+#include <iostream>
+#include <unordered_set>
+
+#include <grpc++/grpc++.h>
+
+struct GrpcServiceOutputConsumer : public ServiceDescriptor::OutputConsumer {
+ using Dest = ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>*;
+
+ explicit GrpcServiceOutputConsumer(Dest s) : stream(s) {}
+
+ void Write(char* ptr, size_t len) override {
+ dumpstate_proto::DumpstateBuffer dumpstateBuffer;
+ dumpstateBuffer.set_buffer(ptr, len);
+ stream->Write(dumpstateBuffer);
+ }
+
+ Dest stream;
+};
+
+static std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
+ // TODO(chenhaosjtuacm): get secured credentials here
+ return ::grpc::InsecureServerCredentials();
+}
+
+static ::grpc::Status toGRpcStatus(const ServiceDescriptor::Error& err) {
+ if (err == std::nullopt)
+ return ::grpc::Status::OK;
+ else
+ return ::grpc::Status(::grpc::StatusCode::INTERNAL, *err);
+}
+
+DumpstateGrpcServer::DumpstateGrpcServer(const std::string& addr, const ServiceSupplier& services)
+ : DumpstateServer(services), mServiceAddr(addr) {}
+
+grpc::Status DumpstateGrpcServer::GetSystemLogs(
+ ::grpc::ServerContext*, const ::google::protobuf::Empty*,
+ ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>* stream) {
+ GrpcServiceOutputConsumer consumer(stream);
+
+ const auto ok = this->DumpstateServer::GetSystemLogs(&consumer);
+ return toGRpcStatus(ok);
+}
+
+grpc::Status DumpstateGrpcServer::GetAvailableServices(
+ ::grpc::ServerContext*, const ::google::protobuf::Empty*,
+ dumpstate_proto::ServiceNameList* serviceList) {
+ const auto services = this->DumpstateServer::GetAvailableServices();
+
+ for (const auto& svc : services) serviceList->add_service_names(svc);
+
+ return ::grpc::Status::OK;
+}
+
+grpc::Status DumpstateGrpcServer::GetServiceLogs(
+ ::grpc::ServerContext*, const dumpstate_proto::ServiceLogRequest* request,
+ ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>* stream) {
+ const auto& serviceName = request->service_name();
+ if (serviceName.empty()) {
+ return ::grpc::Status::OK;
+ }
+
+ GrpcServiceOutputConsumer consumer(stream);
+ const auto ok = this->DumpstateServer::GetServiceLogs(serviceName, &consumer);
+ return toGRpcStatus(ok);
+}
+
+void DumpstateGrpcServer::Start() {
+ ::grpc::ServerBuilder builder;
+ builder.RegisterService(this);
+ builder.AddListeningPort(mServiceAddr, getServerCredentials());
+ std::unique_ptr<::grpc::Server> server(builder.BuildAndStart());
+
+ if (!server) {
+ std::cerr << __func__ << ": failed to create the GRPC server, "
+ << "please make sure the configuration and permissions are correct" << std::endl;
+ std::abort();
+ }
+
+ server->Wait();
+}
diff --git a/hal/dumpstate/1.1/DumpstateGrpcServer.h b/hal/dumpstate/aidl/1.0/DumpstateGrpcServer.h
similarity index 85%
rename from hal/dumpstate/1.1/DumpstateGrpcServer.h
rename to hal/dumpstate/aidl/1.0/DumpstateGrpcServer.h
index bf1de55..32d1a10 100644
--- a/hal/dumpstate/1.1/DumpstateGrpcServer.h
+++ b/hal/dumpstate/aidl/1.0/DumpstateGrpcServer.h
@@ -14,12 +14,16 @@
* limitations under the License.
*/
+#pragma once
+
#include "DumpstateServer.grpc.pb.h"
+#include "DumpstateServer.h"
#include "DumpstateServer.pb.h"
-class DumpstateGrpcServer : public dumpstate_proto::DumpstateServer::Service {
+class DumpstateGrpcServer : public dumpstate_proto::DumpstateServer::Service,
+ private DumpstateServer {
public:
- explicit DumpstateGrpcServer(const std::string& addr) : mServiceAddr(addr) {}
+ DumpstateGrpcServer(const std::string& addr, const ServiceSupplier& services);
grpc::Status GetSystemLogs(
::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
@@ -36,8 +40,5 @@
void Start();
private:
- grpc::Status GetCommandOutput(const std::string& command,
- ::grpc::ServerWriter<dumpstate_proto::DumpstateBuffer>* stream);
-
std::string mServiceAddr;
};
diff --git a/hal/dumpstate/aidl/1.0/DumpstateServer.cpp b/hal/dumpstate/aidl/1.0/DumpstateServer.cpp
new file mode 100644
index 0000000..621a843
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/DumpstateServer.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 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 "DumpstateServer.h"
+
+#include <iostream>
+
+DumpstateServer::DumpstateServer(const ServiceSupplier& services) {
+ mSystemLogsService = services.GetSystemLogsService();
+ for (auto svc : services.GetServices()) {
+ mServices.emplace(svc.name(), svc);
+ }
+
+ services.dump(std::cerr);
+}
+
+ServiceDescriptor::Error DumpstateServer::GetSystemLogs(ServiceDescriptor::OutputConsumer* out) {
+ if (mSystemLogsService)
+ return mSystemLogsService->GetOutput(out);
+ else
+ return "system logs missing";
+}
+
+std::vector<std::string> DumpstateServer::GetAvailableServices() {
+ std::vector<std::string> ret;
+
+ for (auto& svc : mServices) {
+ if (svc.second.IsAvailable()) ret.push_back(svc.first);
+ }
+
+ return ret;
+}
+
+ServiceDescriptor::Error DumpstateServer::GetServiceLogs(const std::string& svc,
+ ServiceDescriptor::OutputConsumer* out) {
+ auto iter = mServices.find(svc);
+ if (iter == mServices.end()) {
+ return "Bad service name: " + svc;
+ }
+
+ return iter->second.GetOutput(out);
+}
diff --git a/hal/dumpstate/aidl/1.0/DumpstateServer.h b/hal/dumpstate/aidl/1.0/DumpstateServer.h
new file mode 100644
index 0000000..7e67067
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/DumpstateServer.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 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 "ServiceDescriptor.h"
+#include "ServiceSupplier.h"
+
+#include <optional>
+#include <unordered_map>
+
+class DumpstateServer {
+ public:
+ explicit DumpstateServer(const ServiceSupplier& services);
+
+ ServiceDescriptor::Error GetSystemLogs(ServiceDescriptor::OutputConsumer* out);
+
+ std::vector<std::string> GetAvailableServices();
+
+ ServiceDescriptor::Error GetServiceLogs(const std::string& svc,
+ ServiceDescriptor::OutputConsumer* out);
+
+ private:
+ std::optional<ServiceDescriptor> mSystemLogsService;
+ std::unordered_map<std::string, ServiceDescriptor> mServices;
+};
diff --git a/hal/dumpstate/aidl/1.0/ServiceDescriptor.cpp b/hal/dumpstate/aidl/1.0/ServiceDescriptor.cpp
new file mode 100644
index 0000000..e4689be
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/ServiceDescriptor.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 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 "ServiceDescriptor.h"
+
+#include <array>
+#include <memory>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ServiceDescriptor::ServiceDescriptor(std::string name, std::string cmd)
+ : mName(name), mCommandLine(cmd) {}
+
+std::optional<std::string> ServiceDescriptor::GetOutput(OutputConsumer* consumer) const {
+ if (!IsAvailable()) return "service not available";
+
+ const auto cmd = command();
+
+ int commandExitStatus = 0;
+ auto pipeStreamDeleter = [&commandExitStatus](std::FILE* fp) {
+ commandExitStatus = pclose(fp);
+ };
+ std::unique_ptr<std::FILE, decltype(pipeStreamDeleter)> pipeStream(popen(cmd, "r"),
+ pipeStreamDeleter);
+
+ if (!pipeStream) {
+ return std::string("Failed to execute ") + cmd + ", " + strerror(errno);
+ }
+
+ std::array<char, 65536> buffer;
+ while (!std::feof(pipeStream.get())) {
+ auto readLen = fread(buffer.data(), 1, buffer.size(), pipeStream.get());
+ consumer->Write(buffer.data(), readLen);
+ }
+
+ pipeStream.reset();
+
+ if (commandExitStatus == 0) {
+ return std::nullopt;
+ } else if (commandExitStatus < 0) {
+ return std::string("Failed when pclose ") + cmd + ", " + strerror(errno);
+ } else {
+ return std::string("Error when executing ") + cmd +
+ ", exit code: " + std::to_string(commandExitStatus);
+ }
+}
diff --git a/hal/dumpstate/aidl/1.0/ServiceDescriptor.h b/hal/dumpstate/aidl/1.0/ServiceDescriptor.h
new file mode 100644
index 0000000..74844d1
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/ServiceDescriptor.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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 <optional>
+#include <string>
+
+class ServiceDescriptor {
+ public:
+ ServiceDescriptor(std::string name, std::string cmd);
+
+ const char* name() const { return mName.c_str(); }
+ const char* command() const { return mCommandLine.c_str(); }
+
+ bool IsAvailable() const {
+ // TODO(egranata): how to validate this?
+ return true;
+ }
+
+ struct OutputConsumer {
+ virtual void Write(char* ptr, size_t len) = 0;
+ };
+
+ using Error = std::optional<std::string>;
+ // std::nullopt for success; an error descriptor otherwise
+ Error GetOutput(OutputConsumer* consumer) const;
+
+ private:
+ std::string mName;
+ std::string mCommandLine;
+};
diff --git a/hal/dumpstate/aidl/1.0/ServiceSupplier.cpp b/hal/dumpstate/aidl/1.0/ServiceSupplier.cpp
new file mode 100644
index 0000000..39bfe2a
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/ServiceSupplier.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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 "ServiceSupplier.h"
+
+std::optional<ServiceDescriptor> ServiceSupplier::GetSystemLogsService() const {
+ return {};
+}
+
+std::vector<ServiceDescriptor> ServiceSupplier::GetServices() const {
+ return {};
+}
+
+void ServiceSupplier::dump(std::ostream& os) const {
+ os << "ServiceSupplier dump[system logs=" << (GetSystemLogsService().has_value() ? "y" : "n")
+ << "], services count = " << GetServices().size() << std::endl;
+
+ if (auto dmesg = GetSystemLogsService()) {
+ os << "system logs service: [name=" << dmesg->name() << ", command=" << dmesg->command()
+ << "]" << std::endl;
+ }
+ for (auto svc : GetServices()) {
+ os << "service " << svc.name() << " runs command " << svc.command() << std::endl;
+ }
+}
diff --git a/hal/dumpstate/aidl/1.0/ServiceSupplier.h b/hal/dumpstate/aidl/1.0/ServiceSupplier.h
new file mode 100644
index 0000000..011a878
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/ServiceSupplier.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2020 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 "ServiceDescriptor.h"
+
+#include <optional>
+#include <ostream>
+#include <vector>
+
+struct ServiceSupplier {
+ virtual std::optional<ServiceDescriptor> GetSystemLogsService() const;
+ virtual std::vector<ServiceDescriptor> GetServices() const;
+
+ void dump(std::ostream& os) const;
+
+ virtual ~ServiceSupplier() = default;
+};
diff --git a/hal/dumpstate/1.1/WatchdogClient.cpp b/hal/dumpstate/aidl/1.0/WatchdogClient.cpp
similarity index 86%
rename from hal/dumpstate/1.1/WatchdogClient.cpp
rename to hal/dumpstate/aidl/1.0/WatchdogClient.cpp
index 0d9d1f2..fe2b3b7 100644
--- a/hal/dumpstate/1.1/WatchdogClient.cpp
+++ b/hal/dumpstate/aidl/1.0/WatchdogClient.cpp
@@ -22,6 +22,8 @@
using aidl::android::automotive::watchdog::ICarWatchdog;
using aidl::android::automotive::watchdog::TimeoutLength;
+using ::android::Looper;
+using ::android::sp;
namespace {
@@ -29,7 +31,7 @@
} // namespace
-namespace android::hardware::dumpstate::V1_1::implementation {
+namespace aidl::android::hardware::dumpstate::implementation {
WatchdogClient::WatchdogClient(const sp<Looper>& handlerLooper, DumpstateDevice* ddh)
: BaseWatchdogClient(handlerLooper), mDumpstateImpl(ddh) {}
@@ -38,4 +40,4 @@
return mDumpstateImpl->isHealthy();
}
-} // namespace android::hardware::dumpstate::V1_1::implementation
+} // namespace aidl::android::hardware::dumpstate::implementation
diff --git a/hal/dumpstate/1.1/WatchdogClient.h b/hal/dumpstate/aidl/1.0/WatchdogClient.h
similarity index 83%
rename from hal/dumpstate/1.1/WatchdogClient.h
rename to hal/dumpstate/aidl/1.0/WatchdogClient.h
index 08a93ea..006d98e 100644
--- a/hal/dumpstate/1.1/WatchdogClient.h
+++ b/hal/dumpstate/aidl/1.0/WatchdogClient.h
@@ -16,7 +16,6 @@
#pragma once
#include "BaseWatchdogClient.h"
-
#include "DumpstateDevice.h"
#include <aidl/android/automotive/watchdog/BnCarWatchdog.h>
@@ -24,9 +23,9 @@
#include <utils/Looper.h>
#include <utils/Mutex.h>
-namespace android::hardware::dumpstate::V1_1::implementation {
+namespace aidl::android::hardware::dumpstate::implementation {
-class WatchdogClient : public android::hardware::automotive::utils::BaseWatchdogClient {
+class WatchdogClient : public ::android::hardware::automotive::utils::BaseWatchdogClient {
public:
WatchdogClient(const ::android::sp<::android::Looper>& handlerLooper, DumpstateDevice* ddh);
@@ -37,4 +36,4 @@
DumpstateDevice* mDumpstateImpl;
};
-} // namespace android::hardware::dumpstate::V1_1::implementation
+} // namespace aidl::android::hardware::dumpstate::implementation
diff --git a/hal/dumpstate/aidl/1.0/agl_build/CMakeLists.txt b/hal/dumpstate/aidl/1.0/agl_build/CMakeLists.txt
new file mode 100644
index 0000000..0c0849d
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/agl_build/CMakeLists.txt
@@ -0,0 +1,80 @@
+set(_dumpstate_CXX_FLAGS -Wall -Werror -std=c++17)
+
+include(${trout_SRC_ROOT}/cmake/googletest.cmake)
+include(${trout_SRC_ROOT}/cmake/grpc.cmake)
+include(${trout_SRC_ROOT}/cmake/protobuf.cmake)
+include(${trout_SRC_ROOT}/cmake/utils/grpc_cpp_generator.cmake)
+
+find_package(LibXml2 REQUIRED)
+
+get_filename_component(dumpstate_SRC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE)
+
+if (NOT trout_GENS_DIR)
+ set(trout_GENS_DIR ${PROJECT_BINARY_DIR}/gens)
+endif()
+
+trout_generate_grpc_cpp_from_proto(
+ SRCS
+ ${dumpstate_SRC_ROOT}/proto/DumpstateServer.proto)
+
+# ========== Protobuf generated code ==================
+
+add_library(dumpstate_protobuf_gen
+ ${trout_GENS_DIR}/DumpstateServer.pb.cc
+ ${trout_GENS_DIR}/DumpstateServer.grpc.pb.cc
+)
+
+target_link_libraries(dumpstate_protobuf_gen
+ ${trout_GRPCXX_LIBRARIES}
+)
+
+target_compile_options(dumpstate_protobuf_gen PRIVATE ${_dumpstate_CXX_FLAGS} -Wno-array-bounds)
+
+# ========== dumpstate_grpc_server ==============
+
+set(_dumpstate_sources
+ ${dumpstate_SRC_ROOT}/DumpstateServer.cpp
+ ${dumpstate_SRC_ROOT}/DumpstateGrpcServer.cpp
+ ${dumpstate_SRC_ROOT}/ServiceDescriptor.cpp
+ ${dumpstate_SRC_ROOT}/ServiceSupplier.cpp
+ ${dumpstate_SRC_ROOT}/config/dumpstate_hal_configuration_V1_0.cpp
+ ${dumpstate_SRC_ROOT}/config/XmlServiceSupplier.cpp
+)
+
+add_executable(dumpstate_grpc_server
+ ${_dumpstate_sources}
+ ${dumpstate_SRC_ROOT}/server_main.cpp
+)
+
+target_include_directories(dumpstate_grpc_server
+ PRIVATE ${trout_GENS_DIR}
+ ${dumpstate_SRC_ROOT}
+ ${LIBXML2_INCLUDE_DIR}
+)
+
+target_link_libraries(dumpstate_grpc_server
+ dumpstate_protobuf_gen
+ ${LIBXML2_LIBRARIES}
+)
+
+target_compile_options(dumpstate_grpc_server PRIVATE ${_dumpstate_CXX_FLAGS})
+
+add_executable(dumpstate_tests
+ ${_dumpstate_sources}
+ ${dumpstate_SRC_ROOT}/tests/test_main.cpp
+ ${dumpstate_SRC_ROOT}/tests/tests.cpp
+)
+
+target_include_directories(dumpstate_tests
+ PRIVATE ${trout_GENS_DIR}
+ ${dumpstate_SRC_ROOT}
+ ${LIBXML2_INCLUDE_DIR}
+)
+
+target_link_libraries(dumpstate_tests
+ dumpstate_protobuf_gen
+ ${trout_GOOGLETEST_LIBRARIES}
+ ${LIBXML2_LIBRARIES}
+)
+
+target_compile_options(dumpstate_tests PRIVATE ${_dumpstate_CXX_FLAGS})
diff --git a/hal/dumpstate/aidl/1.0/config/Android.bp b/hal/dumpstate/aidl/1.0/config/Android.bp
new file mode 100644
index 0000000..abd4ae7
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/Android.bp
@@ -0,0 +1,24 @@
+//
+// Copyright (C) 2020 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.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+xsd_config {
+ name: "dumpstate_hal_configuration_V1_0",
+ srcs: ["dumpstate_hal_configuration.xsd"],
+ package_name: "dumpstate.hal.configuration.V1_0",
+}
diff --git a/hal/dumpstate/aidl/1.0/config/XmlServiceSupplier.cpp b/hal/dumpstate/aidl/1.0/config/XmlServiceSupplier.cpp
new file mode 100644
index 0000000..2161ecd
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/XmlServiceSupplier.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 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 "XmlServiceSupplier.h"
+#include "ServiceDescriptor.h"
+
+using dumpstate::hal::configuration::V1_0::Service;
+
+static std::optional<ServiceDescriptor> serviceFromXml(const Service& svc) {
+ if (svc.hasName() && svc.hasCommand()) {
+ return ServiceDescriptor{svc.getName(), svc.getCommand()};
+ }
+ return std::nullopt;
+}
+
+std::optional<XmlServiceSupplier> XmlServiceSupplier::fromFile(const std::string& path) {
+ if (auto cfg = dumpstate::hal::configuration::V1_0::readFile(path.c_str())) {
+ return XmlServiceSupplier{*cfg};
+ }
+ return std::nullopt;
+}
+
+std::optional<XmlServiceSupplier> XmlServiceSupplier::fromBuffer(const std::string& buffer) {
+ if (auto cfg = dumpstate::hal::configuration::V1_0::readBuffer(buffer)) {
+ return XmlServiceSupplier{*cfg};
+ }
+ return std::nullopt;
+}
+
+XmlServiceSupplier::XmlServiceSupplier(const DumpstateHalConfiguration& cfg) {
+ // TODO(egranata): perform semantic validation before constructing
+
+ if (cfg.hasSystemLogs()) {
+ auto sl = cfg.getFirstSystemLogs();
+ if (sl->hasService()) {
+ auto xsvc = sl->getFirstService();
+ if (auto svc = serviceFromXml(*xsvc)) {
+ mSystemLogs = *svc;
+ }
+ }
+ }
+
+ if (cfg.hasServices()) {
+ auto svcs = cfg.getFirstServices();
+ for (const auto& xsvc : svcs->getService()) {
+ if (auto svc = serviceFromXml(xsvc)) {
+ mServices.push_back(*svc);
+ }
+ }
+ }
+}
+
+std::optional<ServiceDescriptor> XmlServiceSupplier::GetSystemLogsService() const {
+ return mSystemLogs;
+}
+
+std::vector<ServiceDescriptor> XmlServiceSupplier::GetServices() const {
+ return mServices;
+}
diff --git a/hal/dumpstate/aidl/1.0/config/XmlServiceSupplier.h b/hal/dumpstate/aidl/1.0/config/XmlServiceSupplier.h
new file mode 100644
index 0000000..b116ec5
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/XmlServiceSupplier.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 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 "ServiceSupplier.h"
+#include "config/dumpstate_hal_configuration_V1_0.h"
+
+using dumpstate::hal::configuration::V1_0::DumpstateHalConfiguration;
+
+class XmlServiceSupplier : public ServiceSupplier {
+ public:
+ static std::optional<XmlServiceSupplier> fromFile(const std::string& path);
+ static std::optional<XmlServiceSupplier> fromBuffer(const std::string& buffer);
+
+ std::optional<ServiceDescriptor> GetSystemLogsService() const override;
+ std::vector<ServiceDescriptor> GetServices() const override;
+
+ private:
+ explicit XmlServiceSupplier(const DumpstateHalConfiguration& cfg);
+
+ std::optional<ServiceDescriptor> mSystemLogs;
+ std::vector<ServiceDescriptor> mServices;
+};
diff --git a/hal/dumpstate/aidl/1.0/config/api/current.txt b/hal/dumpstate/aidl/1.0/config/api/current.txt
new file mode 100644
index 0000000..e714210
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/api/current.txt
@@ -0,0 +1,41 @@
+// Signature format: 2.0
+package dumpstate.hal.configuration.V1_0 {
+
+ public class DumpstateHalConfiguration {
+ ctor public DumpstateHalConfiguration();
+ method public dumpstate.hal.configuration.V1_0.Services getServices();
+ method public dumpstate.hal.configuration.V1_0.SystemLogs getSystemLogs();
+ method public float getVersion();
+ method public void setServices(dumpstate.hal.configuration.V1_0.Services);
+ method public void setSystemLogs(dumpstate.hal.configuration.V1_0.SystemLogs);
+ method public void setVersion(float);
+ }
+
+ public class Service {
+ ctor public Service();
+ method public String getCommand();
+ method public String getName();
+ method public void setCommand(String);
+ method public void setName(String);
+ }
+
+ public class Services {
+ ctor public Services();
+ method public java.util.List<dumpstate.hal.configuration.V1_0.Service> getService();
+ }
+
+ public class SystemLogs {
+ ctor public SystemLogs();
+ method public dumpstate.hal.configuration.V1_0.Service getService();
+ method public void setService(dumpstate.hal.configuration.V1_0.Service);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static dumpstate.hal.configuration.V1_0.DumpstateHalConfiguration read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/hal/dumpstate/aidl/1.0/config/api/last_current.txt b/hal/dumpstate/aidl/1.0/config/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/api/last_current.txt
diff --git a/hal/dumpstate/aidl/1.0/config/api/last_removed.txt b/hal/dumpstate/aidl/1.0/config/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/api/last_removed.txt
diff --git a/hal/dumpstate/aidl/1.0/config/api/removed.txt b/hal/dumpstate/aidl/1.0/config/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/hal/dumpstate/aidl/1.0/config/coqos_config.xml b/hal/dumpstate/aidl/1.0/config/coqos_config.xml
new file mode 100644
index 0000000..84d613e
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/coqos_config.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<dumpstateHalConfiguration version="1.0">
+ <services>
+ <service name="coqos-virtio-blk" command="/bin/journalctl --no-pager -t coqos-virtio-blk"/>
+ <service name="coqos-virtio-net" command="/bin/journalctl --no-pager -t coqos-virtio-net"/>
+ <service name="coqos-virtio-video" command="/bin/journalctl --no-pager -t coqos-virtio-video"/>
+ <service name="coqos-virtio-console" command="/bin/journalctl --no-pager -t coqos-virtio-console"/>
+ <service name="coqos-virtio-rng" command="/bin/journalctl --no-pager -t coqos-virtio-rng"/>
+ <service name="coqos-virtio-vsock" command="/bin/journalctl --no-pager -t coqos-virtio-vsock"/>
+ <service name="coqos-virtio-gpu-virgl" command="/bin/journalctl --no-pager -t coqos-virtio-gpu-virgl"/>
+ <service name="coqos-virtio-scmi" command="/bin/journalctl --no-pager -t coqos-virtio-scmi"/>
+ <service name="coqos-virtio-input" command="/bin/journalctl --no-pager -t coqos-virtio-input"/>
+ <service name="coqos-virtio-snd" command="/bin/journalctl --no-pager -t coqos-virtio-snd"/>
+ <service name="dumpstate_grpc_server" command="/bin/journalctl --no-pager -t dumpstate_grpc_server"/>
+ <service name="systemd" command="/bin/journalctl --no-pager -t systemd"/>
+ <service name="systemctl" command="/bin/systemctl status"/>
+ <service name="vehicle_hal_grpc_server" command="/bin/journalctl --no-pager -t vehicle_hal_grpc_server"/>
+ </services>
+ <systemLogs>
+ <service name="dmesg" command="/bin/dmesg -kuPT"/>
+ </systemLogs>
+</dumpstateHalConfiguration>
diff --git a/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration.xsd b/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration.xsd
new file mode 100644
index 0000000..0b9897e
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType name="service">
+ <xs:attribute name="name" type="xs:string" use="required"/>
+ <xs:attribute name="command" type="xs:string" use="required"/>
+ </xs:complexType>
+ <xs:complexType name="services">
+ <xs:sequence>
+ <xs:element name="service" type="service" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="systemLogs">
+ <xs:sequence>
+ <xs:element name="service" type="service" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="dumpstateHalConfiguration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="services" type="services" minOccurs="1" maxOccurs="1"/>
+ <xs:element name="systemLogs" type="systemLogs" minOccurs="1" maxOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute type="xs:float" name="version" use="required"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration_V1_0.cpp b/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration_V1_0.cpp
new file mode 100644
index 0000000..9738462
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration_V1_0.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// Autogenerated by dumpstate_hal_config.xsd
+
+#define LOG_TAG "dumpstate.hal.configuration.V1_0"
+
+#include <memory>
+
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+
+#include "config/dumpstate_hal_configuration_V1_0.h"
+
+namespace dumpstate {
+namespace hal {
+namespace configuration {
+namespace V1_0 {
+template <class T>
+constexpr void (*xmlDeleter)(T* t);
+template <>
+constexpr auto xmlDeleter<xmlDoc> = xmlFreeDoc;
+template <>
+auto xmlDeleter<xmlChar> = [](xmlChar* s) { xmlFree(s); };
+
+template <class T>
+constexpr auto make_xmlUnique(T* t) {
+ auto deleter = [](T* t) { xmlDeleter<T>(t); };
+ return std::unique_ptr<T, decltype(deleter)>{t, deleter};
+}
+
+static std::string getXmlAttribute(const xmlNode* cur, const char* attribute) {
+ auto xmlValue = make_xmlUnique(xmlGetProp(cur, reinterpret_cast<const xmlChar*>(attribute)));
+ if (xmlValue == nullptr) {
+ return "";
+ }
+ std::string value(reinterpret_cast<const char*>(xmlValue.get()));
+ return value;
+}
+
+std::optional<DumpstateHalConfiguration> readBuffer(const std::string& xml) {
+ auto doc = make_xmlUnique(xmlParseMemory(xml.data(), xml.size()));
+ if (doc == nullptr) {
+ return std::nullopt;
+ }
+ xmlNodePtr child = xmlDocGetRootElement(doc.get());
+ if (child == NULL) {
+ return std::nullopt;
+ }
+
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("dumpstateHalConfiguration"))) {
+ DumpstateHalConfiguration value = DumpstateHalConfiguration::read(child);
+ return value;
+ }
+ return std::nullopt;
+}
+
+std::optional<DumpstateHalConfiguration> readFile(const char* configFile) {
+ auto doc = make_xmlUnique(xmlParseFile(configFile));
+ if (doc == nullptr) {
+ return std::nullopt;
+ }
+ xmlNodePtr child = xmlDocGetRootElement(doc.get());
+ if (child == NULL) {
+ return std::nullopt;
+ }
+
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("dumpstateHalConfiguration"))) {
+ DumpstateHalConfiguration value = DumpstateHalConfiguration::read(child);
+ return value;
+ }
+ return std::nullopt;
+}
+
+Service::Service(std::string name, std::string command)
+ : name_(std::move(name)), command_(std::move(command)) {}
+
+const std::string& Service::getName() const {
+ return name_;
+}
+
+bool Service::hasName() const {
+ return true;
+}
+
+const std::string& Service::getCommand() const {
+ return command_;
+}
+
+bool Service::hasCommand() const {
+ return true;
+}
+
+Service Service::read(xmlNode* root) {
+ std::string raw;
+ raw = getXmlAttribute(root, "name");
+ std::string name;
+ if (raw != "") {
+ std::string& value = raw;
+ name = value;
+ }
+ raw = getXmlAttribute(root, "command");
+ std::string command;
+ if (raw != "") {
+ std::string& value = raw;
+ command = value;
+ }
+ Service instance(name, command);
+ return instance;
+}
+
+Services::Services(std::vector<Service> service) : service_(std::move(service)) {}
+
+const std::vector<Service>& Services::getService() const {
+ return service_;
+}
+
+bool Services::hasService() const {
+ return !(service_.empty());
+}
+
+const Service* Services::getFirstService() const {
+ if (service_.empty()) {
+ return nullptr;
+ }
+ return &service_[0];
+}
+
+Services Services::read(xmlNode* root) {
+ std::string raw;
+ std::vector<Service> service;
+ for (xmlNode* child = root->xmlChildrenNode; child != nullptr; child = child->next) {
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("service"))) {
+ Service value = Service::read(child);
+ service.push_back(std::move(value));
+ }
+ }
+ Services instance(service);
+ return instance;
+}
+
+SystemLogs::SystemLogs(std::vector<Service> service) : service_(std::move(service)) {}
+
+const std::vector<Service>& SystemLogs::getService() const {
+ return service_;
+}
+
+bool SystemLogs::hasService() const {
+ return !(service_.empty());
+}
+
+const Service* SystemLogs::getFirstService() const {
+ if (service_.empty()) {
+ return nullptr;
+ }
+ return &service_[0];
+}
+
+SystemLogs SystemLogs::read(xmlNode* root) {
+ std::string raw;
+ std::vector<Service> service;
+ for (xmlNode* child = root->xmlChildrenNode; child != nullptr; child = child->next) {
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("service"))) {
+ Service value = Service::read(child);
+ service.push_back(std::move(value));
+ }
+ }
+ SystemLogs instance(service);
+ return instance;
+}
+
+DumpstateHalConfiguration::DumpstateHalConfiguration(std::vector<Services> services,
+ std::vector<SystemLogs> systemLogs,
+ float version)
+ : services_(std::move(services)), systemLogs_(std::move(systemLogs)), version_(version) {}
+
+const std::vector<Services>& DumpstateHalConfiguration::getServices() const {
+ return services_;
+}
+
+bool DumpstateHalConfiguration::hasServices() const {
+ return !(services_.empty());
+}
+
+const Services* DumpstateHalConfiguration::getFirstServices() const {
+ if (services_.empty()) {
+ return nullptr;
+ }
+ return &services_[0];
+}
+
+const std::vector<SystemLogs>& DumpstateHalConfiguration::getSystemLogs() const {
+ return systemLogs_;
+}
+
+bool DumpstateHalConfiguration::hasSystemLogs() const {
+ return !(systemLogs_.empty());
+}
+
+const SystemLogs* DumpstateHalConfiguration::getFirstSystemLogs() const {
+ if (systemLogs_.empty()) {
+ return nullptr;
+ }
+ return &systemLogs_[0];
+}
+
+const float& DumpstateHalConfiguration::getVersion() const {
+ return version_;
+}
+
+bool DumpstateHalConfiguration::hasVersion() const {
+ return true;
+}
+
+DumpstateHalConfiguration DumpstateHalConfiguration::read(xmlNode* root) {
+ std::string raw;
+ raw = getXmlAttribute(root, "version");
+ float version = 0;
+ if (raw != "") {
+ float value = std::stof(raw);
+ version = value;
+ }
+ std::vector<Services> services;
+ std::vector<SystemLogs> systemLogs;
+ for (xmlNode* child = root->xmlChildrenNode; child != nullptr; child = child->next) {
+ if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("services"))) {
+ Services value = Services::read(child);
+ services.push_back(std::move(value));
+ } else if (!xmlStrcmp(child->name, reinterpret_cast<const xmlChar*>("systemLogs"))) {
+ SystemLogs value = SystemLogs::read(child);
+ systemLogs.push_back(std::move(value));
+ }
+ }
+ DumpstateHalConfiguration instance(services, systemLogs, version);
+ return instance;
+}
+} // namespace V1_0
+} // namespace configuration
+} // namespace hal
+} // namespace dumpstate
diff --git a/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration_V1_0.h b/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration_V1_0.h
new file mode 100644
index 0000000..9aba0d4
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/config/dumpstate_hal_configuration_V1_0.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// Autogenerated by dumpstate_hal_config.xsd
+// TODO(egranata): could we build xsdc from AOSP such that
+// one could generate this file instead of having a hardcoded copy?
+
+#ifndef DUMPSTATE_HAL_CONFIGURATION_V1_0_H
+#define DUMPSTATE_HAL_CONFIGURATION_V1_0_H
+
+#include <array>
+#include <map>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <libxml/parser.h>
+#include <libxml/xinclude.h>
+
+namespace dumpstate {
+namespace hal {
+namespace configuration {
+namespace V1_0 {
+class Service;
+class Services;
+class SystemLogs;
+class DumpstateHalConfiguration;
+std::optional<DumpstateHalConfiguration> readFile(const char* configFile);
+std::optional<DumpstateHalConfiguration> readBuffer(const std::string& xml);
+
+class Service {
+ private:
+ const std::string name_;
+ const std::string command_;
+
+ public:
+ Service(std::string name, std::string command);
+ const std::string& getName() const;
+ bool hasName() const;
+ const std::string& getCommand() const;
+ bool hasCommand() const;
+ static Service read(xmlNode* root);
+};
+
+class Services {
+ private:
+ const std::vector<Service> service_;
+
+ public:
+ explicit Services(std::vector<Service> service);
+ const std::vector<Service>& getService() const;
+ bool hasService() const;
+ const Service* getFirstService() const;
+ static Services read(xmlNode* root);
+};
+
+class SystemLogs {
+ private:
+ const std::vector<Service> service_;
+
+ public:
+ explicit SystemLogs(std::vector<Service> service);
+ const std::vector<Service>& getService() const;
+ bool hasService() const;
+ const Service* getFirstService() const;
+ static SystemLogs read(xmlNode* root);
+};
+
+class DumpstateHalConfiguration {
+ private:
+ const std::vector<Services> services_;
+ const std::vector<SystemLogs> systemLogs_;
+ const float version_;
+
+ public:
+ DumpstateHalConfiguration(std::vector<Services> services, std::vector<SystemLogs> systemLogs,
+ float version);
+ const std::vector<Services>& getServices() const;
+ bool hasServices() const;
+ const Services* getFirstServices() const;
+ const std::vector<SystemLogs>& getSystemLogs() const;
+ bool hasSystemLogs() const;
+ const SystemLogs* getFirstSystemLogs() const;
+ const float& getVersion() const;
+ bool hasVersion() const;
+ static DumpstateHalConfiguration read(xmlNode* root);
+};
+
+} // namespace V1_0
+} // namespace configuration
+} // namespace hal
+} // namespace dumpstate
+#endif // DUMPSTATE_HAL_CONFIGURATION_V1_0_H
diff --git a/hal/dumpstate/aidl/1.0/dumpstate-trout.rc b/hal/dumpstate/aidl/1.0/dumpstate-trout.rc
new file mode 100644
index 0000000..d7aab6c
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/dumpstate-trout.rc
@@ -0,0 +1,4 @@
+service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.dumpstate-service.trout
+ class hal
+ user system
+ group system shell
diff --git a/hal/dumpstate/1.1/manifest_android.hardware.dumpstate@1.1-service.trout.xml b/hal/dumpstate/aidl/1.0/dumpstate-trout.xml
similarity index 63%
rename from hal/dumpstate/1.1/manifest_android.hardware.dumpstate@1.1-service.trout.xml
rename to hal/dumpstate/aidl/1.0/dumpstate-trout.xml
index 7d7c27d..dd5e626 100644
--- a/hal/dumpstate/1.1/manifest_android.hardware.dumpstate@1.1-service.trout.xml
+++ b/hal/dumpstate/aidl/1.0/dumpstate-trout.xml
@@ -9,13 +9,8 @@
*/
-->
<manifest version="1.0" type="device">
- <hal format="hidl">
+ <hal format="aidl">
<name>android.hardware.dumpstate</name>
- <transport>hwbinder</transport>
- <version>1.1</version>
- <interface>
- <name>IDumpstateDevice</name>
- <instance>default</instance>
- </interface>
+ <fqname>IDumpstateDevice/default</fqname>
</hal>
</manifest>
diff --git a/hal/dumpstate/1.1/proto/DumpstateServer.proto b/hal/dumpstate/aidl/1.0/proto/DumpstateServer.proto
similarity index 100%
rename from hal/dumpstate/1.1/proto/DumpstateServer.proto
rename to hal/dumpstate/aidl/1.0/proto/DumpstateServer.proto
diff --git a/hal/dumpstate/aidl/1.0/server_main.cpp b/hal/dumpstate/aidl/1.0/server_main.cpp
new file mode 100644
index 0000000..dfcd312
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/server_main.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2020 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 "DumpstateGrpcServer.h"
+#include "ServiceSupplier.h"
+#include "config/XmlServiceSupplier.h"
+
+#include <getopt.h>
+
+#include <iostream>
+#include <string>
+
+static ServiceDescriptor kDmesgService("dmesg", "/bin/dmesg -kuPT");
+
+static ServiceDescriptor SystemdService(const std::string& name) {
+ return ServiceDescriptor{name, std::string("/bin/journalctl --no-pager -t ") + name};
+}
+
+// clang-format off
+static const std::vector<ServiceDescriptor> kAvailableServices {
+ SystemdService("coqos-virtio-blk"),
+ SystemdService("coqos-virtio-net"),
+ SystemdService("coqos-virtio-video"),
+ SystemdService("coqos-virtio-console"),
+ SystemdService("coqos-virtio-rng"),
+ SystemdService("coqos-virtio-vsock"),
+ SystemdService("coqos-virtio-gpu-virgl"),
+ SystemdService("coqos-virtio-scmi"),
+ SystemdService("coqos-virtio-input"),
+ SystemdService("coqos-virtio-snd"),
+ SystemdService("dumpstate_grpc_server"),
+ SystemdService("systemd"),
+ SystemdService("vehicle_hal_grpc_server"),
+};
+// clang-format on
+
+// TODO(egranata): this is a default configuration that we can remove once we land the proper BSP
+class CoqosLvSystemdServices : public ServiceSupplier {
+ public:
+ std::optional<ServiceDescriptor> GetSystemLogsService() const override { return kDmesgService; }
+
+ std::vector<ServiceDescriptor> GetServices() const override { return kAvailableServices; }
+};
+
+static constexpr auto SERVER_CONFIG_FILE = "/etc/aaos.dumpstate.xml";
+
+int main(int argc, char** argv) {
+ // TODO(egranata): move address info to config file?
+ std::string serverAddr;
+ std::string serverConfig = SERVER_CONFIG_FILE;
+
+ // unique values to identify the options
+ constexpr int OPT_SERVER_ADDR = 1001;
+ constexpr int OPT_CONFIG_FILE = 1002;
+
+ struct option longOptions[] = {
+ {"server_addr", 1, 0, OPT_SERVER_ADDR},
+ {"config_file", 1, 0, OPT_CONFIG_FILE},
+ {},
+ };
+
+ int optValue;
+ while ((optValue = getopt_long_only(argc, argv, ":", longOptions, 0)) != -1) {
+ switch (optValue) {
+ case OPT_SERVER_ADDR:
+ serverAddr = optarg;
+ break;
+ case OPT_CONFIG_FILE:
+ serverConfig = optarg;
+ break;
+ default:
+ // ignore other options
+ break;
+ }
+ }
+
+ if (serverAddr.empty()) {
+ std::cerr << "Dumpstate server addreess is missing" << std::endl;
+ return 1;
+ } else {
+ std::cerr << "Dumpstate server addreess: " << serverAddr << std::endl
+ << "Dumpstate server config: " << serverConfig << std::endl;
+ }
+
+ std::unique_ptr<DumpstateGrpcServer> server;
+ if (auto xmlServices = XmlServiceSupplier::fromFile(serverConfig)) {
+ server.reset(new DumpstateGrpcServer{serverAddr, *xmlServices});
+ } else {
+ server.reset(new DumpstateGrpcServer{serverAddr, CoqosLvSystemdServices()});
+ std::cerr << "Server configuration not found; defaulting to built-in configuration which"
+ << " may not work for all environments" << std::endl;
+ }
+ server->Start();
+
+ return 0;
+}
diff --git a/hal/dumpstate/aidl/1.0/service.cpp b/hal/dumpstate/aidl/1.0/service.cpp
new file mode 100644
index 0000000..5c58e0b
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/service.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 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/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "DumpstateDevice.h"
+#include "WatchdogClient.h"
+
+#include <vsockinfo.h>
+
+using ::aidl::android::hardware::dumpstate::implementation::DumpstateDevice;
+using ::aidl::android::hardware::dumpstate::implementation::WatchdogClient;
+using ::android::OK;
+using ::android::sp;
+using ::android::hardware::automotive::utils::VsockConnectionInfo;
+
+int main() {
+ const auto si = VsockConnectionInfo::fromRoPropertyStore(
+ {
+ "ro.boot.vendor.dumpstate.server.cid",
+ "ro.vendor.dumpstate.server.cid",
+ },
+ {
+ "ro.boot.vendor.dumpstate.server.port",
+ "ro.vendor.dumpstate.server.port",
+ });
+
+ if (!si) {
+ ALOGE("failed to get server connection cid/port; configure and try again.");
+ return 1;
+ } else {
+ ALOGI("Connecting to vsock server at %s", si->str().c_str());
+ }
+
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ // Create an instance of our service class
+ std::shared_ptr<DumpstateDevice> dumpstateImpl =
+ ndk::SharedRefBase::make<DumpstateDevice>(si->str());
+
+ const std::string instance = std::string() + DumpstateDevice::descriptor + "/default";
+ binder_status_t status =
+ AServiceManager_addService(dumpstateImpl->asBinder().get(), instance.c_str());
+ CHECK(status == STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/hal/dumpstate/aidl/1.0/tests/test_main.cpp b/hal/dumpstate/aidl/1.0/tests/test_main.cpp
new file mode 100644
index 0000000..d3f96f1
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/tests/test_main.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 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 "gtest/gtest.h"
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/hal/dumpstate/aidl/1.0/tests/tests.cpp b/hal/dumpstate/aidl/1.0/tests/tests.cpp
new file mode 100644
index 0000000..33446b2
--- /dev/null
+++ b/hal/dumpstate/aidl/1.0/tests/tests.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2020 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 "gtest/gtest.h"
+
+#include "DumpstateServer.h"
+#include "ServiceDescriptor.h"
+#include "ServiceSupplier.h"
+#include "config/XmlServiceSupplier.h"
+#include "config/dumpstate_hal_configuration_V1_0.h"
+
+#include <sstream>
+#include <string>
+
+static ServiceDescriptor MakePrinterService(const std::string& msg) {
+ return ServiceDescriptor{msg, "/bin/echo -n \"" + msg + "\""};
+}
+
+class AccumulatorConsumer : public ServiceDescriptor::OutputConsumer {
+ public:
+ void Write(char* ptr, size_t len) override { ss.write(ptr, len); }
+
+ std::string data() { return ss.str(); }
+
+ private:
+ std::stringstream ss;
+};
+
+TEST(DumpstateServer, RunCommand) {
+ auto svc = MakePrinterService("hello world");
+ AccumulatorConsumer ac;
+ auto ok = svc.GetOutput(&ac);
+ ASSERT_FALSE(ok.has_value());
+ ASSERT_EQ("hello world", ac.data());
+}
+
+TEST(Configuration, FromXmlBuffer) {
+ std::string buf = R"foo(
+<dumpstateHalConfiguration version="1.0">
+ <services>
+ <service name="svc1" command="cmd1"/>
+ <service name="svc2" command="cmd2 arg1"/>
+ </services>
+ <systemLogs>
+ <service name="log" command="logcat"/>
+ </systemLogs>
+</dumpstateHalConfiguration>
+ )foo";
+
+ auto supplier = XmlServiceSupplier::fromBuffer(buf);
+ ASSERT_TRUE(supplier.has_value());
+
+ ASSERT_TRUE(supplier->GetSystemLogsService().has_value());
+ ASSERT_EQ(2, supplier->GetServices().size());
+
+ ASSERT_STREQ("log", supplier->GetSystemLogsService()->name());
+ ASSERT_STREQ("logcat", supplier->GetSystemLogsService()->command());
+
+ ASSERT_STREQ("svc1", supplier->GetServices().at(0).name());
+ ASSERT_STREQ("svc2", supplier->GetServices().at(1).name());
+
+ ASSERT_STREQ("cmd1", supplier->GetServices().at(0).command());
+ ASSERT_STREQ("cmd2 arg1", supplier->GetServices().at(1).command());
+}
diff --git a/hal/vehicle/2.0/Android.bp b/hal/vehicle/2.0/Android.bp
index e72a9ea..38db924 100644
--- a/hal/vehicle/2.0/Android.bp
+++ b/hal/vehicle/2.0/Android.bp
@@ -148,12 +148,9 @@
vendor: true,
relative_install_path: "hw",
srcs: [
- "GrpcVehicleClient.cpp",
"VirtualizedVehicleService.cpp",
- "WatchdogClient.cpp",
],
shared_libs: [
- "android.hardware.automotive.utils.watchdog",
"libbase",
"libcutils",
"libjsoncpp",
@@ -161,11 +158,7 @@
"libgrpc++",
],
static_libs: [
- "android.hardware.automotive.utils.vsockinfo",
- "android.hardware.automotive.vehicle@2.0-manager-lib",
- "android.hardware.automotive.vehicle@2.0-default-impl-lib",
- "android.hardware.automotive.vehicle@2.0-grpc-trout",
- "android.hardware.automotive.vehicle@2.0-virtualization-utils",
+ "android.hardware.automotive.vehicle@2.0-virtualization-client-lib",
],
cflags: [
"-Wno-unused-parameter",
diff --git a/hal/vehicle/2.0/GarageModeServerSideHandler.cpp b/hal/vehicle/2.0/GarageModeServerSideHandler.cpp
index b19b1df..60c36bf 100644
--- a/hal/vehicle/2.0/GarageModeServerSideHandler.cpp
+++ b/hal/vehicle/2.0/GarageModeServerSideHandler.cpp
@@ -146,19 +146,20 @@
return;
}
- int watchDescriptor = inotify_add_watch(inotifyFd, mPowerStateMarkerPath.c_str(), IN_MODIFY);
- if (watchDescriptor < 0) {
- LOG(ERROR) << __func__ << ": failed to watch file " << mPowerStateMarkerPath << " : "
- << strerror(errno);
- return;
- }
-
alignas(alignof(struct inotify_event)) char inotifyEventBuffer[4096] = {0};
[[maybe_unused]] struct inotify_event& inotifyEvent =
*reinterpret_cast<struct inotify_event*>(inotifyEventBuffer);
HandleNewPowerState();
while (!mShuttingDownFlag.load()) {
+ int watchDescriptor =
+ inotify_add_watch(inotifyFd, mPowerStateMarkerPath.c_str(), IN_MODIFY);
+ if (watchDescriptor < 0) {
+ LOG(ERROR) << __func__ << ": failed to watch file " << mPowerStateMarkerPath << " : "
+ << strerror(errno);
+ return;
+ }
+
if (!WaitForReadWithTimeout(inotifyFd, kFileStatusCheckPeriod)) {
continue;
}
diff --git a/hal/vehicle/2.0/GrpcVehicleClient.cpp b/hal/vehicle/2.0/GrpcVehicleClient.cpp
index be6e297..d23c651 100644
--- a/hal/vehicle/2.0/GrpcVehicleClient.cpp
+++ b/hal/vehicle/2.0/GrpcVehicleClient.cpp
@@ -64,6 +64,10 @@
StatusCode setProperty(const VehiclePropValue& value, bool updateStatus) override;
+ // methods from VehicleHalClient
+
+ void triggerSendAllValues() override;
+
private:
void StartValuePollingThread();
@@ -119,6 +123,18 @@
return static_cast<StatusCode>(vhal_status.status_code());
}
+void GrpcVehicleClientImpl::triggerSendAllValues() {
+ ::grpc::ClientContext context;
+ ::google::protobuf::Empty empty_response;
+
+ auto grpc_status = mGrpcStub->SendAllPropertyValuesToStream(
+ &context, ::google::protobuf::Empty(), &empty_response);
+ if (!grpc_status.ok()) {
+ LOG(ERROR) << __func__ << ": GRPC SendAllPropertyValuesToStream Failed: "
+ << grpc_status.error_message();
+ }
+}
+
void GrpcVehicleClientImpl::StartValuePollingThread() {
mPollingThread = std::thread([this]() {
while (!mShuttingDownFlag.load()) {
diff --git a/hal/vehicle/2.0/GrpcVehicleServer.cpp b/hal/vehicle/2.0/GrpcVehicleServer.cpp
index 0a7ec9f..c5e2f33 100644
--- a/hal/vehicle/2.0/GrpcVehicleServer.cpp
+++ b/hal/vehicle/2.0/GrpcVehicleServer.cpp
@@ -71,6 +71,10 @@
const vhal_proto::WrappedVehiclePropValue* wrappedPropValue,
vhal_proto::VehicleHalCallStatus* status) override;
+ ::grpc::Status SendAllPropertyValuesToStream(::grpc::ServerContext* context,
+ const ::google::protobuf::Empty*,
+ ::google::protobuf::Empty*) override;
+
::grpc::Status StartPropertyValuesStream(
::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::grpc::ServerWriter<vhal_proto::WrappedVehiclePropValue>* stream) override;
@@ -251,6 +255,13 @@
return ::grpc::Status::OK;
}
+::grpc::Status GrpcVehicleServerImpl::SendAllPropertyValuesToStream(
+ ::grpc::ServerContext* context, const ::google::protobuf::Empty*,
+ ::google::protobuf::Empty*) {
+ sendAllValuesToClient();
+ return ::grpc::Status::OK;
+}
+
::grpc::Status GrpcVehicleServerImpl::StartPropertyValuesStream(
::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::grpc::ServerWriter<vhal_proto::WrappedVehiclePropValue>* stream) {
diff --git a/hal/vehicle/2.0/VirtualizedVehicleService.cpp b/hal/vehicle/2.0/VirtualizedVehicleService.cpp
index 73d2356..14902d8 100644
--- a/hal/vehicle/2.0/VirtualizedVehicleService.cpp
+++ b/hal/vehicle/2.0/VirtualizedVehicleService.cpp
@@ -18,19 +18,13 @@
#include <android/binder_process.h>
#include <hidl/HidlTransportSupport.h>
-#include <utils/Errors.h>
-#include <utils/Looper.h>
-#include <utils/StrongPointer.h>
-
#include <vhal_v2_0/EmulatedVehicleConnector.h>
#include <vhal_v2_0/EmulatedVehicleHal.h>
#include <vhal_v2_0/VehicleHalManager.h>
#include "GrpcVehicleClient.h"
#include "Utils.h"
-#include "WatchdogClient.h"
-using android::Looper;
using android::OK;
using android::status_t;
using android::hardware::configureRpcThreadpool;
@@ -62,21 +56,7 @@
}
LOG(INFO) << "Ready";
-
- // Setup a binder thread pool to be a car watchdog client.
- ABinderProcess_setThreadPoolMaxThreadCount(1);
- ABinderProcess_startThreadPool();
- android::sp<Looper> looper(Looper::prepare(0 /* opts */));
- auto watchdogClient =
- ndk::SharedRefBase::make<vhal_impl::WatchdogClient>(looper, service.get());
- if (!watchdogClient->initialize()) {
- ALOGE("Failed to initialize car watchdog client");
- return 1;
- }
-
- while (true) {
- looper->pollAll(-1 /* timeoutMillis */);
- }
+ joinRpcThreadpool();
// We don't ever actually expect to return, so return an error if we do get here
return 1;
diff --git a/hal/vehicle/2.0/WatchdogClient.cpp b/hal/vehicle/2.0/WatchdogClient.cpp
deleted file mode 100644
index 4130b20..0000000
--- a/hal/vehicle/2.0/WatchdogClient.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2020 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 "trout.audiocontrol@2.0-watchdog"
-
-#include "WatchdogClient.h"
-
-#include <android/binder_manager.h>
-
-using aidl::android::automotive::watchdog::ICarWatchdog;
-using aidl::android::automotive::watchdog::TimeoutLength;
-
-namespace {
-
-enum { WHAT_CHECK_ALIVE = 1 };
-
-} // namespace
-
-namespace android::hardware::automotive::vehicle::V2_0::impl {
-
-WatchdogClient::WatchdogClient(const sp<Looper>& handlerLooper, VehicleHalManager* vhal)
- : BaseWatchdogClient(handlerLooper), mHal(vhal) {}
-
-bool WatchdogClient::isClientHealthy() const {
- // This implementation is the same as the one for the default VHAL
- StatusCode status = StatusCode::TRY_AGAIN;
- VehiclePropValue propValue = {.prop = (int32_t)VehicleProperty::PERF_VEHICLE_SPEED};
- while (status == StatusCode::TRY_AGAIN) {
- mHal->get(propValue, [&propValue, &status](StatusCode s, const VehiclePropValue& v) {
- status = s;
- if (s == StatusCode::OK) {
- propValue = v;
- }
- });
- }
- return status == StatusCode::OK;
-}
-
-} // namespace android::hardware::automotive::vehicle::V2_0::impl
diff --git a/hal/vehicle/2.0/WatchdogClient.h b/hal/vehicle/2.0/WatchdogClient.h
deleted file mode 100644
index 9fad5a0..0000000
--- a/hal/vehicle/2.0/WatchdogClient.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2020 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 "BaseWatchdogClient.h"
-
-#include <aidl/android/automotive/watchdog/BnCarWatchdog.h>
-#include <aidl/android/automotive/watchdog/BnCarWatchdogClient.h>
-#include <utils/Looper.h>
-#include <utils/Mutex.h>
-#include <vhal_v2_0/VehicleHalManager.h>
-
-namespace android::hardware::automotive::vehicle::V2_0::impl {
-
-class WatchdogClient : public android::hardware::automotive::utils::BaseWatchdogClient {
- public:
- WatchdogClient(const ::android::sp<::android::Looper>& handlerLooper, VehicleHalManager* vhal);
-
- protected:
- bool isClientHealthy() const override;
-
- private:
- VehicleHalManager* mHal;
-};
-
-} // namespace android::hardware::automotive::vehicle::V2_0::impl
diff --git a/hal/vehicle/2.0/agl_build/CMakeLists.txt b/hal/vehicle/2.0/agl_build/CMakeLists.txt
index 9ac6526..dbf7150 100644
--- a/hal/vehicle/2.0/agl_build/CMakeLists.txt
+++ b/hal/vehicle/2.0/agl_build/CMakeLists.txt
@@ -50,6 +50,7 @@
${trout_NATIVE_VHAL_ROOT_DIR}/common/src/Obd2SensorStore.cpp
${trout_NATIVE_VHAL_ROOT_DIR}/common/src/VehicleObjectPool.cpp
${trout_NATIVE_VHAL_ROOT_DIR}/common/src/VehicleUtils.cpp
+ ${trout_NATIVE_VHAL_ROOT_DIR}/common/src/VehiclePropertyStore.cpp
${trout_NATIVE_VHAL_ROOT_DIR}/impl/vhal_v2_0/VehicleHalServer.cpp
${trout_NATIVE_VHAL_ROOT_DIR}/impl/vhal_v2_0/GeneratorHub.cpp
${trout_NATIVE_VHAL_ROOT_DIR}/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
diff --git a/hal/vehicle/2.0/proto/VehicleServer.proto b/hal/vehicle/2.0/proto/VehicleServer.proto
index 30c312e..272cb1f 100644
--- a/hal/vehicle/2.0/proto/VehicleServer.proto
+++ b/hal/vehicle/2.0/proto/VehicleServer.proto
@@ -51,6 +51,9 @@
// Change the property value of the vehicle
rpc SetProperty(WrappedVehiclePropValue) returns (VehicleHalCallStatus) {}
+ // Sending all current values to the streams
+ rpc SendAllPropertyValuesToStream(google.protobuf.Empty) returns (google.protobuf.Empty) {}
+
// Start a vehicle property value stream
rpc StartPropertyValuesStream(google.protobuf.Empty) returns (stream WrappedVehiclePropValue) {}
}