-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+parcelable MutingInfo {
+ int zoneId;
+ String[] deviceAddressesToMute;
+ String[] deviceAddressesToUnmute;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..3dc393a5805e8f04eade7c6f89b02e9ae17ff945
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -0,0 +1,29 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @VintfStability
+enum AudioFocusChange {
+ NONE = 0,
+ GAIN = 1,
+ GAIN_TRANSIENT = 2,
+ GAIN_TRANSIENT_MAY_DUCK = 3,
+ GAIN_TRANSIENT_EXCLUSIVE = 4,
+ LOSS = -1,
+ LOSS_TRANSIENT = -2,
+ LOSS_TRANSIENT_CAN_DUCK = -3,
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..6d729e22058319e6c236a327af5d0deccc97c193
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+parcelable DuckingInfo {
+ int zoneId;
+ String[] deviceAddressesToDuck;
+ String[] deviceAddressesToUnduck;
+ String[] usagesHoldingFocus;
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..bc4162bc8bc8d8e149f341d93cbc0db3ba874133
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+interface IAudioControl {
+ oneway void onAudioFocusChange(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusChange);
+ oneway void onDevicesToDuckChange(in android.hardware.automotive.audiocontrol.DuckingInfo[] duckingInfos);
+ oneway void onDevicesToMuteChange(in android.hardware.automotive.audiocontrol.MutingInfo[] mutingInfos);
+ oneway void registerFocusListener(in android.hardware.automotive.audiocontrol.IFocusListener listener);
+ oneway void setBalanceTowardRight(in float value);
+ oneway void setFadeTowardFront(in float value);
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..f00f042a0217530d8d08061d4364e513b3d7f762
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IFocusListener.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+interface IFocusListener {
+ oneway void abandonAudioFocus(in String usage, in int zoneId);
+ oneway void requestAudioFocus(in String usage, in int zoneId, in android.hardware.automotive.audiocontrol.AudioFocusChange focusGain);
+}
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..ab902ec97199390188481044af0c04979840a79a
--- /dev/null
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/MutingInfo.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.automotive.audiocontrol;
+@VintfStability
+parcelable MutingInfo {
+ int zoneId;
+ String[] deviceAddressesToMute;
+ String[] deviceAddressesToUnmute;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..98fa4e83e3eb972741c326f7704dc94bd431ba4f
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * Changes in audio focus that can be experienced
+ */
+@VintfStability
+@Backing(type="int")
+enum AudioFocusChange {
+ 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,
+}
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..e95fe9bb2e7c8c97ef9d299d0c780c53d5faf6a2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DuckingInfo.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+ /**
+ * The current ducking information for a single audio zone.
+ *
+ * This includes devices to duck, as well as unduck based on the contents of a previous
+ * {@link DuckingInfo}. Additionally, the current usages holding focus in the specified zone are
+ * included, which were used to determine which addresses to duck.
+ */
+ @VintfStability
+ parcelable DuckingInfo {
+ /**
+ * ID of the associated audio zone
+ */
+ int zoneId;
+
+ /**
+ * List of addresses for audio output devices that should be ducked.
+ *
+ *
The provided address strings are defined in audio_policy_configuration.xml.
+ */
+ String[] deviceAddressesToDuck;
+
+ /**
+ * List of addresses for audio output devices that were previously be ducked and should now be
+ * unducked.
+ *
+ *
The provided address strings are defined in audio_policy_configuration.xml.
+ */
+ String[] deviceAddressesToUnduck;
+
+ /**
+ * List of usages currently holding focus for this audio zone.
+ *
+ *
See {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
+ */
+ String[] usagesHoldingFocus;
+ }
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..3a0224557ff79d27364e241bea075dc41846fede
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import android.hardware.automotive.audiocontrol.AudioFocusChange;
+import android.hardware.automotive.audiocontrol.DuckingInfo;
+import android.hardware.automotive.audiocontrol.MutingInfo;
+import android.hardware.automotive.audiocontrol.IFocusListener;
+
+/**
+ * Interacts with the car's audio subsystem to manage audio sources and volumes
+ */
+@VintfStability
+interface IAudioControl {
+ /**
+ * 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}. See
+ * {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
+ * @param zoneId The identifier for the audio zone that the HAL is playing the stream in
+ * @param focusChange the AudioFocusChange that has occurred.
+ */
+ oneway void onAudioFocusChange(in String usage, in int zoneId, in AudioFocusChange focusChange);
+
+ /**
+ * Notifies HAL of changes in output devices that the HAL should apply ducking to.
+ *
+ * This will be called in response to changes in audio focus, and will include a
+ * {@link DuckingInfo} object per audio zone that experienced a change in audo focus.
+ *
+ * @param duckingInfos an array of {@link DuckingInfo} objects for the audio zones where audio
+ * focus has changed.
+ */
+ oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos);
+
+ /**
+ * Notifies HAL of changes in output devices that the HAL should apply muting to.
+ *
+ * This will be called in response to changes in audio mute state for each volume group
+ * and will include a {@link MutingInfo} object per audio zone that experienced a mute state
+ * event.
+ *
+ * @param mutingInfos an array of {@link MutingInfo} objects for the audio zones where audio
+ * mute state has changed.
+ */
+ oneway void onDevicesToMuteChange(in MutingInfo[] mutingInfos);
+
+ /**
+ * 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.
+ */
+ oneway void registerFocusListener(in IFocusListener listener);
+
+ /**
+ * 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 void setBalanceTowardRight(in 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 void setFadeTowardFront(in float value);
+}
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..b79295a6da9b07718dcd968fd2a9bf4d07267cac
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IFocusListener.aidl
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+import android.hardware.automotive.audiocontrol.AudioFocusChange;
+
+/**
+ * Callback interface for audio focus listener.
+ *
+ * For typical configuration, the listener the car audio service.
+ */
+@VintfStability
+interface IFocusListener {
+ /**
+ * 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}.
+ * See {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
+ * @param zoneId The identifier for the audio zone that the HAL abandoning focus
+ */
+ oneway void abandonAudioFocus(in String usage, in int zoneId);
+
+ /**
+ * 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}. See
+ * {@code audioUsage} in audio_policy_configuration.xsd for the list of allowed values.
+ * @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 void requestAudioFocus(in String usage, in int zoneId, in AudioFocusChange focusGain);
+}
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.aidl
new file mode 100644
index 0000000000000000000000000000000000000000..783640fcfe1a1bd599bacde6b5ebfe73745b353e
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/MutingInfo.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+ /**
+ * The current muting information for a single audio zone.
+ *
+ *
This includes devices to mute, as well as mute based on the contents of a previous
+ * {@link MutingInfo}.
+ */
+ @VintfStability
+ parcelable MutingInfo {
+ /**
+ * ID of the associated audio zone
+ */
+ int zoneId;
+
+ /**
+ * List of addresses for audio output devices that should be muted.
+ *
+ *
The provided address strings are defined in audio_policy_configuration.xml.
+ */
+ String[] deviceAddressesToMute;
+
+ /**
+ * List of addresses for audio output devices that were previously be muted and should now be
+ * unmuted.
+ *
+ *
The provided address strings are defined in audio_policy_configuration.xml.
+ */
+ String[] deviceAddressesToUnmute;
+ }
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
new file mode 100644
index 0000000000000000000000000000000000000000..1439cce60686dbac89dd9a1124ee0e61c69a4df5
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -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.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_binary {
+ name: "android.hardware.automotive.audiocontrol-service.example",
+ relative_install_path: "hw",
+ init_rc: ["audiocontrol-default.rc"],
+ vintf_fragments: ["audiocontrol-default.xml"],
+ vendor: true,
+ shared_libs: [
+ "android.hardware.audio.common@7.0-enums",
+ "android.frameworks.automotive.powerpolicy-V1-ndk",
+ "android.hardware.automotive.audiocontrol-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libpowerpolicyclient",
+ ],
+ srcs: [
+ "AudioControl.cpp",
+ "main.cpp",
+ "PowerPolicyClient.cpp",
+ ],
+}
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c0bc796cdf46db37bb43c6d52e5b7637d7339b67
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp
@@ -0,0 +1,269 @@
+/*
+ * 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 "AudioControl"
+// #define LOG_NDEBUG 0
+
+#include "AudioControl.h"
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+namespace aidl::android::hardware::automotive::audiocontrol {
+
+using ::android::base::EqualsIgnoreCase;
+using ::android::base::ParseInt;
+using ::std::shared_ptr;
+using ::std::string;
+
+namespace xsd {
+using namespace ::android::audio::policy::configuration::V7_0;
+}
+
+namespace {
+const float kLowerBound = -1.0f;
+const float kUpperBound = 1.0f;
+bool checkCallerHasWritePermissions(int fd) {
+ // Double check that's only called by root - it should be be blocked at debug() level,
+ // but it doesn't hurt to make sure...
+ if (AIBinder_getCallingUid() != AID_ROOT) {
+ dprintf(fd, "Must be root\n");
+ return false;
+ }
+ return true;
+}
+
+bool isValidValue(float value) {
+ return (value >= kLowerBound) && (value <= kUpperBound);
+}
+
+bool safelyParseInt(string s, int* out) {
+ if (!ParseInt(s, out)) {
+ return false;
+ }
+ return true;
+}
+} // namespace
+
+ndk::ScopedAStatus AudioControl::registerFocusListener(
+ const shared_ptr& in_listener) {
+ LOG(DEBUG) << "registering focus listener";
+
+ if (in_listener) {
+ std::atomic_store(&mFocusListener, in_listener);
+ } else {
+ LOG(ERROR) << "Unexpected nullptr for listener resulting in no-op.";
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::setBalanceTowardRight(float value) {
+ if (isValidValue(value)) {
+ // Just log in this default mock implementation
+ LOG(INFO) << "Balance set to " << value;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ LOG(ERROR) << "Balance value out of range -1 to 1 at " << value;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::setFadeTowardFront(float value) {
+ if (isValidValue(value)) {
+ // Just log in this default mock implementation
+ LOG(INFO) << "Fader set to " << value;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ LOG(ERROR) << "Fader value out of range -1 to 1 at " << 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& 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& 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) {
+ if (numArgs == 0) {
+ return dumpsys(fd);
+ }
+
+ string option = string(args[0]);
+ if (EqualsIgnoreCase(option, "--help")) {
+ return cmdHelp(fd);
+ } else if (EqualsIgnoreCase(option, "--request")) {
+ return cmdRequestFocus(fd, args, numArgs);
+ } else if (EqualsIgnoreCase(option, "--abandon")) {
+ return cmdAbandonFocus(fd, args, numArgs);
+ } else {
+ dprintf(fd, "Invalid option: %s\n", option.c_str());
+ return STATUS_BAD_VALUE;
+ }
+}
+
+binder_status_t AudioControl::dumpsys(int fd) {
+ if (mFocusListener == nullptr) {
+ dprintf(fd, "No focus listener registered\n");
+ } else {
+ dprintf(fd, "Focus listener registered\n");
+ }
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdHelp(int fd) const {
+ dprintf(fd, "Usage: \n\n");
+ dprintf(fd, "[no args]: dumps focus listener status\n");
+ dprintf(fd, "--help: shows this help\n");
+ dprintf(fd,
+ "--request : requests audio focus for specified "
+ "usage (string), audio zone ID (int), and focus gain type (int)\n");
+ dprintf(fd,
+ "--abandon : abandons audio focus for specified usage (string) and "
+ "audio zone ID (int)\n");
+ dprintf(fd, "See audio_policy_configuration.xsd for valid AudioUsage values.\n");
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdRequestFocus(int fd, const char** args, uint32_t numArgs) {
+ if (!checkCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 4) {
+ dprintf(fd,
+ "Invalid number of arguments: please provide --request "
+ "\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ string usage = string(args[1]);
+ if (xsd::isUnknownAudioUsage(usage)) {
+ dprintf(fd,
+ "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 "
+ "for supported values\n",
+ usage.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int zoneId;
+ if (!safelyParseInt(string(args[2]), &zoneId)) {
+ dprintf(fd, "Non-integer zoneId provided with request: %s\n", string(args[2]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int focusGainValue;
+ if (!safelyParseInt(string(args[3]), &focusGainValue)) {
+ dprintf(fd, "Non-integer focusGain provided with request: %s\n", string(args[3]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+ AudioFocusChange focusGain = AudioFocusChange(focusGainValue);
+
+ if (mFocusListener == nullptr) {
+ dprintf(fd, "Unable to request focus - no focus listener registered\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ mFocusListener->requestAudioFocus(usage, zoneId, focusGain);
+ dprintf(fd, "Requested focus for usage %s, zoneId %d, and focusGain %d\n", usage.c_str(),
+ zoneId, focusGain);
+ return STATUS_OK;
+}
+
+binder_status_t AudioControl::cmdAbandonFocus(int fd, const char** args, uint32_t numArgs) {
+ if (!checkCallerHasWritePermissions(fd)) {
+ return STATUS_PERMISSION_DENIED;
+ }
+ if (numArgs != 3) {
+ dprintf(fd, "Invalid number of arguments: please provide --abandon \n");
+ return STATUS_BAD_VALUE;
+ }
+
+ string usage = string(args[1]);
+ if (xsd::isUnknownAudioUsage(usage)) {
+ dprintf(fd,
+ "Unknown usage provided: %s. Please see audio_policy_configuration.xsd V7_0 "
+ "for supported values\n",
+ usage.c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ int zoneId;
+ if (!safelyParseInt(string(args[2]), &zoneId)) {
+ dprintf(fd, "Non-integer zoneId provided with abandon: %s\n", string(args[2]).c_str());
+ return STATUS_BAD_VALUE;
+ }
+
+ if (mFocusListener == nullptr) {
+ dprintf(fd, "Unable to abandon focus - no focus listener registered\n");
+ return STATUS_BAD_VALUE;
+ }
+
+ mFocusListener->abandonAudioFocus(usage, zoneId);
+ dprintf(fd, "Abandoned focus for usage %s and zoneId %d\n", usage.c_str(), zoneId);
+ return STATUS_OK;
+}
+
+} // namespace aidl::android::hardware::automotive::audiocontrol
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h
new file mode 100644
index 0000000000000000000000000000000000000000..cca9c44004476aff52459af23c7776464ce67450
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/AudioControl.h
@@ -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.
+ */
+#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
+#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
+
+#include
+#include
+#include
+#include
+
+namespace aidl::android::hardware::automotive::audiocontrol {
+
+class AudioControl : public BnAudioControl {
+ public:
+ ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId,
+ AudioFocusChange in_focusChange) override;
+ ndk::ScopedAStatus onDevicesToDuckChange(
+ const std::vector& in_duckingInfos) override;
+ ndk::ScopedAStatus onDevicesToMuteChange(
+ const std::vector& in_mutingInfos) override;
+ ndk::ScopedAStatus registerFocusListener(
+ const std::shared_ptr& 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;
+
+ 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.
+ std::shared_ptr mFocusListener;
+
+ binder_status_t cmdHelp(int fd) const;
+ binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs);
+ binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs);
+ binder_status_t dumpsys(int fd);
+};
+
+} // namespace aidl::android::hardware::automotive::audiocontrol
+
+#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_AUDIOCONTROL_H
diff --git a/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp b/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..765733716b2ed1855e3280b081e75c32e2031e8f
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/PowerPolicyClient.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "PowerPolicyClient.h"
+#include "AudioControl.h"
+
+#include
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+
+namespace aafap = aidl::android::frameworks::automotive::powerpolicy;
+
+using aafap::CarPowerPolicy;
+using aafap::CarPowerPolicyFilter;
+using aafap::PowerComponent;
+using ::android::frameworks::automotive::powerpolicy::hasComponent;
+using ::ndk::ScopedAStatus;
+
+namespace {
+
+constexpr PowerComponent kAudioComponent = PowerComponent::AUDIO;
+
+} // namespace
+
+PowerPolicyClient::PowerPolicyClient(std::shared_ptr audioControl)
+ : mAudioControl(audioControl) {}
+
+void PowerPolicyClient::onInitFailed() {
+ LOG(ERROR) << "Initializing power policy client failed";
+}
+
+std::vector PowerPolicyClient::getComponentsOfInterest() {
+ std::vector components{kAudioComponent};
+ return components;
+}
+
+ScopedAStatus PowerPolicyClient::onPolicyChanged(const CarPowerPolicy& powerPolicy) {
+ if (hasComponent(powerPolicy.enabledComponents, kAudioComponent)) {
+ LOG(DEBUG) << "Power policy: Audio component is enabled";
+ // TODO(b/173719953): Do something when AUDIO is enabled.
+ } else if (hasComponent(powerPolicy.disabledComponents, kAudioComponent)) {
+ LOG(DEBUG) << "Power policy: Audio component is disabled";
+ // TODO(b/173719953): Do something when AUDIO is disabled.
+ }
+ return ScopedAStatus::ok();
+}
+
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/automotive/audiocontrol/aidl/default/PowerPolicyClient.h b/automotive/audiocontrol/aidl/default/PowerPolicyClient.h
new file mode 100644
index 0000000000000000000000000000000000000000..0b4d5b6c0a18252d811133c7887fbb9316deb0a7
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/PowerPolicyClient.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.
+ */
+
+#ifndef AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
+#define AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
+
+#include "PowerPolicyClientBase.h"
+
+#include
+
+namespace aidl::android::hardware::automotive::audiocontrol {
+
+class AudioControl;
+
+class PowerPolicyClient
+ : public ::android::frameworks::automotive::powerpolicy::PowerPolicyClientBase {
+ public:
+ explicit PowerPolicyClient(std::shared_ptr audioControl);
+
+ void onInitFailed();
+ std::vector<::aidl::android::frameworks::automotive::powerpolicy::PowerComponent>
+ getComponentsOfInterest() override;
+ ::ndk::ScopedAStatus onPolicyChanged(
+ const ::aidl::android::frameworks::automotive::powerpolicy::CarPowerPolicy&) override;
+
+ private:
+ std::shared_ptr mAudioControl;
+};
+
+} // namespace aidl::android::hardware::automotive::audiocontrol
+
+#endif // AUTOMOTIVE_AUDIOCONTROL_AIDL_DEFAULT_POWERPOLICYCLIENT_H_
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.rc b/automotive/audiocontrol/aidl/default/audiocontrol-default.rc
new file mode 100644
index 0000000000000000000000000000000000000000..88d180dbd1d55b626bdd69b7329e67ae6234d7d2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.rc
@@ -0,0 +1,4 @@
+service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example
+ class hal
+ user audioserver
+ group system
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f95d05fe7779353a24a941f7df027c5196a261db
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
@@ -0,0 +1,6 @@
+
+
+ android.hardware.automotive.audiocontrol
+ IAudioControl/default
+
+
diff --git a/automotive/audiocontrol/aidl/default/main.cpp b/automotive/audiocontrol/aidl/default/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b259fca0a005ea8aad989387d812a4f6a9f54fb
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/main.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 "AudioControl.h"
+#include "PowerPolicyClient.h"
+
+#include
+#include
+#include
+
+using aidl::android::hardware::automotive::audiocontrol::AudioControl;
+using aidl::android::hardware::automotive::audiocontrol::PowerPolicyClient;
+
+int main() {
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ std::shared_ptr audioControl = ::ndk::SharedRefBase::make();
+
+ 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);
+
+ std::shared_ptr powerPolicyClient =
+ ::ndk::SharedRefBase::make(audioControl);
+ powerPolicyClient->init();
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
+}
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
new file mode 100644
index 0000000000000000000000000000000000000000..6856b91d2b1418adee80afd83f36021f2b4596b0
--- /dev/null
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -0,0 +1,47 @@
+// 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 {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsAidlHalAudioControlTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ generated_headers: ["audio_policy_configuration_V7_0"],
+ generated_sources: ["audio_policy_configuration_V7_0"],
+ header_libs: ["libxsdc-utils"],
+ srcs: ["VtsHalAudioControlTargetTest.cpp"],
+ shared_libs: [
+ "libbinder",
+ "libbase",
+ "libxml2",
+ ],
+ static_libs: [
+ "android.hardware.automotive.audiocontrol-V1-cpp",
+ "libgmock",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ae53c685285b693c69b91cf1c9b3ad5aba12afb8
--- /dev/null
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -0,0 +1,173 @@
+/*
+ * 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 "VtsAidlHalAudioControlTest"
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+using android::ProcessState;
+using android::sp;
+using android::String16;
+using android::binder::Status;
+using android::hardware::automotive::audiocontrol::AudioFocusChange;
+using android::hardware::automotive::audiocontrol::BnFocusListener;
+using android::hardware::automotive::audiocontrol::DuckingInfo;
+using android::hardware::automotive::audiocontrol::IAudioControl;
+using android::hardware::automotive::audiocontrol::MutingInfo;
+
+#include "android_audio_policy_configuration_V7_0.h"
+
+namespace xsd {
+using namespace android::audio::policy::configuration::V7_0;
+}
+
+class AudioControlAidl : public testing::TestWithParam {
+ public:
+ virtual void SetUp() override {
+ audioControl = android::waitForDeclaredService(String16(GetParam().c_str()));
+ ASSERT_NE(audioControl, nullptr);
+ }
+
+ sp audioControl;
+ int32_t capabilities;
+};
+
+TEST_P(AudioControlAidl, OnSetFadeTowardsFront) {
+ ALOGI("Fader exercise test (silent)");
+
+ // Set the fader all the way to the back
+ ASSERT_TRUE(audioControl->setFadeTowardFront(-1.0f).isOk());
+
+ // Set the fader all the way to the front
+ ASSERT_TRUE(audioControl->setFadeTowardFront(1.0f).isOk());
+
+ // Set the fader part way toward the back
+ ASSERT_TRUE(audioControl->setFadeTowardFront(-0.333f).isOk());
+
+ // Set the fader to a out of bounds value (driver should clamp)
+ ASSERT_TRUE(audioControl->setFadeTowardFront(99999.9f).isOk());
+
+ // Set the fader to a negative out of bounds value (driver should clamp)
+ ASSERT_TRUE(audioControl->setFadeTowardFront(-99999.9f).isOk());
+
+ // Set the fader back to the middle
+ ASSERT_TRUE(audioControl->setFadeTowardFront(0.0f).isOk());
+}
+
+TEST_P(AudioControlAidl, OnSetBalanceTowardsRight) {
+ ALOGI("Balance exercise test (silent)");
+
+ // Set the balance all the way to the left
+ ASSERT_TRUE(audioControl->setBalanceTowardRight(-1.0f).isOk());
+
+ // Set the balance all the way to the right
+ ASSERT_TRUE(audioControl->setBalanceTowardRight(1.0f).isOk());
+
+ // Set the balance part way toward the left
+ ASSERT_TRUE(audioControl->setBalanceTowardRight(-0.333f).isOk());
+
+ // Set the balance to a out of bounds value (driver should clamp)
+ ASSERT_TRUE(audioControl->setBalanceTowardRight(99999.9f).isOk());
+
+ // Set the balance to a negative out of bounds value (driver should clamp)
+ ASSERT_TRUE(audioControl->setBalanceTowardRight(-99999.9f).isOk());
+
+ // Set the balance back to the middle
+ ASSERT_TRUE(audioControl->setBalanceTowardRight(0.0f).isOk());
+
+ // Set the balance back to the middle
+ audioControl->setBalanceTowardRight(0.0f).isOk();
+}
+
+struct FocusListenerMock : BnFocusListener {
+ MOCK_METHOD(Status, requestAudioFocus,
+ (const String16& usage, int32_t zoneId, AudioFocusChange focusGain));
+ MOCK_METHOD(Status, abandonAudioFocus, (const String16& usage, int32_t 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(AudioControlAidl, FocusListenerRegistration) {
+ ALOGI("Focus listener test");
+
+ sp listener = new FocusListenerMock();
+ ASSERT_TRUE(audioControl->registerFocusListener(listener).isOk());
+
+ sp listener2 = new FocusListenerMock();
+ ASSERT_TRUE(audioControl->registerFocusListener(listener2).isOk());
+};
+
+TEST_P(AudioControlAidl, FocusChangeExercise) {
+ ALOGI("Focus Change test");
+
+ String16 usage = String16(xsd::toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA).c_str());
+ ASSERT_TRUE(
+ audioControl->onAudioFocusChange(usage, 0, AudioFocusChange::GAIN_TRANSIENT).isOk());
+};
+
+TEST_P(AudioControlAidl, MuteChangeExercise) {
+ ALOGI("Mute change test");
+
+ MutingInfo mutingInfo;
+ mutingInfo.zoneId = 0;
+ mutingInfo.deviceAddressesToMute = {String16("address 1"), String16("address 2")};
+ mutingInfo.deviceAddressesToUnmute = {String16("address 3"), String16("address 4")};
+ std::vector mutingInfos = {mutingInfo};
+ ALOGI("Mute change test start");
+ ASSERT_TRUE(audioControl->onDevicesToMuteChange(mutingInfos).isOk());
+}
+
+TEST_P(AudioControlAidl, DuckChangeExercise) {
+ ALOGI("Duck change test");
+
+ DuckingInfo duckingInfo;
+ duckingInfo.zoneId = 0;
+ duckingInfo.deviceAddressesToDuck = {String16("address 1"), String16("address 2")};
+ duckingInfo.deviceAddressesToUnduck = {String16("address 3"), String16("address 4")};
+ duckingInfo.usagesHoldingFocus = {
+ String16(xsd::toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA).c_str()),
+ String16(xsd::toString(xsd::AudioUsage::AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
+ .c_str())};
+ std::vector duckingInfos = {duckingInfo};
+ ALOGI("Duck change test start");
+ ASSERT_TRUE(audioControl->onDevicesToDuckChange(duckingInfos).isOk());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl);
+INSTANTIATE_TEST_SUITE_P(
+ Audiocontrol, AudioControlAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ProcessState::self()->setThreadPoolMaxThreadCount(1);
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/automotive/can/1.0/default/Android.bp b/automotive/can/1.0/default/Android.bp
index 879decc4e771b9671dd82f8e1461b1bcdd13360e..c0c17e27f537c4bd2ad30aec5319de8544976ad6 100644
--- a/automotive/can/1.0/default/Android.bp
+++ b/automotive/can/1.0/default/Android.bp
@@ -62,5 +62,6 @@ cc_binary {
static_libs: [
"android.hardware.automotive.can@libnetdevice",
"android.hardware.automotive@libc++fs",
+ "libnl++",
],
}
diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp
index 8b98e5ee2bd9b33f62874800518ca9d459f4bf47..2efe0547eaadf4d81aa7875d7d591b69d5fffaf8 100644
--- a/automotive/can/1.0/default/CanBus.cpp
+++ b/automotive/can/1.0/default/CanBus.cpp
@@ -254,7 +254,7 @@ static bool match(const hidl_vec& filter, CanMessageId id, boo
satisfiesFilterFlag(rule.extendedFormat, isExtendedId);
if (rule.exclude) {
- // Any excluded (blacklist) rule not being satisfied invalidates the whole filter set.
+ // Any exclude rule being satisfied invalidates the whole filter set.
if (satisfied) return false;
} else {
anyNonExcludeRulePresent = true;
diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp
index 757d8e606399049e251be93a4bec0383a0192706..653e77324094a5532d051a2796125932e2536c02 100644
--- a/automotive/can/1.0/default/libnetdevice/Android.bp
+++ b/automotive/can/1.0/default/libnetdevice/Android.bp
@@ -27,13 +27,16 @@ cc_library_static {
name: "android.hardware.automotive.can@libnetdevice",
defaults: ["android.hardware.automotive.can@defaults"],
vendor_available: true,
- relative_install_path: "hw",
srcs: [
- "NetlinkRequest.cpp",
- "NetlinkSocket.cpp",
"can.cpp",
"common.cpp",
+ "ethtool.cpp",
+ "ifreqs.cpp",
"libnetdevice.cpp",
+ "vlan.cpp",
],
export_include_dirs: ["include"],
+ static_libs: [
+ "libnl++",
+ ],
}
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp
deleted file mode 100644
index 556debfc0911aa452d7af504083ca13eb45aacb0..0000000000000000000000000000000000000000
--- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 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 "NetlinkRequest.h"
-
-#include
-
-namespace android::netdevice::impl {
-
-static struct rtattr* nlmsg_tail(struct nlmsghdr* n) {
- return reinterpret_cast( //
- reinterpret_cast(n) + NLMSG_ALIGN(n->nlmsg_len));
-}
-
-struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, const void* data,
- size_t dataLen) {
- size_t newLen = NLMSG_ALIGN(n->nlmsg_len) + RTA_SPACE(dataLen);
- if (newLen > maxLen) {
- LOG(ERROR) << "addattr_l failed - exceeded maxLen: " << newLen << " > " << maxLen;
- return nullptr;
- }
-
- auto attr = nlmsg_tail(n);
- attr->rta_len = RTA_SPACE(dataLen);
- attr->rta_type = type;
- if (dataLen > 0) memcpy(RTA_DATA(attr), data, dataLen);
-
- n->nlmsg_len = newLen;
- return attr;
-}
-
-struct rtattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type) {
- return addattr_l(n, maxLen, type, nullptr, 0);
-}
-
-void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest) {
- size_t nestLen = reinterpret_cast(nlmsg_tail(n)) - reinterpret_cast(nest);
- nest->rta_len = nestLen;
-}
-
-} // namespace android::netdevice::impl
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h b/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
deleted file mode 100644
index 3e28d78485cc4be3a0488ef8d053b872e3e737f2..0000000000000000000000000000000000000000
--- a/automotive/can/1.0/default/libnetdevice/NetlinkRequest.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2019 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
-#include
-
-#include
-
-namespace android::netdevice {
-
-typedef unsigned short rtattrtype_t; // as in rtnetlink.h
-typedef __u16 nlmsgtype_t; // as in netlink.h
-
-/** Implementation details, do not use outside NetlinkRequest template. */
-namespace impl {
-
-struct rtattr* addattr_l(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type, const void* data,
- size_t dataLen);
-struct rtattr* addattr_nest(struct nlmsghdr* n, size_t maxLen, rtattrtype_t type);
-void addattr_nest_end(struct nlmsghdr* n, struct rtattr* nest);
-
-} // namespace impl
-
-/**
- * Wrapper around NETLINK_ROUTE messages, to build them in C++ style.
- *
- * \param T specific message header (such as struct ifinfomsg)
- * \param BUFSIZE how much space to reserve for payload (not counting the header size)
- */
-template
-struct NetlinkRequest {
- /**
- * Create empty message.
- *
- * \param type Message type (such as RTM_NEWLINK)
- * \param flags Message flags (such as NLM_F_REQUEST)
- */
- NetlinkRequest(nlmsgtype_t type, uint16_t flags) {
- mRequest.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(mRequest.data));
- mRequest.nlmsg.nlmsg_type = type;
- mRequest.nlmsg.nlmsg_flags = flags;
- }
-
- /** \return pointer to raw netlink message header. */
- struct nlmsghdr* header() {
- return &mRequest.nlmsg;
- }
- /** Reference to message-specific header. */
- T& data() { return mRequest.data; }
-
- /**
- * Adds an attribute of a simple type.
- *
- * If this method fails (i.e. due to insufficient space), the message will be marked
- * as bad (\see isGood).
- *
- * \param type attribute type (such as IFLA_IFNAME)
- * \param attr attribute data
- */
- template
- void addattr(rtattrtype_t type, const A& attr) {
- if (!mIsGood) return;
- auto ap = impl::addattr_l(&mRequest.nlmsg, sizeof(mRequest), type, &attr, sizeof(attr));
- if (ap == nullptr) mIsGood = false;
- }
-
- template <>
- void addattr(rtattrtype_t type, const std::string& s) {
- if (!mIsGood) return;
- auto ap = impl::addattr_l(&mRequest.nlmsg, sizeof(mRequest), type, s.c_str(), s.size() + 1);
- if (ap == nullptr) mIsGood = false;
- }
-
- /** Guard class to frame nested attributes. See nest(int). */
- struct Nest {
- Nest(NetlinkRequest& req, rtattrtype_t type) : mReq(req), mAttr(req.nestStart(type)) {}
- ~Nest() { mReq.nestEnd(mAttr); }
-
- private:
- NetlinkRequest& mReq;
- struct rtattr* mAttr;
-
- DISALLOW_COPY_AND_ASSIGN(Nest);
- };
-
- /**
- * Add nested attribute.
- *
- * The returned object is a guard for auto-nesting children inside the argument attribute.
- * When the Nest object goes out of scope, the nesting attribute is closed.
- *
- * Example usage nesting IFLA_CAN_BITTIMING inside IFLA_INFO_DATA, which is nested
- * inside IFLA_LINKINFO:
- * NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST);
- * {
- * auto linkinfo = req.nest(IFLA_LINKINFO);
- * req.addattr(IFLA_INFO_KIND, "can");
- * {
- * auto infodata = req.nest(IFLA_INFO_DATA);
- * req.addattr(IFLA_CAN_BITTIMING, bitTimingStruct);
- * }
- * }
- * // use req
- *
- * \param type attribute type (such as IFLA_LINKINFO)
- */
- Nest nest(int type) { return Nest(*this, type); }
-
- /**
- * Indicates, whether the message is in a good state.
- *
- * The bad state is usually a result of payload buffer being too small.
- * You can modify BUFSIZE template parameter to fix this.
- */
- bool isGood() const { return mIsGood; }
-
- private:
- bool mIsGood = true;
-
- struct {
- struct nlmsghdr nlmsg;
- T data;
- char buf[BUFSIZE];
- } mRequest = {};
-
- struct rtattr* nestStart(rtattrtype_t type) {
- if (!mIsGood) return nullptr;
- auto attr = impl::addattr_nest(&mRequest.nlmsg, sizeof(mRequest), type);
- if (attr == nullptr) mIsGood = false;
- return attr;
- }
-
- void nestEnd(struct rtattr* nest) {
- if (mIsGood && nest != nullptr) impl::addattr_nest_end(&mRequest.nlmsg, nest);
- }
-};
-
-} // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
deleted file mode 100644
index 7817169876ea474869cd928a517e36c9f491c0b0..0000000000000000000000000000000000000000
--- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019 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 "NetlinkSocket.h"
-
-#include
-
-namespace android::netdevice {
-
-NetlinkSocket::NetlinkSocket(int protocol) {
- mFd.reset(socket(AF_NETLINK, SOCK_RAW, protocol));
- if (!mFd.ok()) {
- PLOG(ERROR) << "Can't open Netlink socket";
- mFailed = true;
- return;
- }
-
- struct sockaddr_nl sa = {};
- sa.nl_family = AF_NETLINK;
-
- if (bind(mFd.get(), reinterpret_cast(&sa), sizeof(sa)) < 0) {
- PLOG(ERROR) << "Can't bind Netlink socket";
- mFd.reset();
- mFailed = true;
- }
-}
-
-bool NetlinkSocket::send(struct nlmsghdr* nlmsg) {
- if (mFailed) return false;
-
- nlmsg->nlmsg_pid = 0; // kernel
- nlmsg->nlmsg_seq = mSeq++;
- nlmsg->nlmsg_flags |= NLM_F_ACK;
-
- struct iovec iov = {nlmsg, nlmsg->nlmsg_len};
-
- struct sockaddr_nl sa = {};
- sa.nl_family = AF_NETLINK;
-
- struct msghdr msg = {};
- msg.msg_name = &sa;
- msg.msg_namelen = sizeof(sa);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- if (sendmsg(mFd.get(), &msg, 0) < 0) {
- PLOG(ERROR) << "Can't send Netlink message";
- return false;
- }
- return true;
-}
-
-bool NetlinkSocket::receiveAck() {
- if (mFailed) return false;
-
- char buf[8192];
-
- struct sockaddr_nl sa;
- struct iovec iov = {buf, sizeof(buf)};
-
- struct msghdr msg = {};
- msg.msg_name = &sa;
- msg.msg_namelen = sizeof(sa);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
-
- const ssize_t status = recvmsg(mFd.get(), &msg, 0);
- if (status < 0) {
- PLOG(ERROR) << "Failed to receive Netlink message";
- return false;
- }
- size_t remainingLen = status;
-
- if (msg.msg_flags & MSG_TRUNC) {
- LOG(ERROR) << "Failed to receive Netlink message: truncated";
- return false;
- }
-
- for (auto nlmsg = reinterpret_cast(buf); NLMSG_OK(nlmsg, remainingLen);
- nlmsg = NLMSG_NEXT(nlmsg, remainingLen)) {
- // We're looking for error/ack message only, ignoring others.
- if (nlmsg->nlmsg_type != NLMSG_ERROR) {
- LOG(WARNING) << "Received unexpected Netlink message (ignored): " << nlmsg->nlmsg_type;
- continue;
- }
-
- // Found error/ack message, return status.
- auto nlerr = reinterpret_cast(NLMSG_DATA(nlmsg));
- if (nlerr->error != 0) {
- LOG(ERROR) << "Received Netlink error message: " << nlerr->error;
- return false;
- }
- return true;
- }
- // Couldn't find any error/ack messages.
- return false;
-}
-
-} // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h b/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
deleted file mode 100644
index 2b40ea20c0bd0aaea07995e0fe9fbf8820f7691c..0000000000000000000000000000000000000000
--- a/automotive/can/1.0/default/libnetdevice/NetlinkSocket.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 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 "NetlinkRequest.h"
-
-#include
-#include
-
-#include
-
-namespace android::netdevice {
-
-/**
- * A wrapper around AF_NETLINK sockets.
- *
- * This class is not thread safe to use a single instance between multiple threads, but it's fine to
- * use multiple instances over multiple threads.
- */
-struct NetlinkSocket {
- NetlinkSocket(int protocol);
-
- /**
- * Send Netlink message to Kernel.
- *
- * \param msg Message to send, nlmsg_seq will be set to next sequence number
- * \return true, if succeeded
- */
- template
- bool send(NetlinkRequest& req) {
- if (!req.isGood()) return false;
- return send(req.header());
- }
-
- /**
- * Receive Netlink ACK message from Kernel.
- *
- * \return true if received ACK message, false in case of error
- */
- bool receiveAck();
-
- private:
- uint32_t mSeq = 0;
- base::unique_fd mFd;
- bool mFailed = false;
-
- bool send(struct nlmsghdr* msg);
-
- DISALLOW_COPY_AND_ASSIGN(NetlinkSocket);
-};
-
-} // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp
index a2a85dcae8a08107d3f270c34269216f264f5eee..083f4f002870d6b456ecbf8b44e71cb5bb219713 100644
--- a/automotive/can/1.0/default/libnetdevice/can.cpp
+++ b/automotive/can/1.0/default/libnetdevice/can.cpp
@@ -14,26 +14,27 @@
* limitations under the License.
*/
-#include
+#include
-#include "NetlinkRequest.h"
-#include "NetlinkSocket.h"
#include "common.h"
#include
#include
+#include
+#include
#include
#include
#include
#include
+#include
namespace android::netdevice::can {
static constexpr can_err_mask_t kErrMask = CAN_ERR_MASK;
base::unique_fd socket(const std::string& ifname) {
- struct sockaddr_can addr = {};
+ sockaddr_can addr = {};
addr.can_family = AF_CAN;
addr.can_ifindex = nametoindex(ifname);
if (addr.can_ifindex == 0) {
@@ -57,7 +58,7 @@ base::unique_fd socket(const std::string& ifname) {
return {};
}
- if (0 != bind(sock.get(), reinterpret_cast(&addr), sizeof(addr))) {
+ if (0 != bind(sock.get(), reinterpret_cast(&addr), sizeof(addr))) {
LOG(ERROR) << "Can't bind to CAN interface " << ifname;
return {};
}
@@ -66,31 +67,30 @@ base::unique_fd socket(const std::string& ifname) {
}
bool setBitrate(std::string ifname, uint32_t bitrate) {
- struct can_bittiming bt = {};
+ can_bittiming bt = {};
bt.bitrate = bitrate;
- NetlinkRequest req(RTM_NEWLINK, NLM_F_REQUEST);
+ nl::MessageFactory req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK);
- const auto ifidx = nametoindex(ifname);
- if (ifidx == 0) {
+ req->ifi_index = nametoindex(ifname);
+ if (req->ifi_index == 0) {
LOG(ERROR) << "Can't find interface " << ifname;
return false;
}
- req.data().ifi_index = ifidx;
{
- auto linkinfo = req.nest(IFLA_LINKINFO);
- req.addattr(IFLA_INFO_KIND, "can");
+ auto linkinfo = req.addNested(IFLA_LINKINFO);
+ req.add(IFLA_INFO_KIND, "can");
{
- auto infodata = req.nest(IFLA_INFO_DATA);
+ auto infodata = req.addNested(IFLA_INFO_DATA);
/* For CAN FD, it would require to add IFLA_CAN_DATA_BITTIMING
* and IFLA_CAN_CTRLMODE as well. */
- req.addattr(IFLA_CAN_BITTIMING, bt);
+ req.add(IFLA_CAN_BITTIMING, bt);
}
}
- NetlinkSocket sock(NETLINK_ROUTE);
- return sock.send(req) && sock.receiveAck();
+ nl::Socket sock(NETLINK_ROUTE);
+ return sock.send(req) && sock.receiveAck(req);
}
} // namespace android::netdevice::can
diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp
index 5c624439cd068c097fe68aed1cf8324c46d4f7c7..28e50af60ab504819e5be3e30c0137304b0332e5 100644
--- a/automotive/can/1.0/default/libnetdevice/common.cpp
+++ b/automotive/can/1.0/default/libnetdevice/common.cpp
@@ -26,9 +26,8 @@ unsigned int nametoindex(const std::string& ifname) {
const auto ifidx = if_nametoindex(ifname.c_str());
if (ifidx != 0) return ifidx;
- const auto err = errno;
- if (err != ENODEV) {
- LOG(ERROR) << "if_nametoindex(" << ifname << ") failed: " << err;
+ if (errno != ENODEV) {
+ PLOG(ERROR) << "if_nametoindex(" << ifname << ") failed";
}
return 0;
}
diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h
index 8097f374adc4b54e82dbff0cd5a4ee33cc745aeb..661e3f80f2d33aac9e188c9e320d861f1990e9b5 100644
--- a/automotive/can/1.0/default/libnetdevice/common.h
+++ b/automotive/can/1.0/default/libnetdevice/common.h
@@ -16,6 +16,9 @@
#pragma once
+#include
+#include
+
#include
namespace android::netdevice {
diff --git a/automotive/can/1.0/default/libnetdevice/ethtool.cpp b/automotive/can/1.0/default/libnetdevice/ethtool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..762ef5cc884f09867134ce3055175da136bf41a4
--- /dev/null
+++ b/automotive/can/1.0/default/libnetdevice/ethtool.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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
+
+#include "ifreqs.h"
+
+#include
+
+namespace android::netdevice::ethtool {
+
+std::optional getValue(const std::string& ifname, uint32_t command) {
+ struct ethtool_value valueop = {};
+ valueop.cmd = command;
+
+ auto ifr = ifreqs::fromName(ifname);
+ ifr.ifr_data = &valueop;
+
+ if (!ifreqs::send(SIOCETHTOOL, ifr)) return std::nullopt;
+ return valueop.data;
+}
+
+bool setValue(const std::string& ifname, uint32_t command, uint32_t value) {
+ struct ethtool_value valueop = {};
+ valueop.cmd = command;
+ valueop.data = value;
+
+ auto ifr = ifreqs::fromName(ifname);
+ ifr.ifr_data = &valueop;
+
+ return ifreqs::send(SIOCETHTOOL, ifr);
+}
+
+} // namespace android::netdevice::ethtool
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8df64347967da716f5fd115f36c5ad5bfb08581a
--- /dev/null
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.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 "ifreqs.h"
+
+#include "common.h"
+
+#include
+#include
+
+#include