Adding v2 of audiocontrol hal
- Removes deprecated getBusForContext
- Adds APIs for enabling HAL to request and abandon audio focus
Bug: 148098383
Test: vts-tradefed -module VtsHalAudioControlV2_0TargetTest
Change-Id: I353bbd8ea7708ffb59831a8e1008951146798034
diff --git a/automotive/audiocontrol/2.0/Android.bp b/automotive/audiocontrol/2.0/Android.bp
new file mode 100644
index 0000000..2a9f849
--- /dev/null
+++ b/automotive/audiocontrol/2.0/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.automotive.audiocontrol@2.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IAudioControl.hal",
+ "ICloseHandle.hal",
+ "IFocusListener.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ "android.hardware.audio.common@6.0",
+ ],
+ gen_java: true,
+}
diff --git a/automotive/audiocontrol/2.0/IAudioControl.hal b/automotive/audiocontrol/2.0/IAudioControl.hal
new file mode 100644
index 0000000..1073498
--- /dev/null
+++ b/automotive/audiocontrol/2.0/IAudioControl.hal
@@ -0,0 +1,78 @@
+/*
+ * 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 android.hardware.automotive.audiocontrol@2.0;
+
+import ICloseHandle;
+import IFocusListener;
+import android.hardware.audio.common@6.0::AudioUsage;
+
+/**
+ * Interacts with the car's audio subsystem to manage audio sources and volumes
+ */
+interface IAudioControl {
+ /**
+ * Registers focus listener to be used by HAL for requesting and abandoning audio focus.
+ *
+ * It is expected that there will only ever be a single focus listener registered. If the
+ * observer dies, the HAL implementation must unregister observer automatically. If called when
+ * a listener is already registered, the existing one should be unregistered and replaced with
+ * the new listener.
+ *
+ * @param listener the listener interface
+ * @return closeHandle A handle to unregister observer.
+ */
+ registerFocusListener(IFocusListener listener) generates (ICloseHandle closeHandle);
+
+ /**
+ * Notifies HAL of changes in audio focus status for focuses requested or abandoned by the HAL.
+ *
+ * This will be called in response to IFocusListener's requestAudioFocus and
+ * abandonAudioFocus, as well as part of any change in focus being held by the HAL due focus
+ * request from other activities or services.
+ *
+ * The HAL is not required to wait for an callback of AUDIOFOCUS_GAIN before playing audio, nor
+ * is it required to stop playing audio in the event of a AUDIOFOCUS_LOSS callback is received.
+ *
+ * @param usage The audio usage associated with the focus change {@code AttributeUsage}
+ * @param zoneId The identifier for the audio zone that the HAL is playing the stream in
+ * @param focusChange the AudioFocusChange that has occurred
+ */
+ oneway onAudioFocusChange(bitfield<AudioUsage> usage, int32_t zoneId,
+ bitfield<AudioFocusChange> focusChange);
+
+ /**
+ * Control the right/left balance setting of the car speakers.
+ *
+ * This is intended to shift the speaker volume toward the right (+) or left (-) side of
+ * the car. 0.0 means "centered". +1.0 means fully right. -1.0 means fully left.
+ *
+ * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1
+ * range.
+ */
+ oneway setBalanceTowardRight(float value);
+
+ /**
+ * Control the fore/aft fade setting of the car speakers.
+ *
+ * This is intended to shift the speaker volume toward the front (+) or back (-) of the car.
+ * 0.0 means "centered". +1.0 means fully forward. -1.0 means fully rearward.
+ *
+ * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1
+ * range.
+ */
+ oneway setFadeTowardFront(float value);
+};
diff --git a/automotive/audiocontrol/2.0/ICloseHandle.hal b/automotive/audiocontrol/2.0/ICloseHandle.hal
new file mode 100644
index 0000000..537af6d
--- /dev/null
+++ b/automotive/audiocontrol/2.0/ICloseHandle.hal
@@ -0,0 +1,34 @@
+/*
+ * 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 android.hardware.automotive.audiocontrol@2.0;
+
+/**
+ * Represents a generic close handle to remove a callback that doesn't need
+ * active interface.
+ *
+ * When close() is called OR when the interface is released, the underlying
+ * resources must be freed.
+ */
+interface ICloseHandle {
+ /**
+ * Closes the handle.
+ *
+ * The call must not fail and must be issued by the client at most once.
+ * Otherwise, the server must ignore subsequent calls.
+ */
+ close();
+};
diff --git a/automotive/audiocontrol/2.0/IFocusListener.hal b/automotive/audiocontrol/2.0/IFocusListener.hal
new file mode 100644
index 0000000..4fd5ef0
--- /dev/null
+++ b/automotive/audiocontrol/2.0/IFocusListener.hal
@@ -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.
+ */
+
+package android.hardware.automotive.audiocontrol@2.0;
+
+import android.hardware.audio.common@6.0::AudioUsage;
+
+/**
+ * Callback interface for audio focus listener.
+ *
+ * For typical configuration, the listener the car audio service.
+ */
+interface IFocusListener {
+ /**
+ * Called whenever HAL is requesting focus as it is starting to play audio of a given usage in a
+ * specified zone.
+ *
+ * In response, IAudioControl#onAudioFocusChange will be called with focusChange status. This
+ * interaction is oneway to avoid blocking HAL so that it is not required to wait for a response
+ * before playing audio.
+ *
+ * @param usage The audio usage associated with the focus request {@code AttributeUsage}
+ * @param zoneId The identifier for the audio zone where the HAL is requesting focus
+ * @param focusGain The AudioFocusChange associated with this request. Should be one of the
+ * following: GAIN, GAIN_TRANSIENT, GAIN_TRANSIENT_MAY_DUCK, GAIN_TRANSIENT_EXCLUSIVE.
+ */
+ oneway requestAudioFocus(bitfield<AudioUsage> usage, int32_t zoneId,
+ bitfield<AudioFocusChange> focusGain);
+
+ /**
+ * Called whenever HAL is abandoning focus as it is finished playing audio of a given usage in a
+ * specific zone.
+ *
+ * In response, IAudioControl#onAudioFocusChange will be called with focusChange status. This
+ * interaction is oneway to avoid blocking HAL so that it is not required to wait for a response
+ * before stopping audio playback.
+ *
+ * @param usage The audio usage for which the HAL is abandoning focus {@code AttributeUsage}
+ * @param zoneId The identifier for the audio zone that the HAL abandoning focus
+ */
+ oneway abandonAudioFocus(bitfield<AudioUsage> usage, int32_t zoneId);
+};
diff --git a/automotive/audiocontrol/2.0/default/Android.bp b/automotive/audiocontrol/2.0/default/Android.bp
new file mode 100644
index 0000000..44ad028
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/Android.bp
@@ -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.
+
+cc_binary {
+ name: "android.hardware.automotive.audiocontrol@2.0-service",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "AudioControl.cpp",
+ "service.cpp",
+ "CloseHandle.cpp",
+ ],
+ init_rc: ["android.hardware.automotive.audiocontrol@2.0-service.rc"],
+
+ shared_libs: [
+ "android.hardware.automotive.audiocontrol@2.0",
+ "libbase",
+ "libhidlbase",
+ "liblog",
+ "libutils",
+ ],
+ vintf_fragments: ["audiocontrol2_manifest.xml"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/automotive/audiocontrol/2.0/default/AudioControl.cpp b/automotive/audiocontrol/2.0/default/AudioControl.cpp
new file mode 100644
index 0000000..6505e34
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/AudioControl.cpp
@@ -0,0 +1,60 @@
+#include "AudioControl.h"
+
+#include <android-base/logging.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "CloseHandle.h"
+
+namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
+
+AudioControl::AudioControl() {}
+
+Return<sp<ICloseHandle>> AudioControl::registerFocusListener(const sp<IFocusListener>& listener) {
+ LOG(DEBUG) << "registering focus listener";
+ sp<ICloseHandle> closeHandle(nullptr);
+
+ if (listener) {
+ mFocusListener = listener;
+
+ closeHandle = new CloseHandle([this, listener]() {
+ if (mFocusListener == listener) {
+ mFocusListener = nullptr;
+ }
+ });
+ } else {
+ LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op.";
+ }
+
+ return closeHandle;
+}
+
+Return<void> AudioControl::setBalanceTowardRight(float value) {
+ // For completeness, lets bounds check the input...
+ if (isValidValue(value)) {
+ LOG(ERROR) << "Balance value out of range -1 to 1 at " << value;
+ } else {
+ // Just log in this default mock implementation
+ LOG(INFO) << "Balance set to " << value;
+ }
+ return Void();
+}
+
+Return<void> AudioControl::setFadeTowardFront(float value) {
+ // For completeness, lets bounds check the input...
+ if (isValidValue(value)) {
+ LOG(ERROR) << "Fader value out of range -1 to 1 at " << value;
+ } else {
+ // Just log in this default mock implementation
+ LOG(INFO) << "Fader set to " << value;
+ }
+ return Void();
+}
+
+Return<void> AudioControl::onAudioFocusChange(hidl_bitfield<AudioUsage> usage, int zoneId,
+ hidl_bitfield<AudioFocusChange> focusChange) {
+ LOG(INFO) << "Focus changed: " << static_cast<int>(focusChange) << " for usage "
+ << static_cast<int>(usage) << " in zone " << zoneId;
+ return Void();
+}
+
+} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
diff --git a/automotive/audiocontrol/2.0/default/AudioControl.h b/automotive/audiocontrol/2.0/default/AudioControl.h
new file mode 100644
index 0000000..475a693
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/AudioControl.h
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V2_0_AUDIOCONTROL_H
+#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V2_0_AUDIOCONTROL_H
+
+#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>
+
+using android::hardware::audio::common::V6_0::AudioUsage;
+
+namespace android::hardware::automotive::audiocontrol::V2_0::implementation {
+
+class AudioControl : public IAudioControl {
+ public:
+ // 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;
+
+ // Implementation details
+ AudioControl();
+
+ private:
+ sp<IFocusListener> mFocusListener;
+ static bool isValidValue(float value) { return (value > 1.0f) || (value < -1.0f); }
+};
+
+} // namespace android::hardware::automotive::audiocontrol::V2_0::implementation
+
+#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V2_0_AUDIOCONTROL_H
diff --git a/automotive/audiocontrol/2.0/default/CloseHandle.cpp b/automotive/audiocontrol/2.0/default/CloseHandle.cpp
new file mode 100644
index 0000000..bc47931
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/CloseHandle.cpp
@@ -0,0 +1,35 @@
+/*
+ * 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/automotive/audiocontrol/2.0/default/CloseHandle.h b/automotive/audiocontrol/2.0/default/CloseHandle.h
new file mode 100644
index 0000000..6caf0bf
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/CloseHandle.h
@@ -0,0 +1,48 @@
+/*
+ * 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
+ */
+ 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/automotive/audiocontrol/2.0/default/android.hardware.automotive.audiocontrol@2.0-service.rc b/automotive/audiocontrol/2.0/default/android.hardware.automotive.audiocontrol@2.0-service.rc
new file mode 100644
index 0000000..81c9be4
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/android.hardware.automotive.audiocontrol@2.0-service.rc
@@ -0,0 +1,4 @@
+service vendor.audiocontrol-hal-2.0 /vendor/bin/hw/android.hardware.automotive.audiocontrol@2.0-service
+ class hal
+ user audioserver
+ group system
diff --git a/automotive/audiocontrol/2.0/default/audiocontrol2_manifest.xml b/automotive/audiocontrol/2.0/default/audiocontrol2_manifest.xml
new file mode 100644
index 0000000..42d23ed
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/audiocontrol2_manifest.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.automotive.audiocontrol</name>
+ <transport>hwbinder</transport>
+ <version>2.0</version>
+ <interface>
+ <name>IAudioControl</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
\ No newline at end of file
diff --git a/automotive/audiocontrol/2.0/default/service.cpp b/automotive/audiocontrol/2.0/default/service.cpp
new file mode 100644
index 0000000..dcc46c3
--- /dev/null
+++ b/automotive/audiocontrol/2.0/default/service.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 <hidl/HidlTransportSupport.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include "AudioControl.h"
+
+// libhidl:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::automotive::audiocontrol::V2_0::IAudioControl;
+
+// The namespace in which all our implementation code lives
+using namespace android::hardware::automotive::audiocontrol::V2_0::implementation;
+using namespace android;
+
+// Main service entry point
+int main() {
+ // Create an instance of our service class
+ android::sp<IAudioControl> service = new AudioControl();
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ if (service->registerAsService() != OK) {
+ LOG(ERROR) << "registerAsService failed";
+ return 1;
+ }
+
+ // Join (forever) the thread pool we created for the service above
+ joinRpcThreadpool();
+
+ // We don't ever actually expect to return, so return an error if we do get here
+ return 2;
+}
\ No newline at end of file
diff --git a/automotive/audiocontrol/2.0/types.hal b/automotive/audiocontrol/2.0/types.hal
new file mode 100644
index 0000000..65b0988
--- /dev/null
+++ b/automotive/audiocontrol/2.0/types.hal
@@ -0,0 +1,31 @@
+/*
+ * 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 android.hardware.automotive.audiocontrol@2.0;
+
+/**
+ * Changes in audio focus that can be experienced
+ */
+enum AudioFocusChange : uint32_t {
+ NONE = 0,
+ GAIN = 1,
+ GAIN_TRANSIENT = 2,
+ GAIN_TRANSIENT_MAY_DUCK = 3,
+ GAIN_TRANSIENT_EXCLUSIVE = 4,
+ LOSS = -1 * GAIN,
+ LOSS_TRANSIENT = -1 * GAIN_TRANSIENT,
+ LOSS_TRANSIENT_CAN_DUCK = -1 * GAIN_TRANSIENT_MAY_DUCK,
+};
diff --git a/automotive/audiocontrol/2.0/vts/functional/Android.bp b/automotive/audiocontrol/2.0/vts/functional/Android.bp
new file mode 100644
index 0000000..520b042
--- /dev/null
+++ b/automotive/audiocontrol/2.0/vts/functional/Android.bp
@@ -0,0 +1,29 @@
+//
+// 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.
+//
+
+cc_test {
+ name: "VtsHalAudioControlV2_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalAudioControlV2_0TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.automotive.audiocontrol@2.0",
+ "libgmock",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
+}
diff --git a/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp b/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp
new file mode 100644
index 0000000..0c10664
--- /dev/null
+++ b/automotive/audiocontrol/2.0/vts/functional/VtsHalAudioControlV2_0TargetTest.cpp
@@ -0,0 +1,155 @@
+/*
+ * 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 "VtsHalAudioControlTest"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/ProcessState.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#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/types.h>
+#include <android/log.h>
+
+using namespace ::android::hardware::automotive::audiocontrol::V2_0;
+using ::android::sp;
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::hidl_enum_range;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::audio::common::V6_0::AudioUsage;
+
+// The main test class for the automotive AudioControl HAL
+class CarAudioControlHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ // Make sure we can connect to the driver
+ pAudioControl = IAudioControl::getService(GetParam());
+ ASSERT_NE(pAudioControl.get(), nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ protected:
+ sp<IAudioControl> pAudioControl; // Every test needs access to the service
+};
+
+//
+// Tests start here...
+//
+
+/*
+ * Fader exercise test. Note that only a subjective observer could determine if the
+ * fader actually works. The only thing we can do is exercise the HAL and if the HAL crashes,
+ * we _might_ get a test failure if that breaks the connection to the driver.
+ */
+TEST_P(CarAudioControlHidlTest, FaderExercise) {
+ ALOGI("Fader exercise test (silent)");
+
+ // Set the fader all the way to the back
+ pAudioControl->setFadeTowardFront(-1.0f);
+
+ // Set the fader all the way to the front
+ pAudioControl->setFadeTowardFront(1.0f);
+
+ // Set the fader part way toward the back
+ pAudioControl->setFadeTowardFront(-0.333f);
+
+ // Set the fader to a out of bounds value (driver should clamp)
+ pAudioControl->setFadeTowardFront(99999.9f);
+
+ // Set the fader back to the middle
+ pAudioControl->setFadeTowardFront(0.0f);
+}
+
+/*
+ * Balance exercise test.
+ */
+TEST_P(CarAudioControlHidlTest, BalanceExercise) {
+ ALOGI("Balance exercise test (silent)");
+
+ // Set the balance all the way to the left
+ pAudioControl->setBalanceTowardRight(-1.0f);
+
+ // Set the balance all the way to the right
+ pAudioControl->setBalanceTowardRight(1.0f);
+
+ // Set the balance part way toward the left
+ pAudioControl->setBalanceTowardRight(-0.333f);
+
+ // Set the balance to a out of bounds value (driver should clamp)
+ pAudioControl->setBalanceTowardRight(99999.9f);
+
+ // Set the balance back to the middle
+ pAudioControl->setBalanceTowardRight(0.0f);
+}
+
+struct FocusListenerMock : public IFocusListener {
+ MOCK_METHOD(Return<void>, requestAudioFocus,
+ (hidl_bitfield<AudioUsage> usage, int zoneId,
+ hidl_bitfield<AudioFocusChange> focusGain));
+ MOCK_METHOD(Return<void>, abandonAudioFocus, (hidl_bitfield<AudioUsage> usage, int zoneId));
+};
+
+/*
+ * Test focus listener registration.
+ *
+ * Verifies that:
+ * - registerFocusListener succeeds;
+ * - registering a second listener succeeds in replacing the first;
+ * - closing handle does not crash;
+ */
+TEST_P(CarAudioControlHidlTest, FocusListenerRegistration) {
+ ALOGI("Focus listener test");
+
+ sp<FocusListenerMock> listener = new FocusListenerMock();
+
+ auto hidlResult = pAudioControl->registerFocusListener(listener);
+ ASSERT_TRUE(hidlResult.isOk());
+
+ sp<FocusListenerMock> listener2 = new FocusListenerMock();
+
+ auto hidlResult2 = pAudioControl->registerFocusListener(listener2);
+ ASSERT_TRUE(hidlResult2.isOk());
+
+ const sp<ICloseHandle>& closeHandle = hidlResult2;
+ closeHandle->close();
+};
+
+TEST_P(CarAudioControlHidlTest, FocusChangeExercise) {
+ ALOGI("Focus Change test");
+
+ pAudioControl->onAudioFocusChange(AudioUsage::MEDIA | 0, 0,
+ AudioFocusChange::GAIN_TRANSIENT | 0);
+};
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, CarAudioControlHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IAudioControl::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file