Merge "DrmHalTest: null check for skipped test"
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 01af940..e6b0cee 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -120,8 +120,6 @@
"android/hardware/audio/core/IStreamOut.aidl",
"android/hardware/audio/core/IStreamOutEventCallback.aidl",
"android/hardware/audio/core/ITelephony.aidl",
- "android/hardware/audio/core/MicrophoneDynamicInfo.aidl",
- "android/hardware/audio/core/MicrophoneInfo.aidl",
"android/hardware/audio/core/MmapBufferDescriptor.aidl",
"android/hardware/audio/core/ModuleDebug.aidl",
"android/hardware/audio/core/StreamDescriptor.aidl",
@@ -225,11 +223,12 @@
],
srcs: [
"android/hardware/audio/effect/AcousticEchoCanceler.aidl",
- "android/hardware/audio/effect/AutomaticGainControl.aidl",
"android/hardware/audio/effect/AutomaticGainControlV1.aidl",
+ "android/hardware/audio/effect/AutomaticGainControlV2.aidl",
"android/hardware/audio/effect/BassBoost.aidl",
"android/hardware/audio/effect/Capability.aidl",
"android/hardware/audio/effect/CommandId.aidl",
+ "android/hardware/audio/effect/DefaultExtension.aidl",
"android/hardware/audio/effect/Descriptor.aidl",
"android/hardware/audio/effect/Downmix.aidl",
"android/hardware/audio/effect/DynamicsProcessing.aidl",
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 6a545c1..3e06595 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -13,9 +13,6 @@
"name": "VtsHalDownmixTargetTest"
},
{
- "name": "VtsHalDynamicsProcessingTargetTest"
- },
- {
"name": "VtsHalEnvironmentalReverbTargetTest"
},
{
@@ -43,7 +40,10 @@
"name": "VtsHalAECTargetTest"
},
{
- "name": "VtsHalAGCTargetTest"
+ "name": "VtsHalAGC1TargetTest"
+ },
+ {
+ "name": "VtsHalAGC2TargetTest"
},
{
"name": "VtsHalNSTargetTest"
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
index 45217e7..1eafdab 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl
@@ -58,7 +58,7 @@
void setMasterVolume(float volume);
boolean getMicMute();
void setMicMute(boolean mute);
- android.hardware.audio.core.MicrophoneInfo[] getMicrophones();
+ android.media.audio.common.MicrophoneInfo[] getMicrophones();
void updateAudioMode(android.media.audio.common.AudioMode mode);
void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
void updateScreenState(boolean isTurnedOn);
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
index 1041943..a01f877 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl
@@ -35,7 +35,7 @@
@VintfStability
interface IStreamIn {
android.hardware.audio.core.IStreamCommon getStreamCommon();
- android.hardware.audio.core.MicrophoneDynamicInfo[] getActiveMicrophones();
+ android.media.audio.common.MicrophoneDynamicInfo[] getActiveMicrophones();
android.hardware.audio.core.IStreamIn.MicrophoneDirection getMicrophoneDirection();
void setMicrophoneDirection(android.hardware.audio.core.IStreamIn.MicrophoneDirection direction);
float getMicrophoneFieldDimension();
@@ -43,7 +43,7 @@
void updateMetadata(in android.hardware.audio.common.SinkMetadata sinkMetadata);
float[] getHwGain();
void setHwGain(in float[] channelGains);
- const int MIC_FIELD_DIMENSION_WIDE_ANGLE = (-1);
+ const int MIC_FIELD_DIMENSION_WIDE_ANGLE = (-1) /* -1 */;
const int MIC_FIELD_DIMENSION_NO_ZOOM = 0;
const int MIC_FIELD_DIMENSION_MAX_ZOOM = 1;
const int HW_GAIN_MIN = 0;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
index 001d074..84d7aa1 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ITelephony.aidl
@@ -46,7 +46,7 @@
const int VOICE_VOLUME_MAX = 1;
@Backing(type="int") @VintfStability
enum TtyMode {
- UNSPECIFIED = (-1),
+ UNSPECIFIED = (-1) /* -1 */,
OFF = 0,
FULL = 1,
HCO = 2,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneInfo.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneInfo.aidl
deleted file mode 100644
index b77afe3..0000000
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneInfo.aidl
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneInfo {
- @utf8InCpp String id;
- android.media.audio.common.AudioDevice device;
- android.hardware.audio.core.MicrophoneInfo.Location location = android.hardware.audio.core.MicrophoneInfo.Location.UNKNOWN;
- int group = GROUP_UNKNOWN;
- int indexInTheGroup = INDEX_IN_THE_GROUP_UNKNOWN;
- @nullable android.hardware.audio.core.MicrophoneInfo.Sensitivity sensitivity;
- android.hardware.audio.core.MicrophoneInfo.Directionality directionality = android.hardware.audio.core.MicrophoneInfo.Directionality.UNKNOWN;
- android.hardware.audio.core.MicrophoneInfo.FrequencyResponsePoint[] frequencyResponse;
- @nullable android.hardware.audio.core.MicrophoneInfo.Coordinate position;
- @nullable android.hardware.audio.core.MicrophoneInfo.Coordinate orientation;
- const int GROUP_UNKNOWN = (-1);
- const int INDEX_IN_THE_GROUP_UNKNOWN = (-1);
- @Backing(type="int") @VintfStability
- enum Location {
- UNKNOWN = 0,
- MAINBODY = 1,
- MAINBODY_MOVABLE = 2,
- PERIPHERAL = 3,
- }
- @VintfStability
- parcelable Sensitivity {
- float leveldBFS;
- float maxSpldB;
- float minSpldB;
- }
- @Backing(type="int") @VintfStability
- enum Directionality {
- UNKNOWN = 0,
- OMNI = 1,
- BI_DIRECTIONAL = 2,
- CARDIOID = 3,
- HYPER_CARDIOID = 4,
- SUPER_CARDIOID = 5,
- }
- @VintfStability
- parcelable FrequencyResponsePoint {
- float frequencyHz;
- float leveldB;
- }
- @VintfStability
- parcelable Coordinate {
- float x;
- float y;
- float z;
- }
-}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
index a65d7b7..3e3dc38 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/StreamDescriptor.aidl
@@ -39,12 +39,12 @@
int frameSizeBytes;
long bufferSizeFrames;
android.hardware.audio.core.StreamDescriptor.AudioBuffer audio;
- const int LATENCY_UNKNOWN = (-1);
+ const int LATENCY_UNKNOWN = (-1) /* -1 */;
@FixedSize @VintfStability
parcelable Position {
- long frames = UNKNOWN;
- long timeNs = UNKNOWN;
- const long UNKNOWN = (-1);
+ long frames = UNKNOWN /* -1 */;
+ long timeNs = UNKNOWN /* -1 */;
+ const long UNKNOWN = (-1) /* -1 */;
}
@Backing(type="int") @VintfStability
enum State {
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
index 1d51ade..1ec7dad 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -42,10 +42,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.AcousticEchoCanceler.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- int maxEchoDelayUs;
- boolean supportMobileMode;
- }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
index ff010c6..57d4418 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -43,9 +43,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.AutomaticGainControlV1.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- android.hardware.audio.effect.Range[] ranges;
- }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControl.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
similarity index 85%
rename from audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControl.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
index 39068d5..bdb481c 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControl.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -33,21 +33,15 @@
package android.hardware.audio.effect;
@VintfStability
-union AutomaticGainControl {
+union AutomaticGainControlV2 {
android.hardware.audio.effect.VendorExtension vendor;
int fixedDigitalGainMb;
- android.hardware.audio.effect.AutomaticGainControl.LevelEstimator levelEstimator;
+ android.hardware.audio.effect.AutomaticGainControlV2.LevelEstimator levelEstimator;
int saturationMarginMb;
@VintfStability
union Id {
int vendorExtensionTag;
- android.hardware.audio.effect.AutomaticGainControl.Tag commonTag;
- }
- @VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- int maxFixedDigitalGainMb;
- int maxSaturationMarginMb;
+ android.hardware.audio.effect.AutomaticGainControlV2.Tag commonTag;
}
@Backing(type="int") @VintfStability
enum LevelEstimator {
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
index f8baa2a..d09fe54 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/BassBoost.aidl
@@ -41,10 +41,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.BassBoost.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- int maxStrengthPm;
- boolean strengthSupported;
- }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
index 28f77b3..c9df073 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Capability.aidl
@@ -33,20 +33,7 @@
package android.hardware.audio.effect;
@VintfStability
-union Capability {
+parcelable Capability {
android.hardware.audio.effect.VendorExtension vendorExtension;
- android.hardware.audio.effect.AcousticEchoCanceler.Capability acousticEchoCanceler;
- android.hardware.audio.effect.AutomaticGainControl.Capability automaticGainControl;
- android.hardware.audio.effect.BassBoost.Capability bassBoost;
- android.hardware.audio.effect.Downmix.Capability downmix;
- android.hardware.audio.effect.DynamicsProcessing.Capability dynamicsProcessing;
- android.hardware.audio.effect.EnvironmentalReverb.Capability environmentalReverb;
- android.hardware.audio.effect.Equalizer.Capability equalizer;
- android.hardware.audio.effect.HapticGenerator.Capability hapticGenerator;
- android.hardware.audio.effect.LoudnessEnhancer.Capability loudnessEnhancer;
- android.hardware.audio.effect.NoiseSuppression.Capability noiseSuppression;
- android.hardware.audio.effect.PresetReverb.Capability presetReverb;
- android.hardware.audio.effect.Virtualizer.Capability virtualizer;
- android.hardware.audio.effect.Visualizer.Capability visualizer;
- android.hardware.audio.effect.Volume.Capability volume;
+ android.hardware.audio.effect.Range range;
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
similarity index 79%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
index 50a5528..f1cf389 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DefaultExtension.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -31,15 +31,8 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.audio.effect;
+@VintfStability
+parcelable DefaultExtension {
+ byte[] bytes;
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
index 990d369..0baac3d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Descriptor.aidl
@@ -41,7 +41,8 @@
const String EFFECT_TYPE_UUID_EQUALIZER = "0bed4300-ddd6-11db-8f34-0002a5d5c51b";
const String EFFECT_TYPE_UUID_BASS_BOOST = "0634f220-ddd4-11db-a0fc-0002a5d5c51b";
const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
- const String EFFECT_TYPE_UUID_AGC = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+ const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+ const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
const String EFFECT_TYPE_UUID_AEC = "7b491460-8d4d-11e0-bd61-0002a5d5c51b";
const String EFFECT_TYPE_UUID_NS = "58b4b260-8e06-11e0-aa8e-0002a5d5c51b";
const String EFFECT_TYPE_UUID_LOUDNESS_ENHANCER = "fe3199be-aed0-413f-87bb-11260eb63cf1";
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
index 402441d..45a1f28 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Downmix.aidl
@@ -42,10 +42,6 @@
android.hardware.audio.effect.Downmix.Tag commonTag;
}
@VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- }
- @VintfStability
enum Type {
STRIP,
FOLD,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
index 8e5b719..3e20e33 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -49,12 +49,6 @@
int vendorExtensionTag;
android.hardware.audio.effect.DynamicsProcessing.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- float minCutOffFreq;
- float maxCutOffFreq;
- }
enum ResolutionPreference {
FAVOR_FREQUENCY_RESOLUTION,
FAVOR_TIME_RESOLUTION,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
index 9edad09..c12ebb8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -39,6 +39,8 @@
int roomHfLevelMb;
int decayTimeMs;
int decayHfRatioPm;
+ int reflectionsLevelMb;
+ int reflectionsDelayMs;
int levelMb;
int delayMs;
int diffusionPm;
@@ -49,20 +51,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.EnvironmentalReverb.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- int minRoomLevelMb;
- int maxRoomLevelMb;
- int minRoomHfLevelMb;
- int maxRoomHfLevelMb;
- int maxDecayTimeMs;
- int minDecayHfRatioPm;
- int maxDecayHfRatioPm;
- int minLevelMb;
- int maxLevelMb;
- int maxDelayMs;
- int maxDiffusionPm;
- int maxDensityPm;
- }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
index d825eac..3e3539f 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Equalizer.aidl
@@ -37,18 +37,15 @@
android.hardware.audio.effect.VendorExtension vendorExtension;
android.hardware.audio.effect.Equalizer.BandLevel[] bandLevels;
int preset;
+ int[] centerFreqMh;
+ android.hardware.audio.effect.Equalizer.BandFrequency[] bandFrequencies;
+ android.hardware.audio.effect.Equalizer.Preset[] presets;
@VintfStability
union Id {
int vendorExtensionTag;
android.hardware.audio.effect.Equalizer.Tag commonTag;
}
@VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- android.hardware.audio.effect.Equalizer.BandFrequency[] bandFrequencies;
- android.hardware.audio.effect.Equalizer.Preset[] presets;
- }
- @VintfStability
parcelable BandLevel {
int index;
int levelMb;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
index 285ff18..bcbf870 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
@@ -42,7 +42,7 @@
boolean deviceIndication;
boolean audioModeIndication;
boolean audioSourceIndication;
- boolean noProcessing;
+ boolean bypass;
@Backing(type="byte") @VintfStability
enum Type {
INSERT = 0,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
index 20f7e02..a7dc265 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
@@ -42,15 +42,11 @@
int vendorExtensionTag;
android.hardware.audio.effect.HapticGenerator.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- }
@Backing(type="int") @VintfStability
enum VibratorScale {
- MUTE = (-100),
- VERY_LOW = (-2),
- LOW = (-1),
+ MUTE = (-100) /* -100 */,
+ VERY_LOW = (-2) /* -2 */,
+ LOW = (-1) /* -1 */,
NONE = 0,
HIGH = 1,
VERY_HIGH = 2,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
index 5c6ca16..774f45f 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -41,8 +41,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.LoudnessEnhancer.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
index 1cf92ef..f1a3449 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -36,15 +36,12 @@
union NoiseSuppression {
android.hardware.audio.effect.VendorExtension vendor;
android.hardware.audio.effect.NoiseSuppression.Level level;
+ android.hardware.audio.effect.NoiseSuppression.Type type;
@VintfStability
union Id {
int vendorExtensionTag;
android.hardware.audio.effect.NoiseSuppression.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- ParcelableHolder extension;
- }
@Backing(type="int") @VintfStability
enum Level {
LOW,
@@ -52,4 +49,9 @@
HIGH,
VERY_HIGH,
}
+ @Backing(type="int") @VintfStability
+ enum Type {
+ SINGLE_CHANNEL,
+ MULTI_CHANNEL,
+ }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index 3ba44a0..14aa1e8 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -44,7 +44,8 @@
union Id {
int vendorEffectTag;
android.hardware.audio.effect.AcousticEchoCanceler.Id acousticEchoCancelerTag;
- android.hardware.audio.effect.AutomaticGainControl.Id automaticGainControlTag;
+ android.hardware.audio.effect.AutomaticGainControlV1.Id automaticGainControlV1Tag;
+ android.hardware.audio.effect.AutomaticGainControlV2.Id automaticGainControlV2Tag;
android.hardware.audio.effect.BassBoost.Id bassBoostTag;
android.hardware.audio.effect.Downmix.Id downmixTag;
android.hardware.audio.effect.DynamicsProcessing.Id dynamicsProcessingTag;
@@ -75,7 +76,8 @@
union Specific {
android.hardware.audio.effect.VendorExtension vendorEffect;
android.hardware.audio.effect.AcousticEchoCanceler acousticEchoCanceler;
- android.hardware.audio.effect.AutomaticGainControl automaticGainControl;
+ android.hardware.audio.effect.AutomaticGainControlV1 automaticGainControlV1;
+ android.hardware.audio.effect.AutomaticGainControlV2 automaticGainControlV2;
android.hardware.audio.effect.BassBoost bassBoost;
android.hardware.audio.effect.Downmix downmix;
android.hardware.audio.effect.DynamicsProcessing dynamicsProcessing;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
index 4651742..148f79d 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/PresetReverb.aidl
@@ -35,6 +35,7 @@
@VintfStability
union PresetReverb {
android.hardware.audio.effect.VendorExtension vendor;
+ android.hardware.audio.effect.PresetReverb.Presets[] supportedPresets;
android.hardware.audio.effect.PresetReverb.Presets preset;
@Backing(type="int") @VintfStability
enum Presets {
@@ -51,9 +52,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.PresetReverb.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- android.hardware.audio.effect.PresetReverb.Presets[] supportedPresets;
- }
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
index 531d3a1..93edc5e 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Range.aidl
@@ -33,34 +33,101 @@
package android.hardware.audio.effect;
@VintfStability
-parcelable Range {
- int tag;
- android.hardware.audio.effect.Range.Types types;
+union Range {
+ android.hardware.audio.effect.Range.VendorExtensionRange[] vendorExtension = {};
+ android.hardware.audio.effect.Range.AcousticEchoCancelerRange[] acousticEchoCanceler;
+ android.hardware.audio.effect.Range.AutomaticGainControlV1Range[] automaticGainControlV1;
+ android.hardware.audio.effect.Range.AutomaticGainControlV2Range[] automaticGainControlV2;
+ android.hardware.audio.effect.Range.BassBoostRange[] bassBoost;
+ android.hardware.audio.effect.Range.DownmixRange[] downmix;
+ android.hardware.audio.effect.Range.DynamicsProcessingRange[] dynamicsProcessing;
+ android.hardware.audio.effect.Range.EnvironmentalReverbRange[] environmentalReverb;
+ android.hardware.audio.effect.Range.EqualizerRange[] equalizer;
+ android.hardware.audio.effect.Range.HapticGeneratorRange[] hapticGenerator;
+ android.hardware.audio.effect.Range.LoudnessEnhancerRange[] loudnessEnhancer;
+ android.hardware.audio.effect.Range.NoiseSuppressionRange[] noiseSuppression;
+ android.hardware.audio.effect.Range.PresetReverbRange[] presetReverb;
+ android.hardware.audio.effect.Range.VirtualizerRange[] virtualizer;
+ android.hardware.audio.effect.Range.VisualizerRange[] visualizer;
+ android.hardware.audio.effect.Range.VolumeRange[] volume;
@VintfStability
- parcelable Int {
- int min;
- int max;
+ parcelable AcousticEchoCancelerRange {
+ android.hardware.audio.effect.AcousticEchoCanceler min;
+ android.hardware.audio.effect.AcousticEchoCanceler max;
}
@VintfStability
- parcelable Float {
- float min;
- float max;
+ parcelable AutomaticGainControlV1Range {
+ android.hardware.audio.effect.AutomaticGainControlV1 min;
+ android.hardware.audio.effect.AutomaticGainControlV1 max;
}
@VintfStability
- parcelable Long {
- long min;
- long max;
+ parcelable AutomaticGainControlV2Range {
+ android.hardware.audio.effect.AutomaticGainControlV2 min;
+ android.hardware.audio.effect.AutomaticGainControlV2 max;
}
@VintfStability
- parcelable Byte {
- byte min;
- byte max;
+ parcelable BassBoostRange {
+ android.hardware.audio.effect.BassBoost min;
+ android.hardware.audio.effect.BassBoost max;
}
@VintfStability
- union Types {
- android.hardware.audio.effect.Range.Int rangeInt;
- android.hardware.audio.effect.Range.Float rangeFloat;
- android.hardware.audio.effect.Range.Long rangeLong;
- android.hardware.audio.effect.Range.Byte rangeByte;
+ parcelable DownmixRange {
+ android.hardware.audio.effect.Downmix min;
+ android.hardware.audio.effect.Downmix max;
+ }
+ @VintfStability
+ parcelable DynamicsProcessingRange {
+ android.hardware.audio.effect.DynamicsProcessing min;
+ android.hardware.audio.effect.DynamicsProcessing max;
+ }
+ @VintfStability
+ parcelable EnvironmentalReverbRange {
+ android.hardware.audio.effect.EnvironmentalReverb min;
+ android.hardware.audio.effect.EnvironmentalReverb max;
+ }
+ @VintfStability
+ parcelable EqualizerRange {
+ android.hardware.audio.effect.Equalizer min;
+ android.hardware.audio.effect.Equalizer max;
+ }
+ @VintfStability
+ parcelable HapticGeneratorRange {
+ android.hardware.audio.effect.HapticGenerator min;
+ android.hardware.audio.effect.HapticGenerator max;
+ }
+ @VintfStability
+ parcelable LoudnessEnhancerRange {
+ android.hardware.audio.effect.LoudnessEnhancer min;
+ android.hardware.audio.effect.LoudnessEnhancer max;
+ }
+ @VintfStability
+ parcelable NoiseSuppressionRange {
+ android.hardware.audio.effect.NoiseSuppression min;
+ android.hardware.audio.effect.NoiseSuppression max;
+ }
+ @VintfStability
+ parcelable PresetReverbRange {
+ android.hardware.audio.effect.PresetReverb min;
+ android.hardware.audio.effect.PresetReverb max;
+ }
+ @VintfStability
+ parcelable VendorExtensionRange {
+ android.hardware.audio.effect.VendorExtension min;
+ android.hardware.audio.effect.VendorExtension max;
+ }
+ @VintfStability
+ parcelable VirtualizerRange {
+ android.hardware.audio.effect.Virtualizer min;
+ android.hardware.audio.effect.Virtualizer max;
+ }
+ @VintfStability
+ parcelable VisualizerRange {
+ android.hardware.audio.effect.Visualizer min;
+ android.hardware.audio.effect.Visualizer max;
+ }
+ @VintfStability
+ parcelable VolumeRange {
+ android.hardware.audio.effect.Volume min;
+ android.hardware.audio.effect.Volume max;
}
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
index 9fdd692..e9611e4 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Virtualizer.aidl
@@ -36,15 +36,23 @@
union Virtualizer {
android.hardware.audio.effect.VendorExtension vendor;
int strengthPm;
+ android.hardware.audio.effect.Virtualizer.ChannelAngle[] speakerAngles;
+ android.media.audio.common.AudioDeviceDescription device;
@VintfStability
union Id {
int vendorExtensionTag;
android.hardware.audio.effect.Virtualizer.Tag commonTag;
+ android.hardware.audio.effect.Virtualizer.SpeakerAnglesPayload speakerAnglesPayload;
}
@VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- int maxStrengthPm;
- boolean strengthSupported;
+ parcelable SpeakerAnglesPayload {
+ android.media.audio.common.AudioChannelLayout layout;
+ android.media.audio.common.AudioDeviceDescription device;
+ }
+ @VintfStability
+ parcelable ChannelAngle {
+ int channel;
+ int azimuthDegree;
+ int elevationDegree;
}
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
index c8cb551..d1b1b3e 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Visualizer.aidl
@@ -36,30 +36,18 @@
union Visualizer {
android.hardware.audio.effect.Visualizer.Id id;
android.hardware.audio.effect.VendorExtension vendor;
- android.hardware.audio.effect.Visualizer.GetOnlyParameters getOnlyParameters;
- android.hardware.audio.effect.Visualizer.SetOnlyParameters setOnlyParameters;
+ android.hardware.audio.effect.Visualizer.Measurement measurement;
+ byte[] captureSampleBuffer;
+ int latencyMs;
int captureSamples;
android.hardware.audio.effect.Visualizer.ScalingMode scalingMode;
android.hardware.audio.effect.Visualizer.MeasurementMode measurementMode;
@VintfStability
union Id {
int vendorExtensionTag;
- android.hardware.audio.effect.Visualizer.GetOnlyParameters.Tag getOnlyParamTag;
- android.hardware.audio.effect.Visualizer.SetOnlyParameters.Tag setOnlyParamTag;
android.hardware.audio.effect.Visualizer.Tag commonTag;
}
@VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- int maxLatencyMs;
- android.hardware.audio.effect.Visualizer.CaptureSamplesRange captureSampleRange;
- }
- @VintfStability
- parcelable CaptureSamplesRange {
- int min;
- int max;
- }
- @VintfStability
enum ScalingMode {
NORMALIZED = 0,
AS_PLAYED,
@@ -70,17 +58,8 @@
PEAK_RMS,
}
@VintfStability
- union GetOnlyParameters {
- android.hardware.audio.effect.Visualizer.GetOnlyParameters.Measurement measurement;
- byte[] captureSampleBuffer;
- @VintfStability
- parcelable Measurement {
- int rms;
- int peak;
- }
- }
- @VintfStability
- union SetOnlyParameters {
- int latencyMs;
+ parcelable Measurement {
+ int rms;
+ int peak;
}
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
index 6259cfb..c2b2df7 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Volume.aidl
@@ -42,10 +42,4 @@
int vendorExtensionTag;
android.hardware.audio.effect.Volume.Tag commonTag;
}
- @VintfStability
- parcelable Capability {
- android.hardware.audio.effect.VendorExtension extension;
- int minLevelDb;
- int maxLevelDb;
- }
}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 968b573..edfb9f2 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -26,7 +26,6 @@
import android.hardware.audio.core.IStreamOut;
import android.hardware.audio.core.IStreamOutEventCallback;
import android.hardware.audio.core.ITelephony;
-import android.hardware.audio.core.MicrophoneInfo;
import android.hardware.audio.core.ModuleDebug;
import android.hardware.audio.core.StreamDescriptor;
import android.hardware.audio.core.VendorParameter;
@@ -39,6 +38,7 @@
import android.media.audio.common.AudioPort;
import android.media.audio.common.AudioPortConfig;
import android.media.audio.common.Float;
+import android.media.audio.common.MicrophoneInfo;
/**
* Each instance of IModule corresponds to a separate audio module. The system
diff --git a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
index c2b3633..93cad11 100644
--- a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
+++ b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl
@@ -18,7 +18,7 @@
import android.hardware.audio.common.SinkMetadata;
import android.hardware.audio.core.IStreamCommon;
-import android.hardware.audio.core.MicrophoneDynamicInfo;
+import android.media.audio.common.MicrophoneDynamicInfo;
/**
* This interface provides means for receiving audio data from input devices.
diff --git a/audio/aidl/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/audio/aidl/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
deleted file mode 100644
index 36cc51f..0000000
--- a/audio/aidl/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.audio.core;
-
-/**
- * Structure providing dynamic information on a microphone. This information
- * changes between recording sessions.
- */
-@JavaDerive(equals=true, toString=true)
-@VintfStability
-parcelable MicrophoneDynamicInfo {
- /**
- * Unique alphanumeric id for the microphone. It must match the id of one of
- * the 'MicrophoneInfo' entries returned by 'IModule.getMicrophones'.
- */
- @utf8InCpp String id;
-
- @VintfStability
- @Backing(type="int")
- enum ChannelMapping {
- /** Channel not used. */
- UNUSED = 0,
- /** Channel is used and the signal is not processed. */
- DIRECT = 1,
- /** Channel is used and the signal has some processing. */
- PROCESSED = 2,
- }
- /**
- * The vector is indexes by zero-based channels of the microphone, thus the
- * element '0' corresponds to the first channel, '1' is the second, etc. The
- * vector must contain at least 1 element.
- */
- ChannelMapping[] channelMapping;
-}
diff --git a/audio/aidl/android/hardware/audio/core/MicrophoneInfo.aidl b/audio/aidl/android/hardware/audio/core/MicrophoneInfo.aidl
deleted file mode 100644
index 3b8c7f3..0000000
--- a/audio/aidl/android/hardware/audio/core/MicrophoneInfo.aidl
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.audio.core;
-
-import android.media.audio.common.AudioDevice;
-
-/**
- * Structure providing static information on a microphone. This information
- * never changes during the lifetime of the IModule which owns the microphone.
- * The information presented in this structure indicates the location and
- * orientation of the microphone on the device as well as useful information
- * like frequency response and sensitivity.
- */
-@JavaDerive(equals=true, toString=true)
-@VintfStability
-parcelable MicrophoneInfo {
- /**
- * Unique alphanumeric id for the microphone. It must remain the same across
- * device reboots. The client must never attempt to parse the value of this
- * field.
- */
- @utf8InCpp String id;
- /**
- * Describes the location of the microphone in terms of managed audio devices.
- */
- AudioDevice device;
-
- @VintfStability
- @Backing(type="int")
- enum Location {
- /** Microphone location is unknown. */
- UNKNOWN = 0,
- /** The microphone is located on the main body of the device. */
- MAINBODY = 1,
- /** The microphone is located on a movable main body of the device. */
- MAINBODY_MOVABLE = 2,
- /** The microphone is located on a peripheral. */
- PERIPHERAL = 3,
- }
- /** Location of the microphone in regard to the body of the device */
- Location location = Location.UNKNOWN;
-
- /**
- * This value is used when the group of the microphone is unknown.
- */
- const int GROUP_UNKNOWN = -1;
- /**
- * An identifier to group related microphones together, for example,
- * microphones of a microphone array should all belong to the same group.
- * Note that microphones assigned to 'GROUP_UNKNOWN' do not form a group.
- */
- int group = GROUP_UNKNOWN;
- /**
- * This value is used when the index in the group of the microphone is
- * unknown.
- */
- const int INDEX_IN_THE_GROUP_UNKNOWN = -1;
- /**
- * Index of this microphone within the group. The pair (group, index) must
- * be unique within the same HAL module, except the pair
- * (GROUP_UNKNOWN, INDEX_IN_THE_GROUP_UNKNOWN).
- */
- int indexInTheGroup = INDEX_IN_THE_GROUP_UNKNOWN;
-
- @VintfStability
- parcelable Sensitivity {
- /** Level in dBFS produced by a 1000 Hz tone at 94 dB SPL. */
- float leveldBFS;
- /** Level in dB of the max SPL supported at 1000 Hz */
- float maxSpldB;
- /** Level in dB of the min SPL supported at 1000 Hz */
- float minSpldB;
- }
- /**
- * If provided, must describe acceptable sound pressure levels (SPL)
- * for a 1 kHz sine wave, and the resulting level in dBFS.
- */
- @nullable Sensitivity sensitivity;
-
- @VintfStability
- @Backing(type="int")
- enum Directionality {
- UNKNOWN = 0,
- OMNI = 1,
- BI_DIRECTIONAL = 2,
- CARDIOID = 3,
- HYPER_CARDIOID = 4,
- SUPER_CARDIOID = 5,
- }
- /**
- * The standard polar pattern of the microphone.
- */
- Directionality directionality = Directionality.UNKNOWN;
-
- /**
- * A (frequency, level) pair. Used to represent frequency response.
- */
- @VintfStability
- parcelable FrequencyResponsePoint {
- float frequencyHz;
- float leveldB;
- }
- /**
- * Vector with ordered frequency responses (from low to high frequencies)
- * with the frequency response of the microphone. Levels are in dB,
- * relative to level at 1000 Hz.
- */
- FrequencyResponsePoint[] frequencyResponse;
-
- /**
- * A 3D point used to represent position or orientation of a microphone.
- */
- @VintfStability
- parcelable Coordinate {
- float x;
- float y;
- float z;
- }
- /**
- * If provided, must specify distances of the microphone's capsule, in
- * meters, from the bottom-left-back corner of the bounding box of device in
- * its natural orientation (PORTRAIT for phones, LANDSCAPE for tablets, TVs,
- * etc).
- */
- @nullable Coordinate position;
- /**
- * If provided, describes the normalized point which defines the main
- * orientation of the microphone's capsule.
- * Magnitude = sqrt(x^2 + y^2 + z^2) = 1.
- */
- @nullable Coordinate orientation;
-}
diff --git a/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl b/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
index 19d60b6..49377d6 100644
--- a/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
+++ b/audio/aidl/android/hardware/audio/effect/AcousticEchoCanceler.aidl
@@ -22,9 +22,9 @@
* Acoustic Echo Canceler (AEC) is an audio pre-processor which removes the contribution of the
* signal received from the remote party from the captured audio signal.
*
- * All parameters defined in union AcousticEchoCanceler must be gettable and settable. The
- * capabilities defined in AcousticEchoCanceler.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.acousticEchoCanceler
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
*/
@VintfStability
union AcousticEchoCanceler {
@@ -43,35 +43,20 @@
VendorExtension vendor;
/**
- * Capability supported by AEC implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * AEC capability extension, vendor can use this extension in case existing capability
- * definition not enough.
- */
- ParcelableHolder extension;
-
- /**
- * Maximum AEC echo delay in microseconds supported.
- */
- int maxEchoDelayUs;
- /**
- * If AEC mobile mode was supported by the AEC implementation.
- */
- boolean supportMobileMode;
- }
-
- /**
* The AEC echo delay in microseconds.
- * Must never be negative, and not larger than maxEchoDelayUs in capability.
*/
int echoDelayUs;
/**
- * If AEC mobile mode enabled.
- * Can only be false if AEC implementation indicate not support mobile mode by set
- * supportMobileMode to false in capability.
+ * Indicate if the AEC mobile mode is enabled or not.
+ * If an effect implementation supports enabling and disabling mobileMode at runtime, it does
+ * not need to set the min and max range for mobileMode, or report the mobileMode min/max range
+ * as [false, true] in Range.AcousticEchoCancelerRange. If the effect implementation doesn't
+ * support mobileMode, it must report the mobileMode range as [false, false]. If the effect
+ * implementation supports mobileMode and cannot be disabled, it must report the mobileMode
+ * range as [true, true].
+ * If the effect implementation sets the range as invalid: [true, false], it indicates that
+ * mobileMode setParameter is not supported, and clients can only use getParameter to check if
+ * it's enabled or not.
*/
boolean mobileMode;
}
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControl.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControl.aidl
deleted file mode 100644
index e82a564..0000000
--- a/audio/aidl/android/hardware/audio/effect/AutomaticGainControl.aidl
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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.audio.effect;
-
-import android.hardware.audio.effect.VendorExtension;
-
-/**
- * Automatic Gain Control (AGC) is an audio pre-processor which automatically normalizes the output
- * of the captured signal by boosting or lowering input from the microphone to match a preset level
- * so that the output signal level is virtually constant. AGC can be used by applications where the
- * input signal dynamic range is not important but where a constant strong capture level is desired.
- *
- * All parameters defined in union AutomaticGainControl must be gettable and settable. The
- * capabilities defined in AutomaticGainControl.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
- */
-@VintfStability
-union AutomaticGainControl {
- /**
- * Effect parameter tag to identify the parameters for getParameter().
- */
- @VintfStability
- union Id {
- int vendorExtensionTag;
- AutomaticGainControl.Tag commonTag;
- }
-
- /**
- * Vendor AutomaticGainControl implementation definition for additional parameters.
- */
- VendorExtension vendor;
-
- /**
- * Capability supported by AutomaticGainControl implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * AutomaticGainControl capability extension, vendor can use this extension in case existing
- * capability definition not enough.
- */
- ParcelableHolder extension;
- /**
- * Max fixed digital gain supported by AGC implementation in millibel.
- */
- int maxFixedDigitalGainMb;
- /**
- * Max fixed saturation margin supported by AGC implementation in millibel.
- */
- int maxSaturationMarginMb;
- }
-
- @VintfStability
- @Backing(type="int")
- enum LevelEstimator {
- /* Use Root Mean Square level estimator*/
- RMS = 0,
- /* Use Peak level estimator*/
- PEAK = 1,
- }
-
- /**
- * The AGC fixed digital gain in millibel.
- * Must never be negative, and not larger than maxFixedDigitalGainMb in capability.
- */
- int fixedDigitalGainMb;
- /*
- * Adaptive digital level estimator.
- */
- LevelEstimator levelEstimator;
- /**
- * The AGC saturation margin in millibel.
- * Must never be negative, and not larger than maxSaturationMarginMb in capability.
- */
- int saturationMarginMb;
-}
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
index d6e0648..9b2feff 100644
--- a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
+++ b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV1.aidl
@@ -16,7 +16,6 @@
package android.hardware.audio.effect;
-import android.hardware.audio.effect.Range;
import android.hardware.audio.effect.VendorExtension;
/**
@@ -25,9 +24,9 @@
* so that the output signal level is virtually constant. AGC can be used by applications where the
* input signal dynamic range is not important but where a constant strong capture level is desired.
*
- * All parameters defined in union AutomaticGainControlV1 must be gettable and settable. The
- * capabilities defined in AutomaticGainControlV1.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.automaticGainControlV1
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
*/
@VintfStability
union AutomaticGainControlV1 {
@@ -46,31 +45,13 @@
VendorExtension vendor;
/**
- * Capability supported by AutomaticGainControlV1 implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * AutomaticGainControlV1 capability extension, vendor can use this extension in case
- * existing capability definition not enough.
- */
- ParcelableHolder extension;
- /**
- * Supported range for parameters.
- */
- Range[] ranges;
- }
-
- /**
* Target peak level (or envelope) of the AGC implementation in dBFs (dB relative to full
* scale).
- * Must be in range of AutomaticGainControlV1.Capability.ranges with targetPeakLevelDbFs tag.
*/
int targetPeakLevelDbFs;
/*
* Sets the maximum gain the digital compression stage may apply, in dB. A higher number
* corresponds to greater compression, while a value of 0 will leave the signal uncompressed.
- * Must be in range of AutomaticGainControlV1.Capability.ranges with maxCompressionGainDb tag.
*/
int maxCompressionGainDb;
/**
diff --git a/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl
new file mode 100644
index 0000000..836d6b8
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/AutomaticGainControlV2.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.audio.effect;
+
+import android.hardware.audio.effect.VendorExtension;
+
+/**
+ * Automatic Gain Control V2 (AGC2) is an audio pre-processor which automatically normalizes the
+ * output of the captured signal by boosting or lowering input from the microphone to match a preset
+ * level so that the output signal level is virtually constant. AGC can be used by applications
+ * where the input signal dynamic range is not important but where a constant strong capture level
+ * is desired.
+ *
+ * All parameter settings must be inside the range of Capability.Range.automaticGainControlV2
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
+ */
+@VintfStability
+union AutomaticGainControlV2 {
+ /**
+ * Effect parameter tag to identify the parameters for getParameter().
+ */
+ @VintfStability
+ union Id {
+ int vendorExtensionTag;
+ AutomaticGainControlV2.Tag commonTag;
+ }
+
+ /**
+ * Vendor AutomaticGainControlV2 implementation definition for additional parameters.
+ */
+ VendorExtension vendor;
+
+ @VintfStability
+ @Backing(type="int")
+ enum LevelEstimator {
+ /* Use Root Mean Square level estimator*/
+ RMS = 0,
+ /* Use Peak level estimator*/
+ PEAK = 1,
+ }
+
+ /**
+ * The AGC fixed digital gain in millibel.
+ */
+ int fixedDigitalGainMb;
+ /*
+ * Adaptive digital level estimator.
+ */
+ LevelEstimator levelEstimator;
+ /**
+ * The AGC saturation margin in millibel.
+ */
+ int saturationMarginMb;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
index 6a94242..d734825 100644
--- a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
@@ -22,8 +22,8 @@
* Bass boost is an audio effect to boost or amplify low frequencies of the sound. It is comparable
* to a simple equalizer but limited to one band amplification in the low frequency range.
*
- * All parameters defined in union BassBoost must be gettable and settable. The capabilities defined
- * in BassBoost.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.bassBoost definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
*/
@VintfStability
union BassBoost {
@@ -42,35 +42,11 @@
VendorExtension vendor;
/**
- * Capability supported by BassBoost implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * BassBoost capability extension, vendor can use this extension in case existing capability
- * definition not enough.
- */
- ParcelableHolder extension;
- /**
- * Maximum possible per mille strength.
- */
- int maxStrengthPm;
- /**
- * Indicates whether setting strength is supported. False value indicates only one strength
- * is supported and setParameter() method will return EX_ILLEGAL_ARGUMENT.
- */
- boolean strengthSupported;
- }
-
- /**
* The per mille strength of the bass boost effect.
*
* If the implementation does not support per mille accuracy for setting the strength, it is
* allowed to round the given strength to the nearest supported value. In this case {@link
* #IEffect.getParameter()} method should return the rounded value that was actually set.
- *
- * The value of the strength must be non-negative and not exceed the value specified by
- * the 'maxStrengthPm' capability.
*/
int strengthPm;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Capability.aidl b/audio/aidl/android/hardware/audio/effect/Capability.aidl
index 30780e6..06c2024 100644
--- a/audio/aidl/android/hardware/audio/effect/Capability.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Capability.aidl
@@ -16,21 +16,8 @@
package android.hardware.audio.effect;
-import android.hardware.audio.effect.AcousticEchoCanceler;
-import android.hardware.audio.effect.AutomaticGainControl;
-import android.hardware.audio.effect.BassBoost;
-import android.hardware.audio.effect.Downmix;
-import android.hardware.audio.effect.DynamicsProcessing;
-import android.hardware.audio.effect.EnvironmentalReverb;
-import android.hardware.audio.effect.Equalizer;
-import android.hardware.audio.effect.HapticGenerator;
-import android.hardware.audio.effect.LoudnessEnhancer;
-import android.hardware.audio.effect.NoiseSuppression;
-import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.Range;
import android.hardware.audio.effect.VendorExtension;
-import android.hardware.audio.effect.Virtualizer;
-import android.hardware.audio.effect.Visualizer;
-import android.hardware.audio.effect.Volume;
/**
* Effect capability definitions.
@@ -38,32 +25,19 @@
* not meant to change at runtime.
*/
@VintfStability
-union Capability {
+parcelable Capability {
/**
* Vendor defined effect capability.
- * This extension can be used when vendor have a new effect implementated and need
+ * This extension can be used when vendor has a new effect implementation and needs
* capability definition for this new type of effect.
- * If vendor want to extend existing effect capabilities, it is recommended to expose though
- * the ParcelableHolder in each effect capability definition. For example:
- * Equalizer.Capability.extension.
+ * If vendor want to extend existing effect capabilities, it is recommended to expose through
+ * the ParcelableHolder in each effect definition. For example: Equalizer.vendorExtension. And
+ * define an appropriate Range for the extension.
*/
VendorExtension vendorExtension;
/**
- * Effect capabilities.
+ * Supported range for parameters. See Range.aidl.
*/
- AcousticEchoCanceler.Capability acousticEchoCanceler;
- AutomaticGainControl.Capability automaticGainControl;
- BassBoost.Capability bassBoost;
- Downmix.Capability downmix;
- DynamicsProcessing.Capability dynamicsProcessing;
- EnvironmentalReverb.Capability environmentalReverb;
- Equalizer.Capability equalizer;
- HapticGenerator.Capability hapticGenerator;
- LoudnessEnhancer.Capability loudnessEnhancer;
- NoiseSuppression.Capability noiseSuppression;
- PresetReverb.Capability presetReverb;
- Virtualizer.Capability virtualizer;
- Visualizer.Capability visualizer;
- Volume.Capability volume;
+ Range range;
}
diff --git a/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl b/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl
new file mode 100644
index 0000000..33e827f
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/effect/DefaultExtension.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.audio.effect;
+
+/**
+ * The default extension used for Parameter.Specific.vendorEffect ParcelableHolder.
+ *
+ * The audio framework attach this default extension to the ParcelableHolder in VendorExtension,
+ * and pass though all parameters it received from the client to audio HAL.
+ *
+ * For now it's not possible for vendor to define their own vendor extensions without changing the
+ * audio framework. More specificly, in order to add a customized effect parameter AIDL parcelable,
+ * vendors need to add the logic for conversion between AIDL and effect_param_t for the effect AIDL
+ * in: frameworks/av/media/libaudiohal/impl/effectAidlConversion.
+ *
+ * There is no VTS test cases for the vendor extension effect implementation, however all effect
+ * implementations must support the common parameters defined in Parameter.aidl, so vendor
+ * extension effect implementation still need to support setting and getting of these common
+ * parameters, which is enforced by VTS.
+ */
+@VintfStability
+parcelable DefaultExtension {
+ byte[] bytes;
+}
diff --git a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
index 47c88dc..01ca1c6 100644
--- a/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Descriptor.aidl
@@ -57,9 +57,13 @@
*/
const String EFFECT_TYPE_UUID_VIRTUALIZER = "37cc2c00-dddd-11db-8577-0002a5d5c51b";
/**
- * UUID for Automatic Gain Control (AGC) type.
+ * UUID for Automatic Gain Control V1 (AGC1) type.
*/
- const String EFFECT_TYPE_UUID_AGC = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+ const String EFFECT_TYPE_UUID_AGC1 = "0a8abfe0-654c-11e0-ba26-0002a5d5c51b";
+ /**
+ * UUID for Automatic Gain Control V2 (AGC2) type.
+ */
+ const String EFFECT_TYPE_UUID_AGC2 = "ae3c653b-be18-4ab8-8938-418f0a7f06ac";
/**
* UUID for Acoustic Echo Canceler (AEC) type.
*/
diff --git a/audio/aidl/android/hardware/audio/effect/Downmix.aidl b/audio/aidl/android/hardware/audio/effect/Downmix.aidl
index ee57baf..f90e339 100644
--- a/audio/aidl/android/hardware/audio/effect/Downmix.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Downmix.aidl
@@ -21,8 +21,8 @@
/**
* Downmix specific definitions.
*
- * All parameters defined in union Downmix must be gettable and settable. The capabilities defined
- * in Downmix.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.downmix definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
*/
@VintfStability
union Downmix {
@@ -40,18 +40,6 @@
*/
VendorExtension vendor;
- /**
- * Capability supported by Downmix implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * Downmix capability extension, vendor can use this extension in case existing capability
- * definition not enough.
- */
- ParcelableHolder extension;
- }
-
@VintfStability
enum Type {
/**
diff --git a/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl b/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
index 6db3338..486d4f4 100644
--- a/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
+++ b/audio/aidl/android/hardware/audio/effect/DynamicsProcessing.aidl
@@ -21,9 +21,9 @@
/**
* DynamicsProcessing specific definitions.
*
- * All parameters defined in union DynamicsProcessing must be gettable and settable. The
- * capabilities defined in DynamicsProcessing.Capability can only acquired with
- * IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.dynamicsProcessing definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
*/
@VintfStability
union DynamicsProcessing {
@@ -42,26 +42,6 @@
VendorExtension vendorExtension;
/**
- * Capability supported by DynamicsProcessing implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * DynamicsProcessing capability extension, vendor can use this extension in case existing
- * capability definition not enough.
- */
- ParcelableHolder extension;
- /**
- * Min Cut off frequency (in Hz) for all Bands.
- */
- float minCutOffFreq;
- /**
- * Max Cut off frequency (in Hz) for all Bands.
- */
- float maxCutOffFreq;
- }
-
- /**
* Resolution preference definition.
*/
enum ResolutionPreference {
@@ -159,8 +139,7 @@
*/
boolean enable;
/**
- * Topmost frequency number (in Hz) this band will process. Must be in the range of
- * [minCutOffFreq, maxCutOffFreq] defined in Capability.
+ * Topmost frequency number (in Hz) this band will process.
*/
float cutoffFrequencyHz;
/**
@@ -190,8 +169,7 @@
*/
boolean enable;
/**
- * Topmost frequency number (in Hz) this band will process. Must be in the range of
- * [minCutOffFreq, maxCutOffFreq] defined in Capability.
+ * Topmost frequency number (in Hz) this band will process.
*/
float cutoffFrequencyHz;
/**
diff --git a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
index fc98fe6..95d1ff6 100644
--- a/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/EnvironmentalReverb.aidl
@@ -21,9 +21,9 @@
/**
* Environmental Reverb specific definitions.
*
- * All parameters defined in union Environmental must be gettable and settable. The capabilities
- * * defined in EnvironmentalReverb.Capability can only acquired with IEffect.getDescriptor() and
- * not * settable.
+ * All parameter settings must be inside the range of Capability.Range.environmentalReverb
+ * definition if the definition for the corresponding parameter tag exist. See more detals about
+ * Range in Range.aidl.
*/
@VintfStability
@@ -43,103 +43,43 @@
VendorExtension vendor;
/**
- * Capability supported by effect implementation.
- */
- @VintfStability
- parcelable Capability {
- VendorExtension extension;
-
- /**
- * Minimal possible room level in millibels.
- */
- int minRoomLevelMb;
- /**
- * Maximum possible room level in millibels.
- */
- int maxRoomLevelMb;
- /**
- * Minimal possible room hf level in millibels.
- */
- int minRoomHfLevelMb;
- /**
- * Maximum possible room hf level in millibels.
- */
- int maxRoomHfLevelMb;
- /**
- * Max decay time supported in millisecond.
- */
- int maxDecayTimeMs;
- /**
- * Minimal possible per mille decay hf ratio.
- */
- int minDecayHfRatioPm;
- /**
- * Maximum possible per mille decay hf ratio.
- */
- int maxDecayHfRatioPm;
- /**
- * Minimal possible room level in millibels.
- */
- int minLevelMb;
- /**
- * Maximum possible room level in millibels.
- */
- int maxLevelMb;
- /**
- * Maximum possible delay time in milliseconds.
- */
- int maxDelayMs;
- /**
- * Maximum possible per mille diffusion.
- */
- int maxDiffusionPm;
- /**
- * Maximum possible per mille density.
- */
- int maxDensityPm;
- }
-
- /**
- * Room level apply to the reverb effect in millibels. The value of the roomLevelMb must be in
- * range of the value specified by the 'minRoomLevelMb' capability and the 'maxRoomLevelMb'
- * capability.
+ * Room level apply to the reverb effect in millibels.
*/
int roomLevelMb;
/**
- * Room HF level apply to the reverb effect in millibels. The value of the roomHfLevelMb must be
- * in range of the value specified by the 'minRoomHfLevelMb' capability and the
- * 'maxRoomHfLevelMb' capability.
+ * Room HF level apply to the reverb effect in millibels.
*/
int roomHfLevelMb;
/**
- * Delay time apply to the reverb effect in milliseconds.The value of the decayTimeMs must
- * be non-negative and not exceed the value specified by the 'maxDecayTimeMs' capability.
+ * Delay time apply to the reverb effect in milliseconds.
*/
int decayTimeMs;
/**
- * HF decay ratio in permilles. The value of the decayHfRatioPm must be in range
- * of the value specified by the 'minDecayHfRatioPm' capability and the 'maxDecayHfRatioPm'
- * capability.
+ * HF decay ratio in permilles.
*/
int decayHfRatioPm;
/**
- * Reverb level in millibels. The value of the levelMb must be in range
- * of the value specified by the 'minLevelMb' capability and the 'maxLevelMb' capability.
+ * Reverb reflections level in millibels.
+ */
+ int reflectionsLevelMb;
+ /**
+ * Reverb reflections delay in milliseconds.
+ */
+ int reflectionsDelayMs;
+ /**
+ * Reverb level in millibels.
*/
int levelMb;
/**
- * Reverb delay in milliseconds. The value of the delayMs must be non-negative and not
- * exceed the value specified by the 'maxDelayMs' capability.
+ * Reverb delay in milliseconds.
*/
int delayMs;
/**
- * Diffusion in permilles. The value of the diffusionPm must be non-negative and not
- * exceed the value specified by the 'maxDiffusionPm' capability.
+ * Diffusion in permilles.
*/
int diffusionPm;
/**
- * Density in permilles. The value of the densityPm must be non-negative and not
- * exceed the value specified by the 'maxDensityPm' capability.
+ * Density in permilles.
*/
int densityPm;
diff --git a/audio/aidl/android/hardware/audio/effect/Equalizer.aidl b/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
index 79a1c4f..2bce151 100644
--- a/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Equalizer.aidl
@@ -21,8 +21,8 @@
/**
* Equalizer specific definitions.
*
- * All parameters defined in union Equalizer must be gettable and settable. The capabilities defined
- * in Equalizer.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.equalizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
*/
@VintfStability
union Equalizer {
@@ -41,28 +41,6 @@
VendorExtension vendorExtension;
/**
- * Capability MUST be supported by Equalizer implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * Equalizer capability extension, vendor can use this extension in case existing capability
- * definition not enough.
- */
- ParcelableHolder extension;
-
- /**
- * Bands frequency ranges supported.
- */
- BandFrequency[] bandFrequencies;
-
- /**
- * Presets name and index.
- */
- Preset[] presets;
- }
-
- /**
* Level setting for each band in millibels.
*/
@VintfStability
@@ -72,7 +50,7 @@
}
/**
- * Supported minimal and maximal frequency for each band in millihertz.
+ * Supported minimal and maximal frequency for each band in milliHertz.
*/
@VintfStability
parcelable BandFrequency {
@@ -97,8 +75,24 @@
* Level for each band.
*/
BandLevel[] bandLevels;
+
/**
* Index of current preset.
*/
int preset;
+
+ /**
+ * Get only parameter, get the center frequency for all bands in milliHertz.
+ */
+ int[] centerFreqMh;
+
+ /**
+ * Get only parameter, indicating bands frequency ranges supported by implementation.
+ */
+ BandFrequency[] bandFrequencies;
+
+ /**
+ * Get only parameter, indicating presets name and index supported by implementation.
+ */
+ Preset[] presets;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Flags.aidl b/audio/aidl/android/hardware/audio/effect/Flags.aidl
index f449c2d..1612234 100644
--- a/audio/aidl/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Flags.aidl
@@ -141,7 +141,7 @@
boolean audioSourceIndication;
/**
- * Set to true if no processing done for this effect instance.
+ * Set to true if the effect instance bypass audio data (no processing).
*/
- boolean noProcessing;
+ boolean bypass;
}
diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
index 3063ee3..a8e4564 100644
--- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -22,9 +22,9 @@
* HapticGenerator specific definitions. HapticGenerator effect provide HapticGenerator control and
* mute/unmute functionality.
*
- * All parameters defined in union HapticGenerator must be gettable and settable. The capabilities
- * defined in HapticGenerator.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.hapticGenerator definition if
+ * the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
*/
@VintfStability
union HapticGenerator {
@@ -42,18 +42,6 @@
*/
VendorExtension vendorExtension;
- /**
- * Capability supported by HapticGenerator implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * HapticGenerator capability extension, vendor can use this extension in case existing
- * capability definition not enough.
- */
- VendorExtension extension;
- }
-
@VintfStability
@Backing(type="int")
enum VibratorScale {
diff --git a/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl b/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
index 0441f10..a7cbe8d 100644
--- a/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/LoudnessEnhancer.aidl
@@ -21,9 +21,9 @@
/**
* LoudnessEnhancer specific definitions.
*
- * All parameters defined in union LoudnessEnhancer must be gettable and settable. The capabilities
- * defined in LoudnessEnhancer.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.loudnessEnhancer definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
*/
@VintfStability
union LoudnessEnhancer {
@@ -42,18 +42,6 @@
VendorExtension vendor;
/**
- * Capability supported by LoudnessEnhancer implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * LoudnessEnhancer capability extension, vendor can use this extension in case existing
- * capability definition not enough.
- */
- VendorExtension extension;
- }
-
- /**
* The maximum gain in millibels (mB) applied to the signal to process, default value is 0 which
* corresponds to no amplification.
*/
diff --git a/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl b/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
index 9969a0b..6c2fb5f 100644
--- a/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
+++ b/audio/aidl/android/hardware/audio/effect/NoiseSuppression.aidl
@@ -24,9 +24,9 @@
* engine, AC system) or non-stationary (other peoples conversations, car horn) for more advanced
* implementations.
*
- * All parameters defined in union NoiseSuppression must be gettable and settable. The capabilities
- * defined in NoiseSuppression.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.noiseSuppression definition
+ * if the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
*/
@VintfStability
union NoiseSuppression {
@@ -45,18 +45,6 @@
VendorExtension vendor;
/**
- * Capability supported by NoiseSuppression implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * NoiseSuppression capability extension, vendor can use this extension in case existing
- * capability definition not enough.
- */
- ParcelableHolder extension;
- }
-
- /**
* Different level of Noise Suppression to set.
* As an example, webrtc have NsConfig::SuppressionLevel::k6dB applied for LOW level noise
* suppression, NsConfig::SuppressionLevel::k12dB for MEDIUM, and
@@ -68,4 +56,11 @@
* The NS level.
*/
Level level;
+
+ /**
+ * Noise suppression type.
+ */
+ @VintfStability @Backing(type="int") enum Type { SINGLE_CHANNEL, MULTI_CHANNEL }
+
+ Type type;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 473dfb5..9f8874b 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -17,7 +17,8 @@
package android.hardware.audio.effect;
import android.hardware.audio.effect.AcousticEchoCanceler;
-import android.hardware.audio.effect.AutomaticGainControl;
+import android.hardware.audio.effect.AutomaticGainControlV1;
+import android.hardware.audio.effect.AutomaticGainControlV2;
import android.hardware.audio.effect.BassBoost;
import android.hardware.audio.effect.Downmix;
import android.hardware.audio.effect.DynamicsProcessing;
@@ -44,6 +45,14 @@
* 2. Parameters defined for a specific effect type.
* 3. Extension parameters ParcelableHolder can be used for vendor effect definition.
*
+ * All parameter settings must be inside the range of Capability.Range.$EffectType$ definition. If
+ * an effect implementation doesn't have limitation for a parameter, then don't define any effect
+ * range.
+ *
+ * All parameters are get-able, if any parameter doesn't support set, effect implementation should
+ * report the supported range for this parameter as range.min > range.max. If no support range is
+ * defined for a parameter, it means this parameter doesn't have any limitation.
+ *
*/
@VintfStability
union Parameter {
@@ -75,7 +84,8 @@
*
*/
AcousticEchoCanceler.Id acousticEchoCancelerTag;
- AutomaticGainControl.Id automaticGainControlTag;
+ AutomaticGainControlV1.Id automaticGainControlV1Tag;
+ AutomaticGainControlV2.Id automaticGainControlV2Tag;
BassBoost.Id bassBoostTag;
Downmix.Id downmixTag;
DynamicsProcessing.Id dynamicsProcessingTag;
@@ -157,7 +167,8 @@
union Specific {
VendorExtension vendorEffect;
AcousticEchoCanceler acousticEchoCanceler;
- AutomaticGainControl automaticGainControl;
+ AutomaticGainControlV1 automaticGainControlV1;
+ AutomaticGainControlV2 automaticGainControlV2;
BassBoost bassBoost;
Downmix downmix;
DynamicsProcessing dynamicsProcessing;
diff --git a/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl b/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
index 6048eea..87c78b0 100644
--- a/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
+++ b/audio/aidl/android/hardware/audio/effect/PresetReverb.aidl
@@ -21,9 +21,9 @@
/**
* PresetReverb specific definitions.
*
- * All parameters defined in union PresetReverb must be gettable and settable. The capabilities
- * defined in PresetReverb.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.presetReverb definition if
+ * the definition for the corresponding parameter tag exist. See more detals about Range in
+ * Range.aidl.
*/
@VintfStability
union PresetReverb {
@@ -78,21 +78,24 @@
VendorExtension vendor;
/**
- * Capability supported by effect implementation.
+ * The list of presets supported by implementation, effect implementation must declare the
+ * support of Presets with Capability.Range.presetReverb definition. For example, if an effect
+ * implementation supports all Presets in PresetReverb.Presets, then the capability will be:
+ * const std::vector<PresetReverb::Presets> kSupportedPresets{
+ * ndk::enum_range<PresetReverb::Presets>().begin(),
+ * ndk::enum_range<PresetReverb::Presets>().end()};
+ * const std::vector<Range::PresetReverbRange> kRanges = {
+ * MAKE_RANGE(PresetReverb, supportedPresets, kSupportedPresets, kSupportedPresets)};
*/
- @VintfStability
- parcelable Capability {
- VendorExtension extension;
-
- /**
- * List of presets supported.
- */
- Presets[] supportedPresets;
- }
+ Presets[] supportedPresets;
/**
* Get current reverb preset when used in getParameter.
* Enable a preset reverb when used in setParameter.
+ * With the current Range definition, there is no good way to define enum capability, so the
+ * Presets vector supportedPresets is used to defined the capability. Client must check the
+ * capability in PresetReverb.supportedPresets, and make sure to get the list of supported
+ * presets before setting.
*/
Presets preset;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Range.aidl b/audio/aidl/android/hardware/audio/effect/Range.aidl
index c052502..567320a 100644
--- a/audio/aidl/android/hardware/audio/effect/Range.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Range.aidl
@@ -16,50 +16,205 @@
package android.hardware.audio.effect;
+import android.hardware.audio.effect.AcousticEchoCanceler;
+import android.hardware.audio.effect.AutomaticGainControlV1;
+import android.hardware.audio.effect.AutomaticGainControlV2;
+import android.hardware.audio.effect.BassBoost;
+import android.hardware.audio.effect.Downmix;
+import android.hardware.audio.effect.DynamicsProcessing;
+import android.hardware.audio.effect.EnvironmentalReverb;
+import android.hardware.audio.effect.Equalizer;
+import android.hardware.audio.effect.HapticGenerator;
+import android.hardware.audio.effect.LoudnessEnhancer;
+import android.hardware.audio.effect.NoiseSuppression;
+import android.hardware.audio.effect.PresetReverb;
+import android.hardware.audio.effect.VendorExtension;
+import android.hardware.audio.effect.Virtualizer;
+import android.hardware.audio.effect.Visualizer;
+import android.hardware.audio.effect.Volume;
+
/**
- * Define the range (min and max) of a certain field, identified by tag.
- * Can be used by effect capabilities to define supported value ranges.
+ * Define the supported range of effect parameters.
+ * Effect implementation must report the supported range of parameter/capability if there is any
+ * limitation.
+ * Range of each effect type is defined with a vector, because each $EffectType$Range can only
+ * describe the range of one parameter. For example, Range::AcousticEchoCancelerRange can only
+ * describe one of vendor, echoDelayUs, and mobileMode.
+ *
+ * If an effect implementation needs to define the valid range for a certain parameter, it can
+ * write the minimum/maximum supported value to the corresponding effect range, and add the range
+ * to vector of this effect type.
+ * Say if an AcousticEchoCanceler implementation wants to define the supported range of echoDelayUs
+ * to [0, 500], then the Capability range should include an item in acousticEchoCanceler list:
+ * std::vector<Range::AcousticEchoCancelerRange> kRanges = {
+ * MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500)};
+ *
+ * For a more complex example, if a DynamicsProcessing implementation wants to define the
+ * supported range of preEqBand channel to [0, 1], band index to [0, 5], and cutoffFrequencyHz to
+ * [220, 20000]:
+ * Range::DynamicsProcessingRange kRange = {
+ * .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ * {EqBandConfig({.channel = 0,
+ * .band = 0,
+ * .enable = false,
+ * .cutoffFrequencyHz = 220,
+ * .gainDb = std::numeric_limits<float>::min()})}),
+ * .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ * {EqBandConfig({.channel = 1,
+ * .band = 5,
+ * .enable = true,
+ * .cutoffFrequencyHz = 20000,
+ * .gainDb = std::numeric_limits<float>::max()})})};
+ *
+ * For get only parameters, the effect implementation must define an invalid range (min > max), to
+ * indicate no parameter from the effect client can be accepted for setting. The effect
+ * implementation must return EX_ILLEGAL_ARGUMENT if it receives any setParameter call for a get
+ * only parameter.
+ * As an example, the get-only parameter Virtualizer.speakerAngles can be defined with:
+ * Range::VirtualizerRange kRanges = {
+ * MAKE_RANGE(Virtualizer, speakerAngles,
+ * {Virtualizer::ChannelAngle({.channel = 1},
+ * {Virtualizer::ChannelAngle({.channel = 0})};
+ *
+ * For a capability definition (which is also get only), the effect implementation must define a
+ * range with min == max, to indicate this is a fixed capability which shouldn't set by client.
+ * As an example, the Equalizer presets capability can be defined with:
+ * std::vector<Equalizer::Preset> kPresets = {
+ * {0, "Normal"}, {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
+ * {5, "Heavy Metal"}, {6, "Hip Hop"}, {7, "Jazz"}, {8, "Pop"}, {9, "Rock"}};
+ * Range::EqualizerRange kRanges =
+ * MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets);
+ *
+ * For enum capability, it's necessary to either list a range, or explicitly list out all enums in
+ * the Range definition, see PresetReverb.supportedPresets as example.
+ *
+ * The effect implementation must return EX_ILLEGAL_ARGUMENT if:
+ * 1. receive any setParameter call for get only parameter (min > max).
+ * 2. receive any setParameter call for capability parameter definition (min == max).
+ * 3. receive any setParameter call for parameters not in the range of [min, max].
+ *
*/
@VintfStability
-parcelable Range {
+union Range {
+ @VintfStability
+ parcelable AcousticEchoCancelerRange {
+ AcousticEchoCanceler min;
+ AcousticEchoCanceler max;
+ }
+
+ @VintfStability
+ parcelable AutomaticGainControlV1Range {
+ AutomaticGainControlV1 min;
+ AutomaticGainControlV1 max;
+ }
+
+ @VintfStability
+ parcelable AutomaticGainControlV2Range {
+ AutomaticGainControlV2 min;
+ AutomaticGainControlV2 max;
+ }
+
+ @VintfStability
+ parcelable BassBoostRange {
+ BassBoost min;
+ BassBoost max;
+ }
+
+ @VintfStability
+ parcelable DownmixRange {
+ Downmix min;
+ Downmix max;
+ }
+
+ @VintfStability
+ parcelable DynamicsProcessingRange {
+ DynamicsProcessing min;
+ DynamicsProcessing max;
+ }
+
+ @VintfStability
+ parcelable EnvironmentalReverbRange {
+ EnvironmentalReverb min;
+ EnvironmentalReverb max;
+ }
+
+ @VintfStability
+ parcelable EqualizerRange {
+ Equalizer min;
+ Equalizer max;
+ }
+
+ @VintfStability
+ parcelable HapticGeneratorRange {
+ HapticGenerator min;
+ HapticGenerator max;
+ }
+
+ @VintfStability
+ parcelable LoudnessEnhancerRange {
+ LoudnessEnhancer min;
+ LoudnessEnhancer max;
+ }
+
+ @VintfStability
+ parcelable NoiseSuppressionRange {
+ NoiseSuppression min;
+ NoiseSuppression max;
+ }
+
+ @VintfStability
+ parcelable PresetReverbRange {
+ PresetReverb min;
+ PresetReverb max;
+ }
+
+ @VintfStability
+ parcelable VendorExtensionRange {
+ VendorExtension min;
+ VendorExtension max;
+ }
+
+ @VintfStability
+ parcelable VirtualizerRange {
+ Virtualizer min;
+ Virtualizer max;
+ }
+
+ @VintfStability
+ parcelable VisualizerRange {
+ Visualizer min;
+ Visualizer max;
+ }
+
+ @VintfStability
+ parcelable VolumeRange {
+ Volume min;
+ Volume max;
+ }
+
/**
- * The union tag name which the range is defined for.
- * For example: if used in AutomaticGainControlV1.Capability, value of Range.tag could be
- * targetLevelDbFs or compressionGainDb.
+ * The vector of range defined for parameters of each effect implementation.
+ * Each element of the vector represents the min and max range of a parameter, so the size of
+ * vector is the number of parameter ranges defined for this effect implementation.
+ *
+ * The effect implementation must not have duplicated parameter range definition in the vector.
+ * Client side must go though the vector and make sure the parameter setting to effect
+ * implementation is in valid range.
*/
- int tag;
-
- @VintfStability
- parcelable Int {
- int min;
- int max;
- }
-
- @VintfStability
- parcelable Float {
- float min;
- float max;
- }
-
- @VintfStability
- parcelable Long {
- long min;
- long max;
- }
-
- @VintfStability
- parcelable Byte {
- byte min;
- byte max;
- }
-
- @VintfStability
- union Types {
- Int rangeInt;
- Float rangeFloat;
- Long rangeLong;
- Byte rangeByte;
- }
-
- Types types;
+ VendorExtensionRange[] vendorExtension = {};
+ AcousticEchoCancelerRange[] acousticEchoCanceler;
+ AutomaticGainControlV1Range[] automaticGainControlV1;
+ AutomaticGainControlV2Range[] automaticGainControlV2;
+ BassBoostRange[] bassBoost;
+ DownmixRange[] downmix;
+ DynamicsProcessingRange[] dynamicsProcessing;
+ EnvironmentalReverbRange[] environmentalReverb;
+ EqualizerRange[] equalizer;
+ HapticGeneratorRange[] hapticGenerator;
+ LoudnessEnhancerRange[] loudnessEnhancer;
+ NoiseSuppressionRange[] noiseSuppression;
+ PresetReverbRange[] presetReverb;
+ VirtualizerRange[] virtualizer;
+ VisualizerRange[] visualizer;
+ VolumeRange[] volume;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
index 5f385a6..37ea2a4 100644
--- a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
@@ -17,14 +17,15 @@
package android.hardware.audio.effect;
import android.hardware.audio.effect.VendorExtension;
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.common.AudioDeviceDescription;
/**
* Virtualizer specific definitions. An audio virtualizer is a general name for an effect to
* spatialize audio channels.
*
- * All parameters defined in union Virtualizer must be gettable and settable. The capabilities
- * defined in Virtualizer.Capability can only acquired with IEffect.getDescriptor() and not
- * settable.
+ * All parameter settings must be inside the range of Capability.Range.virtualizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
*/
@VintfStability
union Virtualizer {
@@ -35,6 +36,7 @@
union Id {
int vendorExtensionTag;
Virtualizer.Tag commonTag;
+ SpeakerAnglesPayload speakerAnglesPayload;
}
/**
@@ -43,24 +45,22 @@
VendorExtension vendor;
/**
- * Capability supported by Virtualizer implementation.
+ * Payload to query speaker angles for the given channel position mask and device.
+ * The Virtualizer implementation must return EX_ILLEGAL_ARGUMENT if the given payload not
+ * supported.
*/
@VintfStability
- parcelable Capability {
+ parcelable SpeakerAnglesPayload {
/**
- * Virtualizer capability extension, vendor can use this extension in case existing
- * capability definition not enough.
+ * Audio channel position definition. See
+ * android.media.audio.common.AudioChannelLayout.aidl. Only the channel position "CHANNEL_*"
+ * in AudioChannelLayout be used.
*/
- VendorExtension extension;
+ AudioChannelLayout layout;
/**
- * Maximum possible per mille strength.
+ * Audio device type. See android.media.audio.common.AudioDeviceDescription.aidl.
*/
- int maxStrengthPm;
- /**
- * Indicates whether setting strength is supported. False value indicates only one strength
- * is supported and setParameter() method will always return EX_ILLEGAL_ARGUMENT.
- */
- boolean strengthSupported;
+ AudioDeviceDescription device;
}
/**
@@ -70,8 +70,42 @@
* allowed to round the given strength to the nearest supported value. In this case {@link
* #IEffect.getParameter()} method should return the rounded value that was actually set.
*
- * The value of the strength must be non-negative and not exceed the value specified by
- * the 'maxStrengthPm' capability.
*/
int strengthPm;
+
+ /**
+ * All angles are expressed in degrees and are relative to the listener.
+ */
+ @VintfStability
+ parcelable ChannelAngle {
+ /**
+ * Audio channel layout, CHANNEL_* constants defined in
+ * android.media.audio.common.AudioChannelLayout.
+ */
+ int channel;
+
+ /**
+ * 0 is the direction the listener faces, 180 is behind the listener, and -90 is left of
+ * the listener.
+ */
+ int azimuthDegree;
+
+ /**
+ * 0 is the horizontal plane, +90 is above the listener, -90 is below.
+ */
+ int elevationDegree;
+ }
+
+ /**
+ * Get only parameter.
+ * A vector of angles per channel represented by azimuth and elevation (in degrees), client must
+ * set Parameter.Id to SpeakerAnglesPayload to get speakerAngles.
+ */
+ ChannelAngle[] speakerAngles;
+
+ /**
+ * Get only parameter.
+ * The audio device on which virtualzation mode is forced.
+ */
+ AudioDeviceDescription device;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
index dfe29c8..8f2faaa 100644
--- a/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Visualizer.aidl
@@ -22,9 +22,8 @@
* Visualizer specific definitions. Visualizer enables application to retrieve part of the currently
* playing audio for visualization purpose
*
- * All parameters defined in union Visualizer other than these in GetOnlyParameters and
- * SetOnlyParameters must be gettable and settable. The capabilities defined in
- * Visualizer.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.visualizer definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
*
*/
@VintfStability
@@ -35,8 +34,6 @@
@VintfStability
union Id {
int vendorExtensionTag;
- GetOnlyParameters.Tag getOnlyParamTag;
- SetOnlyParameters.Tag setOnlyParamTag;
Visualizer.Tag commonTag;
}
Id id;
@@ -47,35 +44,6 @@
VendorExtension vendor;
/**
- * Capability supported by Visualizer implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * Visualizer capability extension, vendor can use this extension in case existing
- * capability definition not enough.
- */
- VendorExtension extension;
- /**
- * Max latency supported in millseconds.
- */
- int maxLatencyMs;
- /**
- * Capture size range.
- */
- CaptureSamplesRange captureSampleRange;
- }
-
- /**
- * Supported capture size range in samples.
- */
- @VintfStability
- parcelable CaptureSamplesRange {
- int min;
- int max;
- }
-
- /**
* Type of scaling applied on the captured visualization data.
*/
@VintfStability
@@ -115,51 +83,42 @@
}
/**
- * Any parameter defined in this union must be gettable via getParameter(), but must not
- * settable.
+ * Get only parameter to get the current measurements.
*/
@VintfStability
- union GetOnlyParameters {
- /**
- * Get the current measurements.
- */
- @VintfStability
- parcelable Measurement {
- int rms;
- int peak;
- }
- Measurement measurement;
-
- /**
- * Get the latest captureSamples of PCM samples (8 bits per sample).
- */
- byte[] captureSampleBuffer;
+ parcelable Measurement {
+ int rms;
+ int peak;
}
- GetOnlyParameters getOnlyParameters;
+ Measurement measurement;
/**
- * Any parameter defined in this union must be settable via setParameter(), but must not
- * gettable.
+ * Get only parameter to get the latest captured samples of PCM samples (8 bits per sample).
*/
- @VintfStability
- union SetOnlyParameters {
- /**
- * Used by framework to inform the visualizer about the downstream latency (audio hardware
- * driver estimated latency in milliseconds).
- */
- int latencyMs;
- }
- SetOnlyParameters setOnlyParameters;
+ byte[] captureSampleBuffer;
/**
- * Current capture size in number of samples. The capture size must be inside
- * Capability.captureSizeRange.
+ * Used by framework to inform the visualizer about the downstream latency (audio hardware
+ * driver estimated latency in milliseconds).
+ *
+ * Visualizer implementation must use Range.VisualizerRange to define the range of supported
+ * latency.
+ */
+ int latencyMs;
+
+ /**
+ * Current capture size in number of samples.
+ *
+ * Visualizer implementation must use Range.VisualizerRange to define the range of supported
+ * capture size.
*/
int captureSamples;
+
/**
* Visualizer capture mode
*/
ScalingMode scalingMode;
+
/**
* Visualizer measurement mode.
*/
diff --git a/audio/aidl/android/hardware/audio/effect/Volume.aidl b/audio/aidl/android/hardware/audio/effect/Volume.aidl
index 5033881..4a76703 100644
--- a/audio/aidl/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Volume.aidl
@@ -21,8 +21,8 @@
/**
* Volume specific definitions. Volume effect provide volume control and mute/unmute functionality.
*
- * All parameters defined in union Volume must be gettable and settable. The capabilities defined in
- * Volume.Capability can only acquired with IEffect.getDescriptor() and not settable.
+ * All parameter settings must be inside the range of Capability.Range.volume definition if the
+ * definition for the corresponding parameter tag exist. See more detals about Range in Range.aidl.
*/
@VintfStability
union Volume {
@@ -41,29 +41,7 @@
VendorExtension vendor;
/**
- * Capability supported by Volume implementation.
- */
- @VintfStability
- parcelable Capability {
- /**
- * Volume capability extension, vendor can use this extension in case existing capability
- * definition not enough.
- */
- VendorExtension extension;
-
- /**
- * Minimum Volume level supported in dB.
- */
- int minLevelDb;
-
- /**
- * Maximum Volume level supported in dB.
- */
- int maxLevelDb;
- }
-
- /**
- * Current level in dB with supported minimum and maximum level specified in capability.
+ * Current level in dB.
*/
int levelDb;
/**
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 2aaa781..d87bbd4 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -104,6 +104,30 @@
device == ::aidl::android::media::audio::common::AudioDeviceType::OUT_TELEPHONY_TX;
}
+constexpr bool isUsbInputDeviceType(::aidl::android::media::audio::common::AudioDeviceType type) {
+ switch (type) {
+ case ::aidl::android::media::audio::common::AudioDeviceType::IN_DOCK:
+ case ::aidl::android::media::audio::common::AudioDeviceType::IN_ACCESSORY:
+ case ::aidl::android::media::audio::common::AudioDeviceType::IN_DEVICE:
+ case ::aidl::android::media::audio::common::AudioDeviceType::IN_HEADSET:
+ return true;
+ default:
+ return false;
+ }
+}
+
+constexpr bool isUsbOutputtDeviceType(::aidl::android::media::audio::common::AudioDeviceType type) {
+ switch (type) {
+ case ::aidl::android::media::audio::common::AudioDeviceType::OUT_DOCK:
+ case ::aidl::android::media::audio::common::AudioDeviceType::OUT_ACCESSORY:
+ case ::aidl::android::media::audio::common::AudioDeviceType::OUT_DEVICE:
+ case ::aidl::android::media::audio::common::AudioDeviceType::OUT_HEADSET:
+ return true;
+ default:
+ return false;
+ }
+}
+
constexpr bool isValidAudioMode(::aidl::android::media::audio::common::AudioMode mode) {
return std::find(kValidAudioModes.begin(), kValidAudioModes.end(), mode) !=
kValidAudioModes.end();
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 856f83f..21616be 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -11,12 +11,14 @@
name: "aidlaudioservice_defaults",
vendor: true,
shared_libs: [
+ "libalsautilsv2",
"libaudioaidlcommon",
"libbase",
"libbinder_ndk",
"libcutils",
"libfmq",
"libstagefright_foundation",
+ "libtinyalsav2",
"libutils",
"libxml2",
"android.hardware.common-V2-ndk",
@@ -71,6 +73,9 @@
"Stream.cpp",
"StreamStub.cpp",
"Telephony.cpp",
+ "usb/ModuleUsb.cpp",
+ "usb/StreamUsb.cpp",
+ "usb/UsbAlsaUtils.cpp",
],
generated_sources: [
"audio_policy_configuration_aidl_default",
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 854c7f3..a72be24 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -40,6 +40,7 @@
using aidl::android::media::audio::common::AudioPortMixExt;
using aidl::android::media::audio::common::AudioProfile;
using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneInfo;
using aidl::android::media::audio::common::PcmType;
using android::hardware::audio::common::makeBitPositionFlagMask;
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 403a4b9..e90fe35 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -78,7 +78,7 @@
ndk::ScopedAStatus EffectImpl::setParameter(const Parameter& param) {
LOG(DEBUG) << __func__ << " with: " << param.toString();
- auto tag = param.getTag();
+ const auto tag = param.getTag();
switch (tag) {
case Parameter::common:
case Parameter::deviceDescription:
@@ -107,11 +107,8 @@
"CommonParamNotSupported");
break;
}
- case Parameter::Id::vendorEffectTag: {
- LOG(DEBUG) << __func__ << " noop for vendor tag";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
- "vendortagNotSupported");
- }
+ case Parameter::Id::vendorEffectTag:
+ FALLTHROUGH_INTENDED;
default: {
Parameter::Specific specific;
RETURN_IF_ASTATUS_NOT_OK(getParameterSpecific(id, &specific), "SpecParamNotSupported");
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index 2b3513d..024c0ea 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -70,26 +70,14 @@
}
RetCode EffectThread::startThread() {
- if (!mThread.joinable()) {
- LOG(ERROR) << __func__ << " thread already destroyed";
- return RetCode::ERROR_THREAD;
- }
-
- {
- std::lock_guard lg(mThreadMutex);
- if (!mStop) {
- LOG(WARNING) << __func__ << " already start";
- return RetCode::SUCCESS;
- }
- mStop = false;
- }
-
- mCv.notify_one();
- LOG(DEBUG) << __func__ << " done";
- return RetCode::SUCCESS;
+ return handleStartStop(false /* stop */);
}
RetCode EffectThread::stopThread() {
+ return handleStartStop(true /* stop */);
+}
+
+RetCode EffectThread::handleStartStop(bool stop) {
if (!mThread.joinable()) {
LOG(ERROR) << __func__ << " thread already destroyed";
return RetCode::ERROR_THREAD;
@@ -97,13 +85,15 @@
{
std::lock_guard lg(mThreadMutex);
- if (mStop) {
- LOG(WARNING) << __func__ << " already stop";
+ if (stop == mStop) {
+ LOG(WARNING) << __func__ << " already " << (stop ? "stop" : "start");
return RetCode::SUCCESS;
}
- mStop = true;
+ mStop = stop;
}
- LOG(DEBUG) << __func__ << " done";
+
+ mCv.notify_one();
+ LOG(DEBUG) << (stop ? "stop done" : "start done");
return RetCode::SUCCESS;
}
@@ -111,34 +101,23 @@
pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
setpriority(PRIO_PROCESS, 0, mPriority);
while (true) {
- bool needExit = false;
- {
- std::unique_lock l(mThreadMutex);
- mCv.wait(l, [&]() REQUIRES(mThreadMutex) {
- needExit = mExit;
- return mExit || !mStop;
- });
- }
- if (needExit) {
+ std::unique_lock l(mThreadMutex);
+ ::android::base::ScopedLockAssertion lock_assertion(mThreadMutex);
+ mCv.wait(l, [&]() REQUIRES(mThreadMutex) { return mExit || !mStop; });
+ if (mExit) {
LOG(WARNING) << __func__ << " EXIT!";
return;
}
-
- process();
+ process_l();
}
}
-void EffectThread::process() {
- std::shared_ptr<EffectContext> context;
- {
- std::lock_guard lg(mThreadMutex);
- context = mThreadContext;
- RETURN_VALUE_IF(!context, void(), "nullContext");
- }
- std::shared_ptr<EffectContext::StatusMQ> statusMQ = context->getStatusFmq();
- std::shared_ptr<EffectContext::DataMQ> inputMQ = context->getInputDataFmq();
- std::shared_ptr<EffectContext::DataMQ> outputMQ = context->getOutputDataFmq();
- auto buffer = context->getWorkBuffer();
+void EffectThread::process_l() {
+ RETURN_VALUE_IF(!mThreadContext, void(), "nullContext");
+ std::shared_ptr<EffectContext::StatusMQ> statusMQ = mThreadContext->getStatusFmq();
+ std::shared_ptr<EffectContext::DataMQ> inputMQ = mThreadContext->getInputDataFmq();
+ std::shared_ptr<EffectContext::DataMQ> outputMQ = mThreadContext->getOutputDataFmq();
+ auto buffer = mThreadContext->getWorkBuffer();
// Only this worker will read from input data MQ and write to output data MQ.
auto readSamples = inputMQ->availableToRead(), writeSamples = outputMQ->availableToWrite();
@@ -149,7 +128,6 @@
inputMQ->read(buffer, processSamples);
- // call effectProcessImpl without lock
IEffect::Status status = effectProcessImpl(buffer, buffer, processSamples);
outputMQ->write(buffer, status.fmqProduced);
statusMQ->writeBlocking(&status, 1);
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 905ff2c..5440b8d 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -27,8 +27,10 @@
#include "core-impl/Bluetooth.h"
#include "core-impl/Module.h"
+#include "core-impl/ModuleUsb.h"
#include "core-impl/SoundDose.h"
#include "core-impl/StreamStub.h"
+#include "core-impl/StreamUsb.h"
#include "core-impl/Telephony.h"
#include "core-impl/utils.h"
@@ -53,6 +55,7 @@
using aidl::android::media::audio::common::AudioProfile;
using aidl::android::media::audio::common::Boolean;
using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneInfo;
using aidl::android::media::audio::common::PcmType;
using android::hardware::audio::common::getFrameSizeInBytes;
using android::hardware::audio::common::isBitPositionFlagSet;
@@ -104,6 +107,42 @@
} // namespace
+// static
+std::shared_ptr<Module> Module::createInstance(Type type) {
+ switch (type) {
+ case Module::Type::USB:
+ return ndk::SharedRefBase::make<ModuleUsb>(type);
+ case Type::DEFAULT:
+ case Type::R_SUBMIX:
+ default:
+ return ndk::SharedRefBase::make<Module>(type);
+ }
+}
+
+// static
+StreamIn::CreateInstance Module::getStreamInCreator(Type type) {
+ switch (type) {
+ case Type::USB:
+ return StreamInUsb::createInstance;
+ case Type::DEFAULT:
+ case Type::R_SUBMIX:
+ default:
+ return StreamInStub::createInstance;
+ }
+}
+
+// static
+StreamOut::CreateInstance Module::getStreamOutCreator(Type type) {
+ switch (type) {
+ case Type::USB:
+ return StreamOutUsb::createInstance;
+ case Type::DEFAULT:
+ case Type::R_SUBMIX:
+ default:
+ return StreamOutStub::createInstance;
+ }
+}
+
void Module::cleanUpPatch(int32_t patchId) {
erase_all_values(mPatches, std::set<int32_t>{patchId});
}
@@ -153,6 +192,7 @@
std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
portConfigIt->format.value(), portConfigIt->channelMask.value(),
+ portConfigIt->sampleRate.value().value,
std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
asyncCallback, outEventCallback, params);
if (temp.isValid()) {
@@ -261,6 +301,7 @@
break;
case Type::USB:
mConfig = std::move(internal::getUsbConfiguration());
+ break;
}
}
return *mConfig;
@@ -401,6 +442,8 @@
if (!mDebug.simulateDeviceConnections) {
// In a real HAL here we would attempt querying the profiles from the device.
LOG(ERROR) << __func__ << ": failed to query supported device profiles";
+ // TODO: Check the return value when it is ready for actual devices.
+ populateConnectedDevicePort(&connectedPort);
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
@@ -560,10 +603,9 @@
}
context.fillDescriptor(&_aidl_return->desc);
std::shared_ptr<StreamIn> stream;
- // TODO: Add a mapping from module instance names to a corresponding 'createInstance'.
- if (auto status = StreamInStub::createInstance(in_args.sinkMetadata, std::move(context),
- mConfig->microphones, &stream);
- !status.isOk()) {
+ ndk::ScopedAStatus status = getStreamInCreator(mType)(in_args.sinkMetadata, std::move(context),
+ mConfig->microphones, &stream);
+ if (!status.isOk()) {
return status;
}
StreamWrapper streamWrapper(stream);
@@ -615,10 +657,9 @@
}
context.fillDescriptor(&_aidl_return->desc);
std::shared_ptr<StreamOut> stream;
- // TODO: Add a mapping from module instance names to a corresponding 'createInstance'.
- if (auto status = StreamOutStub::createInstance(in_args.sourceMetadata, std::move(context),
- in_args.offloadInfo, &stream);
- !status.isOk()) {
+ ndk::ScopedAStatus status = getStreamOutCreator(mType)(
+ in_args.sourceMetadata, std::move(context), in_args.offloadInfo, &stream);
+ if (!status.isOk()) {
return status;
}
StreamWrapper streamWrapper(stream);
@@ -696,6 +737,10 @@
}
}
+ if (auto status = checkAudioPatchEndpointsMatch(sources, sinks); !status.isOk()) {
+ return status;
+ }
+
auto& patches = getConfig().patches;
auto existing = patches.end();
std::optional<decltype(mPatches)> patchesBackup;
@@ -850,6 +895,21 @@
out_suggested->gain = in_requested.gain.value();
}
+ if (in_requested.ext.getTag() != AudioPortExt::Tag::unspecified) {
+ if (in_requested.ext.getTag() == out_suggested->ext.getTag()) {
+ if (out_suggested->ext.getTag() == AudioPortExt::Tag::mix) {
+ // 'AudioMixPortExt.handle' is set by the client, copy from in_requested
+ out_suggested->ext.get<AudioPortExt::Tag::mix>().handle =
+ in_requested.ext.get<AudioPortExt::Tag::mix>().handle;
+ }
+ } else {
+ LOG(WARNING) << __func__ << ": requested ext tag "
+ << toString(in_requested.ext.getTag()) << " do not match port's tag "
+ << toString(out_suggested->ext.getTag());
+ requestedIsValid = false;
+ }
+ }
+
if (existing == configs.end() && requestedIsValid && requestedIsFullySpecified) {
out_suggested->id = getConfig().nextPortId++;
configs.push_back(*out_suggested);
@@ -1190,4 +1250,16 @@
return mIsMmapSupported.value();
}
+ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) {
+ LOG(DEBUG) << __func__ << ": do nothing and return ok";
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Module::checkAudioPatchEndpointsMatch(
+ const std::vector<AudioPortConfig*>& sources __unused,
+ const std::vector<AudioPortConfig*>& sinks __unused) {
+ LOG(DEBUG) << __func__ << ": do nothing and return ok";
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 25814e4..49ad2f2 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -31,6 +31,8 @@
using aidl::android::media::audio::common::AudioLatencyMode;
using aidl::android::media::audio::common::AudioOffloadInfo;
using aidl::android::media::audio::common::AudioPlaybackRate;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
using android::hardware::audio::common::getChannelCount;
using android::hardware::audio::common::getFrameSizeInBytes;
@@ -135,10 +137,16 @@
mState = StreamDescriptor::State::ERROR;
return Status::ABORT;
}
- LOG(DEBUG) << __func__ << ": received command " << command.toString() << " in " << kThreadName;
+ using Tag = StreamDescriptor::Command::Tag;
+ using LogSeverity = ::android::base::LogSeverity;
+ const LogSeverity severity =
+ command.getTag() == Tag::burst || command.getTag() == Tag::getStatus
+ ? LogSeverity::VERBOSE
+ : LogSeverity::DEBUG;
+ LOG(severity) << __func__ << ": received command " << command.toString() << " in "
+ << kThreadName;
StreamDescriptor::Reply reply{};
reply.status = STATUS_BAD_VALUE;
- using Tag = StreamDescriptor::Command::Tag;
switch (command.getTag()) {
case Tag::halReservedExit:
if (const int32_t cookie = command.get<Tag::halReservedExit>();
@@ -166,8 +174,8 @@
break;
case Tag::burst:
if (const int32_t fmqByteCount = command.get<Tag::burst>(); fmqByteCount >= 0) {
- LOG(DEBUG) << __func__ << ": '" << toString(command.getTag()) << "' command for "
- << fmqByteCount << " bytes";
+ LOG(VERBOSE) << __func__ << ": '" << toString(command.getTag()) << "' command for "
+ << fmqByteCount << " bytes";
if (mState == StreamDescriptor::State::IDLE ||
mState == StreamDescriptor::State::ACTIVE ||
mState == StreamDescriptor::State::PAUSED ||
@@ -253,7 +261,7 @@
break;
}
reply.state = mState;
- LOG(DEBUG) << __func__ << ": writing reply " << reply.toString();
+ LOG(severity) << __func__ << ": writing reply " << reply.toString();
if (!mReplyMQ->writeBlocking(&reply, 1)) {
LOG(ERROR) << __func__ << ": writing of reply " << reply.toString() << " to MQ failed";
mState = StreamDescriptor::State::ERROR;
@@ -284,8 +292,8 @@
if (bool success =
actualByteCount > 0 ? mDataMQ->write(&mDataBuffer[0], actualByteCount) : true;
success) {
- LOG(DEBUG) << __func__ << ": writing of " << actualByteCount << " bytes into data MQ"
- << " succeeded; connected? " << isConnected;
+ LOG(VERBOSE) << __func__ << ": writing of " << actualByteCount << " bytes into data MQ"
+ << " succeeded; connected? " << isConnected;
// Frames are provided and counted regardless of connection status.
reply->fmqByteCount += actualByteCount;
mFrameCount += actualFrameCount;
@@ -340,7 +348,14 @@
mState = StreamDescriptor::State::ERROR;
return Status::ABORT;
}
- LOG(DEBUG) << __func__ << ": received command " << command.toString() << " in " << kThreadName;
+ using Tag = StreamDescriptor::Command::Tag;
+ using LogSeverity = ::android::base::LogSeverity;
+ const LogSeverity severity =
+ command.getTag() == Tag::burst || command.getTag() == Tag::getStatus
+ ? LogSeverity::VERBOSE
+ : LogSeverity::DEBUG;
+ LOG(severity) << __func__ << ": received command " << command.toString() << " in "
+ << kThreadName;
StreamDescriptor::Reply reply{};
reply.status = STATUS_BAD_VALUE;
using Tag = StreamDescriptor::Command::Tag;
@@ -383,8 +398,8 @@
} break;
case Tag::burst:
if (const int32_t fmqByteCount = command.get<Tag::burst>(); fmqByteCount >= 0) {
- LOG(DEBUG) << __func__ << ": '" << toString(command.getTag()) << "' command for "
- << fmqByteCount << " bytes";
+ LOG(VERBOSE) << __func__ << ": '" << toString(command.getTag()) << "' command for "
+ << fmqByteCount << " bytes";
if (mState != StreamDescriptor::State::ERROR &&
mState != StreamDescriptor::State::TRANSFERRING &&
mState != StreamDescriptor::State::TRANSFER_PAUSED) {
@@ -499,7 +514,7 @@
break;
}
reply.state = mState;
- LOG(DEBUG) << __func__ << ": writing reply " << reply.toString();
+ LOG(severity) << __func__ << ": writing reply " << reply.toString();
if (!mReplyMQ->writeBlocking(&reply, 1)) {
LOG(ERROR) << __func__ << ": writing of reply " << reply.toString() << " to MQ failed";
mState = StreamDescriptor::State::ERROR;
@@ -514,8 +529,8 @@
int32_t latency = Module::kLatencyMs;
if (bool success = readByteCount > 0 ? mDataMQ->read(&mDataBuffer[0], readByteCount) : true) {
const bool isConnected = mIsConnected;
- LOG(DEBUG) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
- << " succeeded; connected? " << isConnected;
+ LOG(VERBOSE) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
+ << " succeeded; connected? " << isConnected;
// Amount of data that the HAL module is going to actually use.
size_t byteCount = std::min({clientSize, readByteCount, mDataBufferSize});
if (byteCount >= mFrameSize && mForceTransientBurst) {
diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/StreamStub.cpp
index 5442179..0ed9357 100644
--- a/audio/aidl/default/StreamStub.cpp
+++ b/audio/aidl/default/StreamStub.cpp
@@ -22,7 +22,9 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
namespace aidl::android::hardware::audio::core {
@@ -68,6 +70,11 @@
return ::android::OK;
}
+::android::status_t DriverStub::setConnectedDevices(
+ const std::vector<AudioDevice>& connectedDevices __unused) {
+ return ::android::OK;
+}
+
// static
ndk::ScopedAStatus StreamInStub::createInstance(const SinkMetadata& sinkMetadata,
StreamContext&& context,
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
index 40b46e0..f5af81e 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.cpp
@@ -30,6 +30,7 @@
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::kAcousticEchoCancelerSwImplUUID;
+using aidl::android::hardware::audio::effect::Range;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
@@ -60,8 +61,14 @@
namespace aidl::android::hardware::audio::effect {
const std::string AcousticEchoCancelerSw::kEffectName = "AcousticEchoCancelerSw";
-const AcousticEchoCanceler::Capability AcousticEchoCancelerSw::kCapability = {
- .maxEchoDelayUs = 500, .supportMobileMode = false};
+
+const std::vector<Range::AcousticEchoCancelerRange> AcousticEchoCancelerSw::kRanges = {
+ MAKE_RANGE(AcousticEchoCanceler, echoDelayUs, 0, 500),
+ /* mobile mode not supported, and not settable */
+ MAKE_RANGE(AcousticEchoCanceler, mobileMode, false, false)};
+
+const Capability AcousticEchoCancelerSw::kCapability = {.range = AcousticEchoCancelerSw::kRanges};
+
const Descriptor AcousticEchoCancelerSw::kDescriptor = {
.common = {.id = {.type = kAcousticEchoCancelerTypeUUID,
.uuid = kAcousticEchoCancelerSwImplUUID,
@@ -71,8 +78,7 @@
.volume = Flags::Volume::CTRL},
.name = AcousticEchoCancelerSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::acousticEchoCanceler>(
- AcousticEchoCancelerSw::kCapability)};
+ .capability = AcousticEchoCancelerSw::kCapability};
ndk::ScopedAStatus AcousticEchoCancelerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -87,8 +93,9 @@
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& param = specific.get<Parameter::Specific::acousticEchoCanceler>();
- auto tag = param.getTag();
+ RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+ auto tag = param.getTag();
switch (tag) {
case AcousticEchoCanceler::echoDelayUs: {
RETURN_IF(mContext->setEchoDelay(param.get<AcousticEchoCanceler::echoDelayUs>()) !=
@@ -182,10 +189,6 @@
}
RetCode AcousticEchoCancelerSwContext::setEchoDelay(int echoDelayUs) {
- if (echoDelayUs < 0 || echoDelayUs > AcousticEchoCancelerSw::kCapability.maxEchoDelayUs) {
- LOG(DEBUG) << __func__ << " illegal delay " << echoDelayUs;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
mEchoDelayUs = echoDelayUs;
return RetCode::SUCCESS;
}
diff --git a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
index 5f1bc46..753207d 100644
--- a/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
+++ b/audio/aidl/default/acousticEchoCanceler/AcousticEchoCancelerSw.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <aidl/android/hardware/audio/effect/Range.h>
#include <fmq/AidlMessageQueue.h>
#include <cstdlib>
#include <memory>
@@ -43,8 +44,7 @@
class AcousticEchoCancelerSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const bool kStrengthSupported;
- static const AcousticEchoCanceler::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
AcousticEchoCancelerSw() { LOG(DEBUG) << __func__; }
~AcousticEchoCancelerSw() {
@@ -65,6 +65,7 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
private:
+ static const std::vector<Range::AcousticEchoCancelerRange> kRanges;
std::shared_ptr<AcousticEchoCancelerSwContext> mContext;
ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
Parameter::Specific* specific);
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 6714a7e..0d1731f 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -29,7 +29,8 @@
-->
<libraries>
<library name="aecsw" path="libaecsw.so"/>
- <library name="agcsw" path="libagcsw.so"/>
+ <library name="agc1sw" path="libagc1sw.so"/>
+ <library name="agc2sw" path="libagc2sw.so"/>
<library name="bassboostsw" path="libbassboostsw.so"/>
<library name="bundle" path="libbundleaidl.so"/>
<library name="downmix" path="libdownmixaidl.so"/>
@@ -39,11 +40,13 @@
<library name="loudness_enhancer" path="libloudnessenhanceraidl.so"/>
<library name="nssw" path="libnssw.so"/>
<library name="env_reverbsw" path="libenvreverbsw.so"/>
+ <library name="pre_processing" path="libpreprocessingaidl.so"/>
<library name="preset_reverbsw" path="libpresetreverbsw.so"/>
<library name="reverb" path="libreverbaidl.so"/>
<library name="virtualizersw" path="libvirtualizersw.so"/>
<library name="visualizer" path="libvisualizeraidl.so"/>
<library name="volumesw" path="libvolumesw.so"/>
+ <library name="extensioneffect" path="libextensioneffect.so"/>
</libraries>
<!-- list of effects to load.
@@ -66,8 +69,9 @@
-->
<effects>
- <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
- <effect name="automatic_gain_control" library="agcsw" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
+ <effect name="acoustic_echo_canceler" library="pre_processing" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
+ <effect name="automatic_gain_control_v1" library="pre_processing" uuid="aa8130e0-66fc-11e0-bad0-0002a5d5c51b"/>
+ <effect name="automatic_gain_control_v2" library="pre_processing" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
<effectProxy name="bassboost" uuid="14804144-a5ee-4d24-aa88-0002a5d5c51b">
<libsw library="bassboostsw" uuid="fa8181f2-588b-11ed-9b6a-0242ac120002"/>
<libsw library="bundle" uuid="8631f300-72e2-11df-b57e-0002a5d5c51b"/>
@@ -77,7 +81,7 @@
<effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
<effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
<effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
- <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
+ <effect name="noise_suppression" library="pre_processing" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
<effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
<effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
<effect name="reverb_env_ins" library="reverb" uuid="c7a511a0-a3bb-11df-860e-0002a5d5c51b"/>
@@ -93,6 +97,7 @@
<libsw library="equalizersw" uuid="0bed4300-847d-11df-bb17-0002a5d5c51b"/>
<libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
</effectProxy>
+ <effect name="extensioneffect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002"/>
</effects>
<!-- Audio pre processor configurations.
diff --git a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.cpp b/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.cpp
deleted file mode 100644
index 8c706ef..0000000
--- a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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 <algorithm>
-#include <cstddef>
-#include <memory>
-#define LOG_TAG "AHAL_AutomaticGainControlSw"
-#include <Utils.h>
-#include <unordered_set>
-
-#include <android-base/logging.h>
-#include <fmq/AidlMessageQueue.h>
-
-#include "AutomaticGainControlSw.h"
-
-using aidl::android::hardware::audio::effect::AutomaticGainControlSw;
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::kAutomaticGainControlSwImplUUID;
-using aidl::android::media::audio::common::AudioUuid;
-
-extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
- std::shared_ptr<IEffect>* instanceSpp) {
- if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlSwImplUUID) {
- LOG(ERROR) << __func__ << "uuid not supported";
- return EX_ILLEGAL_ARGUMENT;
- }
- if (instanceSpp) {
- *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlSw>();
- LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
- return EX_NONE;
- } else {
- LOG(ERROR) << __func__ << " invalid input parameter!";
- return EX_ILLEGAL_ARGUMENT;
- }
-}
-
-extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
- if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlSwImplUUID) {
- LOG(ERROR) << __func__ << "uuid not supported";
- return EX_ILLEGAL_ARGUMENT;
- }
- *_aidl_return = AutomaticGainControlSw::kDescriptor;
- return EX_NONE;
-}
-
-namespace aidl::android::hardware::audio::effect {
-
-const std::string AutomaticGainControlSw::kEffectName = "AutomaticGainControlSw";
-const AutomaticGainControl::Capability AutomaticGainControlSw::kCapability = {
- .maxFixedDigitalGainMb = 50000, .maxSaturationMarginMb = 10000};
-const Descriptor AutomaticGainControlSw::kDescriptor = {
- .common = {.id = {.type = kAutomaticGainControlTypeUUID,
- .uuid = kAutomaticGainControlSwImplUUID,
- .proxy = std::nullopt},
- .flags = {.type = Flags::Type::INSERT,
- .insert = Flags::Insert::FIRST,
- .volume = Flags::Volume::CTRL},
- .name = AutomaticGainControlSw::kEffectName,
- .implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::automaticGainControl>(
- AutomaticGainControlSw::kCapability)};
-
-ndk::ScopedAStatus AutomaticGainControlSw::getDescriptor(Descriptor* _aidl_return) {
- LOG(DEBUG) << __func__ << kDescriptor.toString();
- *_aidl_return = kDescriptor;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus AutomaticGainControlSw::setParameterSpecific(
- const Parameter::Specific& specific) {
- RETURN_IF(Parameter::Specific::automaticGainControl != specific.getTag(), EX_ILLEGAL_ARGUMENT,
- "EffectNotSupported");
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
-
- auto& param = specific.get<Parameter::Specific::automaticGainControl>();
- auto tag = param.getTag();
-
- switch (tag) {
- case AutomaticGainControl::fixedDigitalGainMb: {
- RETURN_IF(mContext->setDigitalGain(
- param.get<AutomaticGainControl::fixedDigitalGainMb>()) !=
- RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
- return ndk::ScopedAStatus::ok();
- }
- case AutomaticGainControl::levelEstimator: {
- RETURN_IF(
- mContext->setLevelEstimator(
- param.get<AutomaticGainControl::levelEstimator>()) != RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
- return ndk::ScopedAStatus::ok();
- }
- case AutomaticGainControl::saturationMarginMb: {
- RETURN_IF(mContext->setSaturationMargin(
- param.get<AutomaticGainControl::saturationMarginMb>()) !=
- RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
- return ndk::ScopedAStatus::ok();
- }
- default: {
- LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
- }
- }
-}
-
-ndk::ScopedAStatus AutomaticGainControlSw::getParameterSpecific(const Parameter::Id& id,
- Parameter::Specific* specific) {
- auto tag = id.getTag();
- RETURN_IF(Parameter::Id::automaticGainControlTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
- auto specificId = id.get<Parameter::Id::automaticGainControlTag>();
- auto specificIdTag = specificId.getTag();
- switch (specificIdTag) {
- case AutomaticGainControl::Id::commonTag:
- return getParameterAutomaticGainControl(
- specificId.get<AutomaticGainControl::Id::commonTag>(), specific);
- default:
- LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
- }
-}
-
-ndk::ScopedAStatus AutomaticGainControlSw::getParameterAutomaticGainControl(
- const AutomaticGainControl::Tag& tag, Parameter::Specific* specific) {
- RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
- AutomaticGainControl param;
- switch (tag) {
- case AutomaticGainControl::fixedDigitalGainMb: {
- param.set<AutomaticGainControl::fixedDigitalGainMb>(mContext->getDigitalGain());
- break;
- }
- case AutomaticGainControl::levelEstimator: {
- param.set<AutomaticGainControl::levelEstimator>(mContext->getLevelEstimator());
- break;
- }
- case AutomaticGainControl::saturationMarginMb: {
- param.set<AutomaticGainControl::saturationMarginMb>(mContext->getSaturationMargin());
- break;
- }
- default: {
- LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
- }
- }
-
- specific->set<Parameter::Specific::automaticGainControl>(param);
- return ndk::ScopedAStatus::ok();
-}
-
-std::shared_ptr<EffectContext> AutomaticGainControlSw::createContext(
- const Parameter::Common& common) {
- if (mContext) {
- LOG(DEBUG) << __func__ << " context already exist";
- } else {
- mContext = std::make_shared<AutomaticGainControlSwContext>(1 /* statusFmqDepth */, common);
- }
- return mContext;
-}
-
-std::shared_ptr<EffectContext> AutomaticGainControlSw::getContext() {
- return mContext;
-}
-
-RetCode AutomaticGainControlSw::releaseContext() {
- if (mContext) {
- mContext.reset();
- }
- return RetCode::SUCCESS;
-}
-
-// Processing method running in EffectWorker thread.
-IEffect::Status AutomaticGainControlSw::effectProcessImpl(float* in, float* out, int samples) {
- // TODO: get data buffer and process.
- LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
- for (int i = 0; i < samples; i++) {
- *out++ = *in++;
- }
- return {STATUS_OK, samples, samples};
-}
-
-RetCode AutomaticGainControlSwContext::setDigitalGain(int gain) {
- if (gain < 0 || gain > AutomaticGainControlSw::kCapability.maxFixedDigitalGainMb) {
- LOG(DEBUG) << __func__ << " illegal digital gain " << gain;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- mDigitalGain = gain;
- return RetCode::SUCCESS;
-}
-
-int AutomaticGainControlSwContext::getDigitalGain() {
- return mDigitalGain;
-}
-
-RetCode AutomaticGainControlSwContext::setLevelEstimator(
- AutomaticGainControl::LevelEstimator levelEstimator) {
- mLevelEstimator = levelEstimator;
- return RetCode::SUCCESS;
-}
-
-AutomaticGainControl::LevelEstimator AutomaticGainControlSwContext::getLevelEstimator() {
- return mLevelEstimator;
-}
-
-RetCode AutomaticGainControlSwContext::setSaturationMargin(int margin) {
- if (margin < 0 || margin > AutomaticGainControlSw::kCapability.maxSaturationMarginMb) {
- LOG(DEBUG) << __func__ << " illegal saturationMargin " << margin;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- mSaturationMargin = margin;
- return RetCode::SUCCESS;
-}
-
-int AutomaticGainControlSwContext::getSaturationMargin() {
- return mSaturationMargin;
-}
-
-} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/Android.bp b/audio/aidl/default/automaticGainControlV1/Android.bp
similarity index 91%
copy from audio/aidl/default/automaticGainControl/Android.bp
copy to audio/aidl/default/automaticGainControlV1/Android.bp
index 17d6416..4ae8e63 100644
--- a/audio/aidl/default/automaticGainControl/Android.bp
+++ b/audio/aidl/default/automaticGainControlV1/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,14 +24,14 @@
}
cc_library_shared {
- name: "libagcsw",
+ name: "libagc1sw",
defaults: [
"aidlaudioeffectservice_defaults",
"latest_android_media_audio_common_types_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
- "AutomaticGainControlSw.cpp",
+ "AutomaticGainControlV1Sw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
new file mode 100644
index 0000000..39290b4
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.cpp
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2023 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 "AHAL_AutomaticGainControlV1Sw"
+
+#include <android-base/logging.h>
+
+#include "AutomaticGainControlV1Sw.h"
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV1Sw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kAutomaticGainControlV1SwImplUUID;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlV1SwImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV1Sw>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlV1SwImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = AutomaticGainControlV1Sw::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AutomaticGainControlV1Sw::kEffectName = "AutomaticGainControlV1Sw";
+
+const std::vector<Range::AutomaticGainControlV1Range> AutomaticGainControlV1Sw::kRanges = {
+ MAKE_RANGE(AutomaticGainControlV1, targetPeakLevelDbFs, -3100, 0),
+ MAKE_RANGE(AutomaticGainControlV1, maxCompressionGainDb, 0, 9000)};
+
+const Capability AutomaticGainControlV1Sw::kCapability = {
+ .range = AutomaticGainControlV1Sw::kRanges};
+
+const Descriptor AutomaticGainControlV1Sw::kDescriptor = {
+ .common = {.id = {.type = kAutomaticGainControlV1TypeUUID,
+ .uuid = kAutomaticGainControlV1SwImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .name = AutomaticGainControlV1Sw::kEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = AutomaticGainControlV1Sw::kCapability};
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getDescriptor(Descriptor* _aidl_return) {
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::setParameterSpecific(
+ const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::automaticGainControlV1 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& param = specific.get<Parameter::Specific::automaticGainControlV1>();
+ RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+ auto tag = param.getTag();
+ switch (tag) {
+ case AutomaticGainControlV1::targetPeakLevelDbFs: {
+ RETURN_IF(mContext->setTargetPeakLevel(
+ param.get<AutomaticGainControlV1::targetPeakLevelDbFs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "targetPeakLevelNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV1::maxCompressionGainDb: {
+ RETURN_IF(mContext->setMaxCompressionGain(
+ param.get<AutomaticGainControlV1::maxCompressionGainDb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "maxCompressionGainNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV1::enableLimiter: {
+ RETURN_IF(
+ mContext->setEnableLimiter(
+ param.get<AutomaticGainControlV1::enableLimiter>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "enableLimiterNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::automaticGainControlV1Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto specificId = id.get<Parameter::Id::automaticGainControlV1Tag>();
+ auto specificIdTag = specificId.getTag();
+ switch (specificIdTag) {
+ case AutomaticGainControlV1::Id::commonTag:
+ return getParameterAutomaticGainControlV1(
+ specificId.get<AutomaticGainControlV1::Id::commonTag>(), specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV1Sw::getParameterAutomaticGainControlV1(
+ const AutomaticGainControlV1::Tag& tag, Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ AutomaticGainControlV1 param;
+ switch (tag) {
+ case AutomaticGainControlV1::targetPeakLevelDbFs: {
+ param.set<AutomaticGainControlV1::targetPeakLevelDbFs>(mContext->getTargetPeakLevel());
+ break;
+ }
+ case AutomaticGainControlV1::maxCompressionGainDb: {
+ param.set<AutomaticGainControlV1::maxCompressionGainDb>(
+ mContext->getMaxCompressionGain());
+ break;
+ }
+ case AutomaticGainControlV1::enableLimiter: {
+ param.set<AutomaticGainControlV1::enableLimiter>(mContext->getEnableLimiter());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV1TagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::automaticGainControlV1>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::createContext(
+ const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ mContext =
+ std::make_shared<AutomaticGainControlV1SwContext>(1 /* statusFmqDepth */, common);
+ }
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV1Sw::getContext() {
+ return mContext;
+}
+
+RetCode AutomaticGainControlV1Sw::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AutomaticGainControlV1Sw::effectProcessImpl(float* in, float* out, int samples) {
+ // TODO: get data buffer and process.
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+ for (int i = 0; i < samples; i++) {
+ *out++ = *in++;
+ }
+ return {STATUS_OK, samples, samples};
+}
+
+RetCode AutomaticGainControlV1SwContext::setTargetPeakLevel(int targetPeakLevel) {
+ mTargetPeakLevel = targetPeakLevel;
+ return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV1SwContext::getTargetPeakLevel() {
+ return mTargetPeakLevel;
+}
+
+RetCode AutomaticGainControlV1SwContext::setMaxCompressionGain(int maxCompressionGain) {
+ mMaxCompressionGain = maxCompressionGain;
+ return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV1SwContext::getMaxCompressionGain() {
+ return mMaxCompressionGain;
+}
+
+RetCode AutomaticGainControlV1SwContext::setEnableLimiter(bool enableLimiter) {
+ mEnableLimiter = enableLimiter;
+ return RetCode::SUCCESS;
+}
+
+bool AutomaticGainControlV1SwContext::getEnableLimiter() {
+ return mEnableLimiter;
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
new file mode 100644
index 0000000..6ba7328
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV1/AutomaticGainControlV1Sw.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 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 "effect-impl/EffectImpl.h"
+#include "effect-impl/EffectUUID.h"
+
+namespace aidl::android::hardware::audio::effect {
+
+class AutomaticGainControlV1SwContext final : public EffectContext {
+ public:
+ AutomaticGainControlV1SwContext(int statusDepth, const Parameter::Common& common)
+ : EffectContext(statusDepth, common) {
+ LOG(DEBUG) << __func__;
+ }
+
+ RetCode setTargetPeakLevel(int targetPeakLevel);
+ int getTargetPeakLevel();
+ RetCode setMaxCompressionGain(int maxCompressionGainDb);
+ int getMaxCompressionGain();
+ RetCode setEnableLimiter(bool enableLimiter);
+ bool getEnableLimiter();
+
+ private:
+ int mTargetPeakLevel = 0;
+ int mMaxCompressionGain = 0;
+ bool mEnableLimiter = false;
+};
+
+class AutomaticGainControlV1Sw final : public EffectImpl {
+ public:
+ static const std::string kEffectName;
+ static const bool kStrengthSupported;
+ static const Capability kCapability;
+ static const Descriptor kDescriptor;
+ AutomaticGainControlV1Sw() { LOG(DEBUG) << __func__; }
+ ~AutomaticGainControlV1Sw() {
+ cleanUp();
+ LOG(DEBUG) << __func__;
+ }
+
+ ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+ ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+ ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) override;
+
+ std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+ std::shared_ptr<EffectContext> getContext() override;
+ RetCode releaseContext() override;
+
+ std::string getEffectName() override { return kEffectName; };
+ IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+ private:
+ static const std::vector<Range::AutomaticGainControlV1Range> kRanges;
+ std::shared_ptr<AutomaticGainControlV1SwContext> mContext;
+ ndk::ScopedAStatus getParameterAutomaticGainControlV1(const AutomaticGainControlV1::Tag& tag,
+ Parameter::Specific* specific);
+};
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/Android.bp b/audio/aidl/default/automaticGainControlV2/Android.bp
similarity index 95%
rename from audio/aidl/default/automaticGainControl/Android.bp
rename to audio/aidl/default/automaticGainControlV2/Android.bp
index 17d6416..631cf58 100644
--- a/audio/aidl/default/automaticGainControl/Android.bp
+++ b/audio/aidl/default/automaticGainControlV2/Android.bp
@@ -24,14 +24,14 @@
}
cc_library_shared {
- name: "libagcsw",
+ name: "libagc2sw",
defaults: [
"aidlaudioeffectservice_defaults",
"latest_android_media_audio_common_types_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
- "AutomaticGainControlSw.cpp",
+ "AutomaticGainControlV2Sw.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
diff --git a/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
new file mode 100644
index 0000000..8441f22
--- /dev/null
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <algorithm>
+#include <cstddef>
+#include <memory>
+#define LOG_TAG "AHAL_AutomaticGainControlV2Sw"
+#include <Utils.h>
+#include <unordered_set>
+
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "AutomaticGainControlV2Sw.h"
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV2Sw;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kAutomaticGainControlV2SwImplUUID;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlV2SwImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlV2Sw>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlV2SwImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = AutomaticGainControlV2Sw::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string AutomaticGainControlV2Sw::kEffectName = "AutomaticGainControlV2Sw";
+
+const std::vector<Range::AutomaticGainControlV2Range> AutomaticGainControlV2Sw::kRanges = {
+ MAKE_RANGE(AutomaticGainControlV2, fixedDigitalGainMb, 0, 50000),
+ MAKE_RANGE(AutomaticGainControlV2, saturationMarginMb, 0, 10000)};
+
+const Capability AutomaticGainControlV2Sw::kCapability = {
+ .range = AutomaticGainControlV2Sw::kRanges};
+
+const Descriptor AutomaticGainControlV2Sw::kDescriptor = {
+ .common = {.id = {.type = kAutomaticGainControlV2TypeUUID,
+ .uuid = kAutomaticGainControlV2SwImplUUID,
+ .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .name = AutomaticGainControlV2Sw::kEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = AutomaticGainControlV2Sw::kCapability};
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getDescriptor(Descriptor* _aidl_return) {
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::setParameterSpecific(
+ const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::automaticGainControlV2 != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& param = specific.get<Parameter::Specific::automaticGainControlV2>();
+ RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+ auto tag = param.getTag();
+ switch (tag) {
+ case AutomaticGainControlV2::fixedDigitalGainMb: {
+ RETURN_IF(mContext->setDigitalGain(
+ param.get<AutomaticGainControlV2::fixedDigitalGainMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV2::levelEstimator: {
+ RETURN_IF(mContext->setLevelEstimator(
+ param.get<AutomaticGainControlV2::levelEstimator>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case AutomaticGainControlV2::saturationMarginMb: {
+ RETURN_IF(mContext->setSaturationMargin(
+ param.get<AutomaticGainControlV2::saturationMarginMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+ }
+ }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::automaticGainControlV2Tag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto specificId = id.get<Parameter::Id::automaticGainControlV2Tag>();
+ auto specificIdTag = specificId.getTag();
+ switch (specificIdTag) {
+ case AutomaticGainControlV2::Id::commonTag:
+ return getParameterAutomaticGainControlV2(
+ specificId.get<AutomaticGainControlV2::Id::commonTag>(), specific);
+ default:
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+ }
+}
+
+ndk::ScopedAStatus AutomaticGainControlV2Sw::getParameterAutomaticGainControlV2(
+ const AutomaticGainControlV2::Tag& tag, Parameter::Specific* specific) {
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+ AutomaticGainControlV2 param;
+ switch (tag) {
+ case AutomaticGainControlV2::fixedDigitalGainMb: {
+ param.set<AutomaticGainControlV2::fixedDigitalGainMb>(mContext->getDigitalGain());
+ break;
+ }
+ case AutomaticGainControlV2::levelEstimator: {
+ param.set<AutomaticGainControlV2::levelEstimator>(mContext->getLevelEstimator());
+ break;
+ }
+ case AutomaticGainControlV2::saturationMarginMb: {
+ param.set<AutomaticGainControlV2::saturationMarginMb>(mContext->getSaturationMargin());
+ break;
+ }
+ default: {
+ LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "AutomaticGainControlV2TagNotSupported");
+ }
+ }
+
+ specific->set<Parameter::Specific::automaticGainControlV2>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::createContext(
+ const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ mContext =
+ std::make_shared<AutomaticGainControlV2SwContext>(1 /* statusFmqDepth */, common);
+ }
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> AutomaticGainControlV2Sw::getContext() {
+ return mContext;
+}
+
+RetCode AutomaticGainControlV2Sw::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status AutomaticGainControlV2Sw::effectProcessImpl(float* in, float* out, int samples) {
+ // TODO: get data buffer and process.
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+ for (int i = 0; i < samples; i++) {
+ *out++ = *in++;
+ }
+ return {STATUS_OK, samples, samples};
+}
+
+RetCode AutomaticGainControlV2SwContext::setDigitalGain(int gain) {
+ mDigitalGain = gain;
+ return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV2SwContext::getDigitalGain() {
+ return mDigitalGain;
+}
+
+RetCode AutomaticGainControlV2SwContext::setLevelEstimator(
+ AutomaticGainControlV2::LevelEstimator levelEstimator) {
+ mLevelEstimator = levelEstimator;
+ return RetCode::SUCCESS;
+}
+
+AutomaticGainControlV2::LevelEstimator AutomaticGainControlV2SwContext::getLevelEstimator() {
+ return mLevelEstimator;
+}
+
+RetCode AutomaticGainControlV2SwContext::setSaturationMargin(int margin) {
+ mSaturationMargin = margin;
+ return RetCode::SUCCESS;
+}
+
+int AutomaticGainControlV2SwContext::getSaturationMargin() {
+ return mSaturationMargin;
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
similarity index 68%
rename from audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
rename to audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
index 2724835..0b50f4d 100644
--- a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
+++ b/audio/aidl/default/automaticGainControlV2/AutomaticGainControlV2Sw.h
@@ -26,35 +26,35 @@
namespace aidl::android::hardware::audio::effect {
-class AutomaticGainControlSwContext final : public EffectContext {
+class AutomaticGainControlV2SwContext final : public EffectContext {
public:
- AutomaticGainControlSwContext(int statusDepth, const Parameter::Common& common)
+ AutomaticGainControlV2SwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
RetCode setDigitalGain(int gain);
int getDigitalGain();
- RetCode setLevelEstimator(AutomaticGainControl::LevelEstimator levelEstimator);
- AutomaticGainControl::LevelEstimator getLevelEstimator();
+ RetCode setLevelEstimator(AutomaticGainControlV2::LevelEstimator levelEstimator);
+ AutomaticGainControlV2::LevelEstimator getLevelEstimator();
RetCode setSaturationMargin(int margin);
int getSaturationMargin();
private:
int mDigitalGain = 0;
- AutomaticGainControl::LevelEstimator mLevelEstimator =
- AutomaticGainControl::LevelEstimator::RMS;
+ AutomaticGainControlV2::LevelEstimator mLevelEstimator =
+ AutomaticGainControlV2::LevelEstimator::RMS;
int mSaturationMargin = 0;
};
-class AutomaticGainControlSw final : public EffectImpl {
+class AutomaticGainControlV2Sw final : public EffectImpl {
public:
static const std::string kEffectName;
static const bool kStrengthSupported;
- static const AutomaticGainControl::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
- AutomaticGainControlSw() { LOG(DEBUG) << __func__; }
- ~AutomaticGainControlSw() {
+ AutomaticGainControlV2Sw() { LOG(DEBUG) << __func__; }
+ ~AutomaticGainControlV2Sw() {
cleanUp();
LOG(DEBUG) << __func__;
}
@@ -72,8 +72,9 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
private:
- std::shared_ptr<AutomaticGainControlSwContext> mContext;
- ndk::ScopedAStatus getParameterAutomaticGainControl(const AutomaticGainControl::Tag& tag,
- Parameter::Specific* specific);
+ static const std::vector<Range::AutomaticGainControlV2Range> kRanges;
+ std::shared_ptr<AutomaticGainControlV2SwContext> mContext;
+ ndk::ScopedAStatus getParameterAutomaticGainControlV2(const AutomaticGainControlV2::Tag& tag,
+ Parameter::Specific* specific);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 0c7ebe1..e50f0a2 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -61,9 +61,10 @@
namespace aidl::android::hardware::audio::effect {
const std::string BassBoostSw::kEffectName = "BassBoostSw";
-const bool BassBoostSw::kStrengthSupported = true;
-const BassBoost::Capability BassBoostSw::kCapability = {.maxStrengthPm = 1000,
- .strengthSupported = kStrengthSupported};
+
+const std::vector<Range::BassBoostRange> BassBoostSw::kRanges = {
+ MAKE_RANGE(BassBoost, strengthPm, 0, 1000)};
+const Capability BassBoostSw::kCapability = {.range = {BassBoostSw::kRanges}};
const Descriptor BassBoostSw::kDescriptor = {
.common = {.id = {.type = kBassBoostTypeUUID,
.uuid = kBassBoostSwImplUUID,
@@ -73,7 +74,7 @@
.volume = Flags::Volume::CTRL},
.name = BassBoostSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::bassBoost>(BassBoostSw::kCapability)};
+ .capability = BassBoostSw::kCapability};
ndk::ScopedAStatus BassBoostSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -87,15 +88,14 @@
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& bbParam = specific.get<Parameter::Specific::bassBoost>();
+ RETURN_IF(!inRange(bbParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = bbParam.getTag();
switch (tag) {
case BassBoost::strengthPm: {
- RETURN_IF(!kStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");
-
- RETURN_IF(mContext->setBbStrengthPm(bbParam.get<BassBoost::strengthPm>()) !=
- RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "strengthPmNotSupported");
+ const auto strength = bbParam.get<BassBoost::strengthPm>();
+ RETURN_IF(mContext->setBbStrengthPm(strength) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
+ "strengthPmNotSupported");
return ndk::ScopedAStatus::ok();
}
default: {
@@ -173,11 +173,6 @@
}
RetCode BassBoostSwContext::setBbStrengthPm(int strength) {
- if (strength < 0 || strength > BassBoostSw::kCapability.maxStrengthPm) {
- LOG(ERROR) << __func__ << " invalid strength: " << strength;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new strength
mStrength = strength;
return RetCode::SUCCESS;
}
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 65c01c8..8d183dd 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -43,8 +43,7 @@
class BassBoostSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const bool kStrengthSupported;
- static const BassBoost::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
BassBoostSw() { LOG(DEBUG) << __func__; }
~BassBoostSw() {
@@ -65,6 +64,7 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
private:
+ static const std::vector<Range::BassBoostRange> kRanges;
std::shared_ptr<BassBoostSwContext> mContext;
ndk::ScopedAStatus getParameterBassBoost(const BassBoost::Tag& tag,
Parameter::Specific* specific);
diff --git a/audio/aidl/default/downmix/DownmixSw.cpp b/audio/aidl/default/downmix/DownmixSw.cpp
index 7bb958d..0af95d0 100644
--- a/audio/aidl/default/downmix/DownmixSw.cpp
+++ b/audio/aidl/default/downmix/DownmixSw.cpp
@@ -60,17 +60,14 @@
namespace aidl::android::hardware::audio::effect {
const std::string DownmixSw::kEffectName = "DownmixSw";
-const Downmix::Capability DownmixSw::kCapability;
const Descriptor DownmixSw::kDescriptor = {
- .common = {.id = {.type = kDownmixTypeUUID,
- .uuid = kDownmixSwImplUUID,
- .proxy = std::nullopt},
- .flags = {.type = Flags::Type::INSERT,
- .insert = Flags::Insert::FIRST,
- .volume = Flags::Volume::CTRL},
- .name = kEffectName,
- .implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::downmix>(kCapability)};
+ .common = {
+ .id = {.type = kDownmixTypeUUID, .uuid = kDownmixSwImplUUID, .proxy = std::nullopt},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .name = kEffectName,
+ .implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus DownmixSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
diff --git a/audio/aidl/default/downmix/DownmixSw.h b/audio/aidl/default/downmix/DownmixSw.h
index 51546c1..37c978b 100644
--- a/audio/aidl/default/downmix/DownmixSw.h
+++ b/audio/aidl/default/downmix/DownmixSw.h
@@ -47,7 +47,7 @@
class DownmixSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const Downmix::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
DownmixSw() { LOG(DEBUG) << __func__; }
~DownmixSw() {
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
index 0ffbaa1..da6d0c6 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.cpp
@@ -61,8 +61,33 @@
namespace aidl::android::hardware::audio::effect {
const std::string DynamicsProcessingSw::kEffectName = "DynamicsProcessingSw";
-const DynamicsProcessing::Capability DynamicsProcessingSw::kCapability = {.minCutOffFreq = 220,
- .maxCutOffFreq = 20000};
+const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMin =
+ DynamicsProcessing::EqBandConfig({.channel = 0,
+ .band = 0,
+ .enable = false,
+ .cutoffFrequencyHz = 220,
+ .gainDb = std::numeric_limits<float>::min()});
+const DynamicsProcessing::EqBandConfig DynamicsProcessingSw::kEqBandConfigMax =
+ DynamicsProcessing::EqBandConfig({.channel = std::numeric_limits<int>::max(),
+ .band = std::numeric_limits<int>::max(),
+ .enable = true,
+ .cutoffFrequencyHz = 20000,
+ .gainDb = std::numeric_limits<float>::max()});
+const Range::DynamicsProcessingRange DynamicsProcessingSw::kPreEqBandRange = {
+ .min = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ {DynamicsProcessingSw::kEqBandConfigMin}),
+ .max = DynamicsProcessing::make<DynamicsProcessing::preEqBand>(
+ {DynamicsProcessingSw::kEqBandConfigMax})};
+const Range::DynamicsProcessingRange DynamicsProcessingSw::kPostEqBandRange = {
+ .min = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+ {DynamicsProcessingSw::kEqBandConfigMin}),
+ .max = DynamicsProcessing::make<DynamicsProcessing::postEqBand>(
+ {DynamicsProcessingSw::kEqBandConfigMax})};
+
+const std::vector<Range::DynamicsProcessingRange> DynamicsProcessingSw::kRanges = {
+ DynamicsProcessingSw::kPreEqBandRange, DynamicsProcessingSw::kPostEqBandRange};
+const Capability DynamicsProcessingSw::kCapability = {.range = DynamicsProcessingSw::kRanges};
+
const Descriptor DynamicsProcessingSw::kDescriptor = {
.common = {.id = {.type = kDynamicsProcessingTypeUUID,
.uuid = kDynamicsProcessingSwImplUUID,
@@ -72,8 +97,7 @@
.volume = Flags::Volume::CTRL},
.name = DynamicsProcessingSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::dynamicsProcessing>(
- DynamicsProcessingSw::kCapability)};
+ .capability = DynamicsProcessingSw::kCapability};
ndk::ScopedAStatus DynamicsProcessingSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -341,7 +365,6 @@
LOG(WARNING) << __func__ << " skip invalid band " << cfg.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
continue;
- ;
}
targetCfgs[cfg.channel * stage.bandCount + cfg.band] = cfg;
}
@@ -380,7 +403,6 @@
LOG(WARNING) << __func__ << " skip invalid band " << it.toString();
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
continue;
- ;
}
mMbcChBands[it.channel * bandCount + it.band] = it;
}
@@ -462,11 +484,6 @@
return ret;
}
-bool DynamicsProcessingSwContext::validateCutoffFrequency(float freq) {
- return freq >= DynamicsProcessingSw::kCapability.minCutOffFreq &&
- freq <= DynamicsProcessingSw::kCapability.maxCutOffFreq;
-}
-
bool DynamicsProcessingSwContext::validateStageEnablement(
const DynamicsProcessing::StageEnablement& enablement) {
return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
@@ -484,7 +501,7 @@
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
return band.channel >= 0 && band.channel < maxChannel &&
(size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
- band.band >= 0 && band.band < maxBand && validateCutoffFrequency(band.cutoffFrequencyHz);
+ band.band >= 0 && band.band < maxBand;
}
bool DynamicsProcessingSwContext::validateMbcBandConfig(
@@ -492,8 +509,7 @@
const std::vector<DynamicsProcessing::ChannelConfig>& channelConfig) {
return band.channel >= 0 && band.channel < maxChannel &&
(size_t)band.channel < channelConfig.size() && channelConfig[band.channel].enable &&
- band.band >= 0 && band.band < maxBand &&
- validateCutoffFrequency(band.cutoffFrequencyHz) && band.attackTimeMs >= 0 &&
+ band.band >= 0 && band.band < maxBand && band.attackTimeMs >= 0 &&
band.releaseTimeMs >= 0 && band.ratio >= 0 && band.thresholdDb <= 0 &&
band.kneeWidthDb <= 0 && band.noiseGateThresholdDb <= 0 && band.expanderRatio >= 0;
}
diff --git a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
index e336df7..3e14cce 100644
--- a/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
+++ b/audio/aidl/default/dynamicProcessing/DynamicsProcessingSw.h
@@ -86,8 +86,6 @@
std::vector<DynamicsProcessing::EqBandConfig> mPreEqChBands;
std::vector<DynamicsProcessing::EqBandConfig> mPostEqChBands;
std::vector<DynamicsProcessing::MbcBandConfig> mMbcChBands;
-
- bool validateCutoffFrequency(float freq);
bool validateStageEnablement(const DynamicsProcessing::StageEnablement& enablement);
bool validateEngineConfig(const DynamicsProcessing::EngineArchitecture& engine);
bool validateEqBandConfig(const DynamicsProcessing::EqBandConfig& band, int maxChannel,
@@ -104,7 +102,7 @@
class DynamicsProcessingSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const DynamicsProcessing::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
DynamicsProcessingSw() { LOG(DEBUG) << __func__; }
~DynamicsProcessingSw() {
@@ -125,6 +123,11 @@
std::string getEffectName() override { return kEffectName; };
private:
+ static const DynamicsProcessing::EqBandConfig kEqBandConfigMin;
+ static const DynamicsProcessing::EqBandConfig kEqBandConfigMax;
+ static const Range::DynamicsProcessingRange kPreEqBandRange;
+ static const Range::DynamicsProcessingRange kPostEqBandRange;
+ static const std::vector<Range::DynamicsProcessingRange> kRanges;
std::shared_ptr<DynamicsProcessingSwContext> mContext;
ndk::ScopedAStatus getParameterDynamicsProcessing(const DynamicsProcessing::Tag& tag,
Parameter::Specific* specific);
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.cpp b/audio/aidl/default/envReverb/EnvReverbSw.cpp
index 905dba4..15373fe 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.cpp
+++ b/audio/aidl/default/envReverb/EnvReverbSw.cpp
@@ -60,18 +60,22 @@
namespace aidl::android::hardware::audio::effect {
const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
-const EnvironmentalReverb::Capability EnvReverbSw::kCapability = {.minRoomLevelMb = -6000,
- .maxRoomLevelMb = 0,
- .minRoomHfLevelMb = -4000,
- .maxRoomHfLevelMb = 0,
- .maxDecayTimeMs = 7000,
- .minDecayHfRatioPm = 100,
- .maxDecayHfRatioPm = 2000,
- .minLevelMb = -6000,
- .maxLevelMb = 0,
- .maxDelayMs = 65,
- .maxDiffusionPm = 1000,
- .maxDensityPm = 1000};
+
+const std::vector<Range::EnvironmentalReverbRange> EnvReverbSw::kRanges = {
+ MAKE_RANGE(EnvironmentalReverb, roomLevelMb, -6000, 0),
+ MAKE_RANGE(EnvironmentalReverb, roomHfLevelMb, -4000, 0),
+ MAKE_RANGE(EnvironmentalReverb, decayTimeMs, 0, 7000),
+ MAKE_RANGE(EnvironmentalReverb, decayHfRatioPm, 100, 2000),
+ MAKE_RANGE(EnvironmentalReverb, reflectionsLevelMb, -6000, 0),
+ MAKE_RANGE(EnvironmentalReverb, reflectionsDelayMs, 0, 65),
+ MAKE_RANGE(EnvironmentalReverb, levelMb, -6000, 0),
+ MAKE_RANGE(EnvironmentalReverb, delayMs, 0, 65),
+ MAKE_RANGE(EnvironmentalReverb, diffusionPm, 0, 1000),
+ MAKE_RANGE(EnvironmentalReverb, densityPm, 0, 1000)};
+
+const Capability EnvReverbSw::kCapability = {
+ .range = Range::make<Range::environmentalReverb>(EnvReverbSw::kRanges)};
+
const Descriptor EnvReverbSw::kDescriptor = {
.common = {.id = {.type = kEnvReverbTypeUUID,
.uuid = kEnvReverbSwImplUUID,
@@ -81,7 +85,7 @@
.volume = Flags::Volume::CTRL},
.name = EnvReverbSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::environmentalReverb>(EnvReverbSw::kCapability)};
+ .capability = EnvReverbSw::kCapability};
ndk::ScopedAStatus EnvReverbSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -94,8 +98,8 @@
"EffectNotSupported");
auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
+ RETURN_IF(!inRange(erParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = erParam.getTag();
-
switch (tag) {
case EnvironmentalReverb::roomLevelMb: {
RETURN_IF(mContext->setErRoomLevel(erParam.get<EnvironmentalReverb::roomLevelMb>()) !=
@@ -123,6 +127,20 @@
EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
return ndk::ScopedAStatus::ok();
}
+ case EnvironmentalReverb::reflectionsLevelMb: {
+ RETURN_IF(mContext->setErReflectionsLevel(
+ erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case EnvironmentalReverb::reflectionsDelayMs: {
+ RETURN_IF(mContext->setErReflectionsDelay(
+ erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
+ return ndk::ScopedAStatus::ok();
+ }
case EnvironmentalReverb::levelMb: {
RETURN_IF(mContext->setErLevel(erParam.get<EnvironmentalReverb::levelMb>()) !=
RetCode::SUCCESS,
@@ -199,6 +217,14 @@
erParam.set<EnvironmentalReverb::decayHfRatioPm>(mContext->getErDecayHfRatio());
break;
}
+ case EnvironmentalReverb::reflectionsLevelMb: {
+ erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getErReflectionsLevel());
+ break;
+ }
+ case EnvironmentalReverb::reflectionsDelayMs: {
+ erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getErReflectionsDelay());
+ break;
+ }
case EnvironmentalReverb::levelMb: {
erParam.set<EnvironmentalReverb::levelMb>(mContext->getErLevel());
break;
@@ -262,85 +288,41 @@
}
RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
- if (roomLevel < EnvReverbSw::kCapability.minRoomLevelMb ||
- roomLevel > EnvReverbSw::kCapability.maxRoomLevelMb) {
- LOG(ERROR) << __func__ << " invalid roomLevel: " << roomLevel;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new room level
mRoomLevel = roomLevel;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
- if (roomHfLevel < EnvReverbSw::kCapability.minRoomHfLevelMb ||
- roomHfLevel > EnvReverbSw::kCapability.maxRoomHfLevelMb) {
- LOG(ERROR) << __func__ << " invalid roomHfLevel: " << roomHfLevel;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new room HF level
mRoomHfLevel = roomHfLevel;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
- if (decayTime < 0 || decayTime > EnvReverbSw::kCapability.maxDecayTimeMs) {
- LOG(ERROR) << __func__ << " invalid decayTime: " << decayTime;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new decay time
mDecayTime = decayTime;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
- if (decayHfRatio < EnvReverbSw::kCapability.minDecayHfRatioPm ||
- decayHfRatio > EnvReverbSw::kCapability.maxDecayHfRatioPm) {
- LOG(ERROR) << __func__ << " invalid decayHfRatio: " << decayHfRatio;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new decay HF ratio
mDecayHfRatio = decayHfRatio;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErLevel(int level) {
- if (level < EnvReverbSw::kCapability.minLevelMb ||
- level > EnvReverbSw::kCapability.maxLevelMb) {
- LOG(ERROR) << __func__ << " invalid level: " << level;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new level
mLevel = level;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDelay(int delay) {
- if (delay < 0 || delay > EnvReverbSw::kCapability.maxDelayMs) {
- LOG(ERROR) << __func__ << " invalid delay: " << delay;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new delay
mDelay = delay;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
- if (diffusion < 0 || diffusion > EnvReverbSw::kCapability.maxDiffusionPm) {
- LOG(ERROR) << __func__ << " invalid diffusion: " << diffusion;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new diffusion
mDiffusion = diffusion;
return RetCode::SUCCESS;
}
RetCode EnvReverbSwContext::setErDensity(int density) {
- if (density < 0 || density > EnvReverbSw::kCapability.maxDensityPm) {
- LOG(ERROR) << __func__ << " invalid density: " << density;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new density
mDensity = density;
return RetCode::SUCCESS;
}
diff --git a/audio/aidl/default/envReverb/EnvReverbSw.h b/audio/aidl/default/envReverb/EnvReverbSw.h
index 77f384e..dd2cf5d 100644
--- a/audio/aidl/default/envReverb/EnvReverbSw.h
+++ b/audio/aidl/default/envReverb/EnvReverbSw.h
@@ -58,12 +58,23 @@
int getErDensity() const { return mDensity; }
RetCode setErBypass(bool bypass) {
- // TODO : Add implementation to apply new bypass
mBypass = bypass;
return RetCode::SUCCESS;
}
bool getErBypass() const { return mBypass; }
+ RetCode setErReflectionsDelay(int delay) {
+ mReflectionsDelayMs = delay;
+ return RetCode::SUCCESS;
+ }
+ bool getErReflectionsDelay() const { return mReflectionsDelayMs; }
+
+ RetCode setErReflectionsLevel(int level) {
+ mReflectionsLevelMb = level;
+ return RetCode::SUCCESS;
+ }
+ bool getErReflectionsLevel() const { return mReflectionsLevelMb; }
+
private:
int mRoomLevel = -6000; // Default room level
int mRoomHfLevel = 0; // Default room hf level
@@ -71,6 +82,8 @@
int mDecayHfRatio = 500; // Default decay hf ratio
int mLevel = -6000; // Default level
int mDelay = 40; // Default delay
+ int mReflectionsLevelMb = 0;
+ int mReflectionsDelayMs = 0;
int mDiffusion = 1000; // Default diffusion
int mDensity = 1000; // Default density
bool mBypass = false; // Default bypass
@@ -79,7 +92,7 @@
class EnvReverbSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const EnvironmentalReverb::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
EnvReverbSw() { LOG(DEBUG) << __func__; }
~EnvReverbSw() {
@@ -100,6 +113,7 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const std::vector<Range::EnvironmentalReverbRange> kRanges;
std::shared_ptr<EnvReverbSwContext> mContext;
ndk::ScopedAStatus getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
Parameter::Specific* specific);
diff --git a/audio/aidl/default/equalizer/EqualizerSw.cpp b/audio/aidl/default/equalizer/EqualizerSw.cpp
index 984b943..8cfe82e 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.cpp
+++ b/audio/aidl/default/equalizer/EqualizerSw.cpp
@@ -60,6 +60,7 @@
namespace aidl::android::hardware::audio::effect {
const std::string EqualizerSw::kEffectName = "EqualizerSw";
+
const std::vector<Equalizer::BandFrequency> EqualizerSw::kBandFrequency = {{0, 30000, 120000},
{1, 120001, 460000},
{2, 460001, 1800000},
@@ -69,19 +70,33 @@
{0, "Normal"}, {1, "Classical"}, {2, "Dance"}, {3, "Flat"}, {4, "Folk"},
{5, "Heavy Metal"}, {6, "Hip Hop"}, {7, "Jazz"}, {8, "Pop"}, {9, "Rock"}};
-const Equalizer::Capability EqualizerSw::kEqCap = {.bandFrequencies = kBandFrequency,
- .presets = kPresets};
+/**
+ * Use the same min and max to build a capability represented by Range.
+ */
+const std::vector<Range::EqualizerRange> EqualizerSw::kRanges = {
+ MAKE_RANGE(Equalizer, preset, 0, EqualizerSw::kPresets.size() - 1),
+ MAKE_RANGE(Equalizer, bandLevels,
+ std::vector<Equalizer::BandLevel>{
+ Equalizer::BandLevel({.index = 0, .levelMb = -15})},
+ std::vector<Equalizer::BandLevel>{Equalizer::BandLevel(
+ {.index = EqualizerSwContext::kMaxBandNumber - 1, .levelMb = 15})}),
+ /* capability definition */
+ MAKE_RANGE(Equalizer, bandFrequencies, EqualizerSw::kBandFrequency,
+ EqualizerSw::kBandFrequency),
+ MAKE_RANGE(Equalizer, presets, EqualizerSw::kPresets, EqualizerSw::kPresets),
+ /* centerFreqMh is get only, set invalid range min > max */
+ MAKE_RANGE(Equalizer, centerFreqMh, std::vector<int>({1}), std::vector<int>({0}))};
-const Descriptor EqualizerSw::kDesc = {
- .common = {.id = {.type = kEqualizerTypeUUID,
- .uuid = kEqualizerSwImplUUID,
- .proxy = kEqualizerProxyUUID},
- .flags = {.type = Flags::Type::INSERT,
- .insert = Flags::Insert::FIRST,
- .volume = Flags::Volume::CTRL},
- .name = EqualizerSw::kEffectName,
- .implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::equalizer>(EqualizerSw::kEqCap)};
+const Capability EqualizerSw::kEqCap = {.range = EqualizerSw::kRanges};
+const Descriptor EqualizerSw::kDesc = {.common = {.id = {.type = kEqualizerTypeUUID,
+ .uuid = kEqualizerSwImplUUID,
+ .proxy = kEqualizerProxyUUID},
+ .flags = {.type = Flags::Type::INSERT,
+ .insert = Flags::Insert::FIRST,
+ .volume = Flags::Volume::CTRL},
+ .name = EqualizerSw::kEffectName,
+ .implementor = "The Android Open Source Project"},
+ .capability = EqualizerSw::kEqCap};
ndk::ScopedAStatus EqualizerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDesc.toString();
@@ -95,6 +110,7 @@
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& eqParam = specific.get<Parameter::Specific::equalizer>();
+ RETURN_IF(!inRange(eqParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = eqParam.getTag();
switch (tag) {
case Equalizer::preset: {
@@ -150,6 +166,18 @@
eqParam.set<Equalizer::preset>(mContext->getEqPreset());
break;
}
+ case Equalizer::centerFreqMh: {
+ eqParam.set<Equalizer::centerFreqMh>(mContext->getCenterFreqs());
+ break;
+ }
+ case Equalizer::bandFrequencies: {
+ eqParam.set<Equalizer::bandFrequencies>(kBandFrequency);
+ break;
+ }
+ case Equalizer::presets: {
+ eqParam.set<Equalizer::presets>(kPresets);
+ break;
+ }
default: {
LOG(ERROR) << __func__ << " not handled tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
diff --git a/audio/aidl/default/equalizer/EqualizerSw.h b/audio/aidl/default/equalizer/EqualizerSw.h
index 65a8002..f8987c7 100644
--- a/audio/aidl/default/equalizer/EqualizerSw.h
+++ b/audio/aidl/default/equalizer/EqualizerSw.h
@@ -34,7 +34,7 @@
}
RetCode setEqPreset(const int& presetIdx) {
- if (presetIdx < 0 || presetIdx >= NUM_OF_PRESETS) {
+ if (presetIdx < 0 || presetIdx >= kMaxPresetNumber) {
return RetCode::ERROR_ILLEGAL_PARAMETER;
}
mPreset = presetIdx;
@@ -43,13 +43,13 @@
int getEqPreset() { return mPreset; }
RetCode setEqBandLevels(const std::vector<Equalizer::BandLevel>& bandLevels) {
- if (bandLevels.size() > NUM_OF_BANDS) {
- LOG(ERROR) << __func__ << " return because size exceed " << NUM_OF_BANDS;
+ if (bandLevels.size() > kMaxBandNumber) {
+ LOG(ERROR) << __func__ << " return because size exceed " << kMaxBandNumber;
return RetCode::ERROR_ILLEGAL_PARAMETER;
}
RetCode ret = RetCode::SUCCESS;
for (auto& it : bandLevels) {
- if (it.index >= NUM_OF_BANDS || it.index < 0) {
+ if (it.index >= kMaxBandNumber || it.index < 0) {
LOG(ERROR) << __func__ << " index illegal, skip: " << it.index << " - "
<< it.levelMb;
ret = RetCode::ERROR_ILLEGAL_PARAMETER;
@@ -62,19 +62,25 @@
std::vector<Equalizer::BandLevel> getEqBandLevels() {
std::vector<Equalizer::BandLevel> bandLevels;
- for (int i = 0; i < NUM_OF_BANDS; i++) {
+ for (int i = 0; i < kMaxBandNumber; i++) {
bandLevels.push_back({i, mBandLevels[i]});
}
return bandLevels;
}
+ std::vector<int> getCenterFreqs() {
+ return {std::begin(kPresetsFrequencies), std::end(kPresetsFrequencies)};
+ }
+ static const int kMaxBandNumber = 5;
+ static const int kMaxPresetNumber = 10;
+ static const int kCustomPreset = -1;
+
private:
- static const int NUM_OF_BANDS = 5;
- static const int NUM_OF_PRESETS = 10;
- static const int PRESET_CUSTOM = -1;
+ static constexpr std::array<uint16_t, kMaxBandNumber> kPresetsFrequencies = {60, 230, 910, 3600,
+ 14000};
// preset band level
- int mPreset = PRESET_CUSTOM;
- int32_t mBandLevels[NUM_OF_BANDS] = {3, 0, 0, 0, 3};
+ int mPreset = kCustomPreset;
+ int32_t mBandLevels[kMaxBandNumber] = {3, 0, 0, 0, 3};
// Add equalizer specific context for processing here
};
@@ -82,9 +88,7 @@
class EqualizerSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const std::vector<Equalizer::BandFrequency> kBandFrequency;
- static const std::vector<Equalizer::Preset> kPresets;
- static const Equalizer::Capability kEqCap;
+ static const Capability kEqCap;
static const Descriptor kDesc;
EqualizerSw() { LOG(DEBUG) << __func__; }
@@ -106,6 +110,9 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const std::vector<Equalizer::BandFrequency> kBandFrequency;
+ static const std::vector<Equalizer::Preset> kPresets;
+ static const std::vector<Range::EqualizerRange> kRanges;
ndk::ScopedAStatus getParameterEqualizer(const Equalizer::Tag& tag,
Parameter::Specific* specific);
std::shared_ptr<EqualizerSwContext> mContext;
diff --git a/audio/aidl/default/automaticGainControl/Android.bp b/audio/aidl/default/extension/Android.bp
similarity index 91%
copy from audio/aidl/default/automaticGainControl/Android.bp
copy to audio/aidl/default/extension/Android.bp
index 17d6416..4e5d352 100644
--- a/audio/aidl/default/automaticGainControl/Android.bp
+++ b/audio/aidl/default/extension/Android.bp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,14 +24,14 @@
}
cc_library_shared {
- name: "libagcsw",
+ name: "libextensioneffect",
defaults: [
"aidlaudioeffectservice_defaults",
"latest_android_media_audio_common_types_ndk_shared",
"latest_android_hardware_audio_effect_ndk_shared",
],
srcs: [
- "AutomaticGainControlSw.cpp",
+ "ExtensionEffect.cpp",
":effectCommonFile",
],
relative_install_path: "soundfx",
diff --git a/audio/aidl/default/extension/ExtensionEffect.cpp b/audio/aidl/default/extension/ExtensionEffect.cpp
new file mode 100644
index 0000000..d2e3ccd
--- /dev/null
+++ b/audio/aidl/default/extension/ExtensionEffect.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2023 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 <algorithm>
+#include <cstddef>
+#include <memory>
+#include <unordered_set>
+
+#define LOG_TAG "AHAL_ExtensionEffect"
+#include <Utils.h>
+#include <aidl/android/hardware/audio/effect/DefaultExtension.h>
+#include <android-base/logging.h>
+#include <fmq/AidlMessageQueue.h>
+
+#include "ExtensionEffect.h"
+
+using aidl::android::hardware::audio::effect::DefaultExtension;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::ExtensionEffect;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kExtensionEffectImplUUID;
+using aidl::android::hardware::audio::effect::kExtensionEffectTypeUUID;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::VendorExtension;
+using aidl::android::media::audio::common::AudioUuid;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+ std::shared_ptr<IEffect>* instanceSpp) {
+ if (!in_impl_uuid || *in_impl_uuid != kExtensionEffectImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ if (instanceSpp) {
+ *instanceSpp = ndk::SharedRefBase::make<ExtensionEffect>();
+ LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+ return EX_NONE;
+ } else {
+ LOG(ERROR) << __func__ << " invalid input parameter!";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+ if (!in_impl_uuid || *in_impl_uuid != kExtensionEffectImplUUID) {
+ LOG(ERROR) << __func__ << "uuid not supported";
+ return EX_ILLEGAL_ARGUMENT;
+ }
+ *_aidl_return = ExtensionEffect::kDescriptor;
+ return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string ExtensionEffect::kEffectName = "ExtensionEffectExample";
+
+const Descriptor ExtensionEffect::kDescriptor = {
+ .common = {.id = {.type = kExtensionEffectTypeUUID,
+ .uuid = kExtensionEffectImplUUID,
+ .proxy = std::nullopt},
+ .name = ExtensionEffect::kEffectName,
+ .implementor = "The Android Open Source Project"}};
+
+ndk::ScopedAStatus ExtensionEffect::getDescriptor(Descriptor* _aidl_return) {
+ LOG(DEBUG) << __func__ << kDescriptor.toString();
+ *_aidl_return = kDescriptor;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ExtensionEffect::setParameterSpecific(const Parameter::Specific& specific) {
+ RETURN_IF(Parameter::Specific::vendorEffect != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+ "EffectNotSupported");
+ RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+ auto& vendorEffect = specific.get<Parameter::Specific::vendorEffect>();
+ std::optional<DefaultExtension> defaultExt;
+ RETURN_IF(STATUS_OK != vendorEffect.extension.getParcelable(&defaultExt), EX_ILLEGAL_ARGUMENT,
+ "getParcelableFailed");
+ RETURN_IF(!defaultExt.has_value(), EX_ILLEGAL_ARGUMENT, "parcelableNulld");
+ RETURN_IF(mContext->setParams(defaultExt->bytes) != RetCode::SUCCESS, EX_ILLEGAL_ARGUMENT,
+ "paramNotSupported");
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ExtensionEffect::getParameterSpecific(const Parameter::Id& id,
+ Parameter::Specific* specific) {
+ auto tag = id.getTag();
+ RETURN_IF(Parameter::Id::vendorEffectTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+ auto specificId = id.get<Parameter::Id::vendorEffectTag>();
+ VendorExtension extension;
+ DefaultExtension defaultExt;
+ defaultExt.bytes = mContext->getParams(specificId);
+ RETURN_IF(STATUS_OK != extension.extension.setParcelable(defaultExt), EX_ILLEGAL_ARGUMENT,
+ "setParcelableFailed");
+ specific->set<Parameter::Specific::vendorEffect>(extension);
+ return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> ExtensionEffect::createContext(const Parameter::Common& common) {
+ if (mContext) {
+ LOG(DEBUG) << __func__ << " context already exist";
+ } else {
+ mContext = std::make_shared<ExtensionEffectContext>(1 /* statusFmqDepth */, common);
+ }
+ return mContext;
+}
+
+std::shared_ptr<EffectContext> ExtensionEffect::getContext() {
+ return mContext;
+}
+
+RetCode ExtensionEffect::releaseContext() {
+ if (mContext) {
+ mContext.reset();
+ }
+ return RetCode::SUCCESS;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status ExtensionEffect::effectProcessImpl(float* in, float* out, int samples) {
+ // TODO: get data buffer and process.
+ LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+ for (int i = 0; i < samples; i++) {
+ *out++ = *in++;
+ }
+ return {STATUS_OK, samples, samples};
+}
+
+} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h b/audio/aidl/default/extension/ExtensionEffect.h
similarity index 60%
copy from audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
copy to audio/aidl/default/extension/ExtensionEffect.h
index 2724835..399fa83 100644
--- a/audio/aidl/default/automaticGainControl/AutomaticGainControlSw.h
+++ b/audio/aidl/default/extension/ExtensionEffect.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 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.
@@ -18,43 +18,38 @@
#include <aidl/android/hardware/audio/effect/BnEffect.h>
#include <fmq/AidlMessageQueue.h>
-#include <cstdlib>
#include <memory>
+#include <vector>
#include "effect-impl/EffectImpl.h"
#include "effect-impl/EffectUUID.h"
namespace aidl::android::hardware::audio::effect {
-class AutomaticGainControlSwContext final : public EffectContext {
+class ExtensionEffectContext final : public EffectContext {
public:
- AutomaticGainControlSwContext(int statusDepth, const Parameter::Common& common)
+ ExtensionEffectContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
- RetCode setDigitalGain(int gain);
- int getDigitalGain();
- RetCode setLevelEstimator(AutomaticGainControl::LevelEstimator levelEstimator);
- AutomaticGainControl::LevelEstimator getLevelEstimator();
- RetCode setSaturationMargin(int margin);
- int getSaturationMargin();
+ RetCode setParams(const std::vector<uint8_t>& params) {
+ mParams = params;
+ return RetCode::SUCCESS;
+ }
+ std::vector<uint8_t> getParams(int tag __unused) const { return mParams; }
private:
- int mDigitalGain = 0;
- AutomaticGainControl::LevelEstimator mLevelEstimator =
- AutomaticGainControl::LevelEstimator::RMS;
- int mSaturationMargin = 0;
+ std::vector<uint8_t> mParams;
};
-class AutomaticGainControlSw final : public EffectImpl {
+class ExtensionEffect final : public EffectImpl {
public:
static const std::string kEffectName;
- static const bool kStrengthSupported;
- static const AutomaticGainControl::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
- AutomaticGainControlSw() { LOG(DEBUG) << __func__; }
- ~AutomaticGainControlSw() {
+ ExtensionEffect() { LOG(DEBUG) << __func__; }
+ ~ExtensionEffect() {
cleanUp();
LOG(DEBUG) << __func__;
}
@@ -72,8 +67,6 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
private:
- std::shared_ptr<AutomaticGainControlSwContext> mContext;
- ndk::ScopedAStatus getParameterAutomaticGainControl(const AutomaticGainControl::Tag& tag,
- Parameter::Specific* specific);
+ std::shared_ptr<ExtensionEffectContext> mContext;
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index 3c3b66f..6037ad2 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -60,8 +60,6 @@
namespace aidl::android::hardware::audio::effect {
const std::string HapticGeneratorSw::kEffectName = "HapticGeneratorSw";
-/* capabilities */
-const HapticGenerator::Capability HapticGeneratorSw::kCapability;
/* Effect descriptor */
const Descriptor HapticGeneratorSw::kDescriptor = {
.common = {.id = {.type = kHapticGeneratorTypeUUID,
@@ -71,9 +69,7 @@
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = HapticGeneratorSw::kEffectName,
- .implementor = "The Android Open Source Project"},
- .capability =
- Capability::make<Capability::hapticGenerator>(HapticGeneratorSw::kCapability)};
+ .implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus HapticGeneratorSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index 7159501..428f460 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -58,7 +58,6 @@
class HapticGeneratorSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const HapticGenerator::Capability kCapability;
static const Descriptor kDescriptor;
HapticGeneratorSw() { LOG(DEBUG) << __func__; }
~HapticGeneratorSw() {
diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h
index 1aca1fe..4dd0133 100644
--- a/audio/aidl/default/include/core-impl/Configuration.h
+++ b/audio/aidl/default/include/core-impl/Configuration.h
@@ -22,14 +22,14 @@
#include <aidl/android/hardware/audio/core/AudioPatch.h>
#include <aidl/android/hardware/audio/core/AudioRoute.h>
-#include <aidl/android/hardware/audio/core/MicrophoneInfo.h>
#include <aidl/android/media/audio/common/AudioPort.h>
#include <aidl/android/media/audio/common/AudioPortConfig.h>
+#include <aidl/android/media/audio/common/MicrophoneInfo.h>
namespace aidl::android::hardware::audio::core::internal {
struct Configuration {
- std::vector<MicrophoneInfo> microphones;
+ std::vector<::aidl::android::media::audio::common::MicrophoneInfo> microphones;
std::vector<::aidl::android::media::audio::common::AudioPort> ports;
std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs;
std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs;
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 80a22dc..8365b34 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -35,6 +35,10 @@
explicit Module(Type type) : mType(type) {}
+ static std::shared_ptr<Module> createInstance(Type type);
+ static StreamIn::CreateInstance getStreamInCreator(Type type);
+ static StreamOut::CreateInstance getStreamOutCreator(Type type);
+
private:
struct VendorDebug {
static const std::string kForceTransientBurstName;
@@ -90,7 +94,9 @@
ndk::ScopedAStatus setMasterVolume(float in_volume) override;
ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
ndk::ScopedAStatus setMicMute(bool in_mute) override;
- ndk::ScopedAStatus getMicrophones(std::vector<MicrophoneInfo>* _aidl_return) override;
+ ndk::ScopedAStatus getMicrophones(
+ std::vector<::aidl::android::media::audio::common::MicrophoneInfo>* _aidl_return)
+ override;
ndk::ScopedAStatus updateAudioMode(
::aidl::android::media::audio::common::AudioMode in_mode) override;
ndk::ScopedAStatus updateScreenRotation(
@@ -163,6 +169,17 @@
std::shared_ptr<sounddose::ISoundDose> mSoundDose;
ndk::SpAIBinder mSoundDoseBinder;
std::optional<bool> mIsMmapSupported;
+
+ protected:
+ // If the module is unable to populate the connected device port correctly, the returned error
+ // code must correspond to the errors of `IModule.connectedExternalDevice` method.
+ virtual ndk::ScopedAStatus populateConnectedDevicePort(
+ ::aidl::android::media::audio::common::AudioPort* audioPort);
+ // If the module finds that the patch endpoints configurations are not matched, the returned
+ // error code must correspond to the errors of `IModule.setAudioPatch` method.
+ virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+ const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
+ const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks);
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h
new file mode 100644
index 0000000..7b177e8
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/ModuleUsb.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 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 "core-impl/Module.h"
+
+namespace aidl::android::hardware::audio::core {
+
+class ModuleUsb : public Module {
+ public:
+ explicit ModuleUsb(Module::Type type) : Module(type) {}
+
+ private:
+ // IModule interfaces
+ ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
+ ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
+ ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override;
+ ndk::ScopedAStatus setMasterMute(bool in_mute) override;
+ ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override;
+ ndk::ScopedAStatus setMasterVolume(float in_volume) override;
+ ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
+ ndk::ScopedAStatus setMicMute(bool in_mute) override;
+
+ // Module interfaces
+ ndk::ScopedAStatus populateConnectedDevicePort(
+ ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+ ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+ const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
+ const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
+ override;
+};
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 7cd4259..0d4365a3 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -32,10 +32,10 @@
#include <aidl/android/hardware/audio/core/BnStreamOut.h>
#include <aidl/android/hardware/audio/core/IStreamCallback.h>
#include <aidl/android/hardware/audio/core/IStreamOutEventCallback.h>
-#include <aidl/android/hardware/audio/core/MicrophoneInfo.h>
#include <aidl/android/hardware/audio/core/StreamDescriptor.h>
#include <aidl/android/media/audio/common/AudioDevice.h>
#include <aidl/android/media/audio/common/AudioOffloadInfo.h>
+#include <aidl/android/media/audio/common/MicrophoneInfo.h>
#include <fmq/AidlMessageQueue.h>
#include <system/thread_defs.h>
#include <utils/Errors.h>
@@ -77,7 +77,8 @@
StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ,
const ::aidl::android::media::audio::common::AudioFormatDescription& format,
const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout,
- std::unique_ptr<DataMQ> dataMQ, std::shared_ptr<IStreamCallback> asyncCallback,
+ int sampleRate, std::unique_ptr<DataMQ> dataMQ,
+ std::shared_ptr<IStreamCallback> asyncCallback,
std::shared_ptr<IStreamOutEventCallback> outEventCallback,
DebugParameters debugParameters)
: mCommandMQ(std::move(commandMQ)),
@@ -85,6 +86,7 @@
mReplyMQ(std::move(replyMQ)),
mFormat(format),
mChannelLayout(channelLayout),
+ mSampleRate(sampleRate),
mDataMQ(std::move(dataMQ)),
mAsyncCallback(asyncCallback),
mOutEventCallback(outEventCallback),
@@ -95,6 +97,7 @@
mReplyMQ(std::move(other.mReplyMQ)),
mFormat(other.mFormat),
mChannelLayout(other.mChannelLayout),
+ mSampleRate(other.mSampleRate),
mDataMQ(std::move(other.mDataMQ)),
mAsyncCallback(std::move(other.mAsyncCallback)),
mOutEventCallback(std::move(other.mOutEventCallback)),
@@ -105,6 +108,7 @@
mReplyMQ = std::move(other.mReplyMQ);
mFormat = std::move(other.mFormat);
mChannelLayout = std::move(other.mChannelLayout);
+ mSampleRate = other.mSampleRate;
mDataMQ = std::move(other.mDataMQ);
mAsyncCallback = std::move(other.mAsyncCallback);
mOutEventCallback = std::move(other.mOutEventCallback);
@@ -131,6 +135,7 @@
}
ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
int getTransientStateDelayMs() const { return mDebugParameters.transientStateDelayMs; }
+ int getSampleRate() const { return mSampleRate; }
bool isValid() const;
void reset();
@@ -140,6 +145,7 @@
std::unique_ptr<ReplyMQ> mReplyMQ;
::aidl::android::media::audio::common::AudioFormatDescription mFormat;
::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout;
+ int mSampleRate;
std::unique_ptr<DataMQ> mDataMQ;
std::shared_ptr<IStreamCallback> mAsyncCallback;
std::shared_ptr<IStreamOutEventCallback> mOutEventCallback; // Only used by output streams
@@ -151,6 +157,11 @@
virtual ~DriverInterface() = default;
// This function is called once, on the main thread, before starting the worker thread.
virtual ::android::status_t init() = 0;
+ // This function is called from Binder pool thread. It must be done in a thread-safe manner
+ // if this method and other methods in this interface share data.
+ virtual ::android::status_t setConnectedDevices(
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>&
+ connectedDevices) = 0;
// All the functions below are called on the worker thread.
virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
virtual ::android::status_t flush() = 0;
@@ -370,6 +381,7 @@
const std::vector<::aidl::android::media::audio::common::AudioDevice>& devices) {
mWorker->setIsConnected(!devices.empty());
mConnectedDevices = devices;
+ mDriver->setConnectedDevices(devices);
}
ndk::ScopedAStatus updateMetadata(const Metadata& metadata);
@@ -401,7 +413,8 @@
getStreamCommon(_aidl_return);
}
ndk::ScopedAStatus getActiveMicrophones(
- std::vector<MicrophoneDynamicInfo>* _aidl_return) override;
+ std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
+ override;
ndk::ScopedAStatus getMicrophoneDirection(MicrophoneDirection* _aidl_return) override;
ndk::ScopedAStatus setMicrophoneDirection(MicrophoneDirection in_direction) override;
ndk::ScopedAStatus getMicrophoneFieldDimension(float* _aidl_return) override;
@@ -422,7 +435,7 @@
StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
StreamContext&& context, const DriverInterface::CreateInstance& createDriver,
const StreamWorkerInterface::CreateInstance& createWorker,
- const std::vector<MicrophoneInfo>& microphones);
+ const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
void createStreamCommon(const std::shared_ptr<StreamIn>& myPtr) {
StreamCommonImpl<
::aidl::android::hardware::audio::common::SinkMetadata>::createStreamCommon(myPtr);
@@ -433,7 +446,8 @@
public:
using CreateInstance = std::function<ndk::ScopedAStatus(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
- StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+ StreamContext&& context,
+ const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result)>;
};
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index 98a062a..69fd7b3 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -24,6 +24,9 @@
public:
DriverStub(const StreamContext& context, bool isInput);
::android::status_t init() override;
+ ::android::status_t setConnectedDevices(
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
+ override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
::android::status_t flush() override;
::android::status_t pause() override;
@@ -40,13 +43,16 @@
public:
static ndk::ScopedAStatus createInstance(
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
- StreamContext&& context, const std::vector<MicrophoneInfo>& microphones,
+ StreamContext&& context,
+ const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
std::shared_ptr<StreamIn>* result);
private:
friend class ndk::SharedRefBase;
- StreamInStub(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
- StreamContext&& context, const std::vector<MicrophoneInfo>& microphones);
+ StreamInStub(
+ const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+ StreamContext&& context,
+ const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
};
class StreamOutStub final : public StreamOut {
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
new file mode 100644
index 0000000..c04dc66
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 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 <mutex>
+
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+
+#include "core-impl/Stream.h"
+
+extern "C" {
+#include <tinyalsa/pcm.h>
+#include "alsa_device_proxy.h"
+}
+
+namespace aidl::android::hardware::audio::core {
+
+class DriverUsb : public DriverInterface {
+ public:
+ DriverUsb(const StreamContext& context, bool isInput);
+ ::android::status_t init() override;
+ ::android::status_t setConnectedDevices(
+ const std::vector<::aidl::android::media::audio::common::AudioDevice>& connectedDevices)
+ override;
+ ::android::status_t drain(StreamDescriptor::DrainMode) override;
+ ::android::status_t flush() override;
+ ::android::status_t pause() override;
+ ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) override;
+ ::android::status_t standby() override;
+
+ private:
+ ::android::status_t exitStandby();
+
+ std::mutex mLock;
+
+ const size_t mFrameSizeBytes;
+ std::optional<struct pcm_config> mConfig;
+ const bool mIsInput;
+ // Cached device addresses for connected devices.
+ std::vector<::aidl::android::media::audio::common::AudioDeviceAddress> mConnectedDevices
+ GUARDED_BY(mLock);
+ std::vector<std::shared_ptr<alsa_device_proxy>> mAlsaDeviceProxies GUARDED_BY(mLock);
+ bool mIsStandby = false;
+};
+
+class StreamInUsb final : public StreamIn {
+ ndk::ScopedAStatus getActiveMicrophones(
+ std::vector<::aidl::android::media::audio::common::MicrophoneDynamicInfo>* _aidl_return)
+ override;
+
+ public:
+ static ndk::ScopedAStatus createInstance(
+ const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+ StreamContext&& context,
+ const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
+ std::shared_ptr<StreamIn>* result);
+
+ private:
+ friend class ndk::SharedRefBase;
+ StreamInUsb(
+ const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
+ StreamContext&& context,
+ const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones);
+};
+
+class StreamOutUsb final : public StreamOut {
+ public:
+ static ndk::ScopedAStatus createInstance(
+ const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+ offloadInfo,
+ std::shared_ptr<StreamOut>* result);
+
+ private:
+ friend class ndk::SharedRefBase;
+ StreamOutUsb(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+ offloadInfo);
+};
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/utils.h b/audio/aidl/default/include/core-impl/utils.h
index 9d06f08..ae33227 100644
--- a/audio/aidl/default/include/core-impl/utils.h
+++ b/audio/aidl/default/include/core-impl/utils.h
@@ -17,6 +17,7 @@
#pragma once
#include <algorithm>
+#include <map>
#include <set>
#include <vector>
@@ -101,4 +102,21 @@
return result;
}
+// Assuming that M is a map whose keys' type is K and values' type is V,
+// return the corresponding value of the given key from the map or default
+// value if the key is not found.
+template <typename M, typename K, typename V>
+auto findValueOrDefault(const M& m, const K& key, V defaultValue) {
+ auto it = m.find(key);
+ return it == m.end() ? defaultValue : it->second;
+}
+
+// Assuming that M is a map whose keys' type is K, return the given key if it
+// is found from the map or default value.
+template <typename M, typename K>
+auto findKeyOrDefault(const M& m, const K& key, K defaultValue) {
+ auto it = m.find(key);
+ return it == m.end() ? defaultValue : key;
+}
+
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index 4b6cecd..9b1a75b 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -54,6 +54,9 @@
* EffectThread will make sure effectProcessImpl only be called after startThread() successful
* and before stopThread() successful.
*
+ * effectProcessImpl implementation must not call any EffectThread interface, otherwise it will
+ * cause deadlock.
+ *
* @param in address of input float buffer.
* @param out address of output float buffer.
* @param samples number of samples to process.
@@ -62,16 +65,11 @@
virtual IEffect::Status effectProcessImpl(float* in, float* out, int samples) = 0;
/**
- * The default EffectThread::process() implementation doesn't need to lock. It will only
- * access the FMQ and mWorkBuffer in EffectContext, since they will only be changed in
- * EffectImpl IEffect::open() (in this case EffectThread just created and not running yet) and
- * IEffect::command(CommandId::RESET) (in this case EffectThread already stopped).
- *
- * process() call effectProcessImpl for effect processing, and because effectProcessImpl is
- * implemented by effects, process() must not hold lock before call into effectProcessImpl to
- * avoid deadlock.
+ * process() call effectProcessImpl() for effect data processing, it is necessary for the
+ * processing to be called under Effect thread mutex mThreadMutex, to avoid the effect state
+ * change before/during data processing, and keep the thread and effect state consistent.
*/
- virtual void process();
+ virtual void process_l() REQUIRES(mThreadMutex);
private:
const int kMaxTaskNameLen = 15;
@@ -83,5 +81,7 @@
std::thread mThread;
int mPriority;
std::string mName;
+
+ RetCode handleStartStop(bool stop);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/include/effect-impl/EffectTypes.h b/audio/aidl/default/include/effect-impl/EffectTypes.h
index b100a2e..fe534d7 100644
--- a/audio/aidl/default/include/effect-impl/EffectTypes.h
+++ b/audio/aidl/default/include/effect-impl/EffectTypes.h
@@ -19,16 +19,18 @@
#include <string>
#include <aidl/android/hardware/audio/effect/BnEffect.h>
+#include <aidl/android/hardware/audio/effect/Range.h>
#include <android-base/logging.h>
+#include <system/audio_effects/aidl_effects_utils.h>
typedef binder_exception_t (*EffectCreateFunctor)(
const ::aidl::android::media::audio::common::AudioUuid*,
- std::shared_ptr<aidl::android::hardware::audio::effect::IEffect>*);
+ std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>*);
typedef binder_exception_t (*EffectDestroyFunctor)(
- const std::shared_ptr<aidl::android::hardware::audio::effect::IEffect>&);
+ const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>&);
typedef binder_exception_t (*EffectQueryFunctor)(
const ::aidl::android::media::audio::common::AudioUuid*,
- aidl::android::hardware::audio::effect::Descriptor*);
+ ::aidl::android::hardware::audio::effect::Descriptor*);
struct effect_dl_interface_s {
EffectCreateFunctor createEffectFunc;
@@ -116,6 +118,16 @@
} \
}
+/**
+ * Make a Range::$EffectType$Range.
+ * T: The $EffectType$, Visualizer for example.
+ * Tag: The union tag name in $EffectType$ definition, latencyMs for example.
+ * l: The value of Range::$EffectType$Range.min.
+ * r: The value of Range::$EffectType$Range.max.
+ */
+#define MAKE_RANGE(T, Tag, l, r) \
+ { .min = T::make<T::Tag>(l), .max = T::make<T::Tag>(r) }
+
static inline bool stringToUuid(const char* str,
::aidl::android::media::audio::common::AudioUuid* uuid) {
RETURN_VALUE_IF(!uuid || !str, false, "nullPtr");
diff --git a/audio/aidl/default/include/effect-impl/EffectUUID.h b/audio/aidl/default/include/effect-impl/EffectUUID.h
index 7703091..bc61c0f 100644
--- a/audio/aidl/default/include/effect-impl/EffectUUID.h
+++ b/audio/aidl/default/include/effect-impl/EffectUUID.h
@@ -45,18 +45,30 @@
0x11e0,
0xa896,
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
-static const AudioUuid kAutomaticGainControlTypeUUID = {static_cast<int32_t>(0xae3c653b),
- 0xbe18,
- 0x4ab8,
- 0x8938,
- {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
+// 0a8abfe0-654c-11e0-ba26-0002a5d5c51b
+static const AudioUuid kAutomaticGainControlV1TypeUUID = {static_cast<int32_t>(0x0a8abfe0),
+ 0x654c,
+ 0x11e0,
+ 0xba26,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// aa8130e0-66fc-11e0-bad0-0002a5d5c51b
+static const AudioUuid kAutomaticGainControlV1SwImplUUID = {static_cast<int32_t>(0xaa8130e0),
+ 0x66fc,
+ 0x11e0,
+ 0xbad0,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// ae3c653b-be18-4ab8-8938-418f0a7f06ac
+static const AudioUuid kAutomaticGainControlV2TypeUUID = {static_cast<int32_t>(0xae3c653b),
+ 0xbe18,
+ 0x4ab8,
+ 0x8938,
+ {0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
// 89f38e65-d4d2-4d64-ad0e-2b3e799ea886
-static const AudioUuid kAutomaticGainControlSwImplUUID = {static_cast<int32_t>(0x89f38e65),
- 0xd4d2,
- 0x4d64,
- 0xad0e,
- {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}};
+static const AudioUuid kAutomaticGainControlV2SwImplUUID = {static_cast<int32_t>(0x89f38e65),
+ 0xd4d2,
+ 0x4d64,
+ 0xad0e,
+ {0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}};
// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
0xddd4,
@@ -81,12 +93,12 @@
0x4d24,
0xaa88,
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa81862a-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0xfa81862a),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// 381e49cc-a858-4aa2-87f6-e8388e7601b2
+static const AudioUuid kDownmixTypeUUID = {static_cast<int32_t>(0x381e49cc),
+ 0xa858,
+ 0x4aa2,
+ 0x87f6,
+ {0xe8, 0x38, 0x8e, 0x76, 0x01, 0xb2}};
// fa8187ba-588b-11ed-9b6a-0242ac120002
static const AudioUuid kDownmixSwImplUUID = {static_cast<int32_t>(0xfa8187ba),
0x588b,
@@ -261,12 +273,12 @@
0x4d34,
0xacaf,
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-// fa819f3e-588b-11ed-9b6a-0242ac120002
-static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xfa819f3e),
- 0x588b,
- 0x11ed,
- 0x9b6a,
- {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// e46b26a0-dddd-11db-8afd-0002a5d5c51b
+static const AudioUuid kVisualizerTypeUUID = {static_cast<int32_t>(0xe46b26a0),
+ 0xdddd,
+ 0x11db,
+ 0x8afd,
+ {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
// fa81a0f6-588b-11ed-9b6a-0242ac120002
static const AudioUuid kVisualizerSwImplUUID = {static_cast<int32_t>(0xfa81a0f6),
0x588b,
@@ -299,6 +311,18 @@
0x81f9,
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
+// fa81dbde-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kExtensionEffectTypeUUID = {static_cast<int32_t>(0xfa81dbde),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
+// fa81dd00-588b-11ed-9b6a-0242ac120002
+static const AudioUuid kExtensionEffectImplUUID = {static_cast<int32_t>(0xfa81dd00),
+ 0x588b,
+ 0x11ed,
+ 0x9b6a,
+ {0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
/**
* @brief A map between effect name and effect type UUID.
* All <name> attribution in effect/effectProxy of audio_effects.xml should be listed in this map.
@@ -306,11 +330,13 @@
*/
static const std::map<const std::string /* effect type */, const AudioUuid&> kUuidNameTypeMap = {
{"acoustic_echo_canceler", kAcousticEchoCancelerTypeUUID},
- {"automatic_gain_control", kAutomaticGainControlTypeUUID},
+ {"automatic_gain_control_v1", kAutomaticGainControlV1TypeUUID},
+ {"automatic_gain_control_v2", kAutomaticGainControlV2TypeUUID},
{"bassboost", kBassBoostTypeUUID},
{"downmix", kDownmixTypeUUID},
{"dynamics_processing", kDynamicsProcessingTypeUUID},
{"equalizer", kEqualizerTypeUUID},
+ {"extensioneffect", kExtensionEffectTypeUUID},
{"haptic_generator", kHapticGeneratorTypeUUID},
{"loudness_enhancer", kLoudnessEnhancerTypeUUID},
{"env_reverb", kEnvReverbTypeUUID},
diff --git a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
index 5da70c7..e252f4a 100644
--- a/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
+++ b/audio/aidl/default/loudnessEnhancer/LoudnessEnhancerSw.h
@@ -47,7 +47,6 @@
class LoudnessEnhancerSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const LoudnessEnhancer::Capability kCapability;
static const Descriptor kDescriptor;
LoudnessEnhancerSw() { LOG(DEBUG) << __func__; }
~LoudnessEnhancerSw() {
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index 1933509..a861f9d 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -25,9 +25,11 @@
#include "core-impl/Config.h"
#include "core-impl/Module.h"
+#include "core-impl/ModuleUsb.h"
using aidl::android::hardware::audio::core::Config;
using aidl::android::hardware::audio::core::Module;
+using aidl::android::hardware::audio::core::ModuleUsb;
int main() {
// Random values are used in the implementation.
@@ -35,6 +37,8 @@
// This is a debug implementation, always enable debug logging.
android::base::SetMinimumLogSeverity(::android::base::DEBUG);
+ // For more logs, use VERBOSE, however this may hinder performance.
+ // android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
ABinderProcess_setThreadPoolMaxThreadCount(16);
// Make the default config service
@@ -46,7 +50,7 @@
// Make modules
auto createModule = [](Module::Type type, const std::string& instance) {
- auto module = ndk::SharedRefBase::make<Module>(type);
+ auto module = Module::createInstance(type);
ndk::SpAIBinder moduleBinder = module->asBinder();
const std::string moduleName = std::string(Module::descriptor).append("/").append(instance);
AIBinder_setMinSchedulerPolicy(moduleBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
index a36cfe0..0ea31ea 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
@@ -60,7 +60,6 @@
namespace aidl::android::hardware::audio::effect {
const std::string NoiseSuppressionSw::kEffectName = "NoiseSuppressionSw";
-const NoiseSuppression::Capability NoiseSuppressionSw::kCapability;
const Descriptor NoiseSuppressionSw::kDescriptor = {
.common = {.id = {.type = kNoiseSuppressionTypeUUID,
.uuid = kNoiseSuppressionSwImplUUID,
@@ -69,9 +68,7 @@
.insert = Flags::Insert::FIRST,
.volume = Flags::Volume::CTRL},
.name = NoiseSuppressionSw::kEffectName,
- .implementor = "The Android Open Source Project"},
- .capability =
- Capability::make<Capability::noiseSuppression>(NoiseSuppressionSw::kCapability)};
+ .implementor = "The Android Open Source Project"}};
ndk::ScopedAStatus NoiseSuppressionSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -90,10 +87,15 @@
switch (tag) {
case NoiseSuppression::level: {
RETURN_IF(mContext->setLevel(param.get<NoiseSuppression::level>()) != RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "levelSupported");
+ EX_ILLEGAL_ARGUMENT, "levelNotSupported");
return ndk::ScopedAStatus::ok();
}
- default: {
+ case NoiseSuppression::type: {
+ RETURN_IF(mContext->setType(param.get<NoiseSuppression::type>()) != RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "typeNotSupported");
+ return ndk::ScopedAStatus::ok();
+ }
+ case NoiseSuppression::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
@@ -111,10 +113,11 @@
case NoiseSuppression::Id::commonTag:
return getParameterNoiseSuppression(specificId.get<NoiseSuppression::Id::commonTag>(),
specific);
- default:
+ case NoiseSuppression::Id::vendorExtensionTag: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
+ }
}
}
@@ -127,7 +130,11 @@
param.set<NoiseSuppression::level>(mContext->getLevel());
break;
}
- default: {
+ case NoiseSuppression::type: {
+ param.set<NoiseSuppression::type>(mContext->getType());
+ break;
+ }
+ case NoiseSuppression::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
@@ -177,4 +184,9 @@
return mLevel;
}
+RetCode NoiseSuppressionSwContext::setType(NoiseSuppression::Type type) {
+ mType = type;
+ return RetCode::SUCCESS;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
index f39d8e5..22bf066 100644
--- a/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
+++ b/audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
@@ -35,16 +35,18 @@
RetCode setLevel(NoiseSuppression::Level level);
NoiseSuppression::Level getLevel();
+ RetCode setType(NoiseSuppression::Type type);
+ NoiseSuppression::Type getType() { return mType; }
private:
NoiseSuppression::Level mLevel = NoiseSuppression::Level::LOW;
+ NoiseSuppression::Type mType = NoiseSuppression::Type::SINGLE_CHANNEL;
};
class NoiseSuppressionSw final : public EffectImpl {
public:
static const std::string kEffectName;
static const bool kStrengthSupported;
- static const NoiseSuppression::Capability kCapability;
static const Descriptor kDescriptor;
NoiseSuppressionSw() { LOG(DEBUG) << __func__; }
~NoiseSuppressionSw() {
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.cpp b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
index d038596..2da3ff6 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.cpp
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.cpp
@@ -62,12 +62,17 @@
const std::string PresetReverbSw::kEffectName = "PresetReverbSw";
-const std::vector<PresetReverb::Presets> kSupportedPresets{
+const std::vector<PresetReverb::Presets> PresetReverbSw::kSupportedPresets{
ndk::enum_range<PresetReverb::Presets>().begin(),
ndk::enum_range<PresetReverb::Presets>().end()};
-const PresetReverb::Capability PresetReverbSw::kCapability = {.supportedPresets =
- kSupportedPresets};
+const std::vector<Range::PresetReverbRange> PresetReverbSw::kRanges = {
+ MAKE_RANGE(PresetReverb, supportedPresets, PresetReverbSw::kSupportedPresets,
+ PresetReverbSw::kSupportedPresets)};
+
+const Capability PresetReverbSw::kCapability = {
+ .range = Range::make<Range::presetReverb>(PresetReverbSw::kRanges)};
+
const Descriptor PresetReverbSw::kDescriptor = {
.common = {.id = {.type = kPresetReverbTypeUUID,
.uuid = kPresetReverbSwImplUUID,
@@ -77,7 +82,7 @@
.volume = Flags::Volume::CTRL},
.name = PresetReverbSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::presetReverb>(PresetReverbSw::kCapability)};
+ .capability = PresetReverbSw::kCapability};
ndk::ScopedAStatus PresetReverbSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -92,6 +97,7 @@
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
auto& prParam = specific.get<Parameter::Specific::presetReverb>();
+ RETURN_IF(!inRange(prParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = prParam.getTag();
switch (tag) {
diff --git a/audio/aidl/default/presetReverb/PresetReverbSw.h b/audio/aidl/default/presetReverb/PresetReverbSw.h
index eb1d80a..5061475 100644
--- a/audio/aidl/default/presetReverb/PresetReverbSw.h
+++ b/audio/aidl/default/presetReverb/PresetReverbSw.h
@@ -46,7 +46,9 @@
class PresetReverbSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const PresetReverb::Capability kCapability;
+ static const std::vector<PresetReverb::Presets> kSupportedPresets;
+ static const std::vector<Range::PresetReverbRange> kRanges;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
PresetReverbSw() { LOG(DEBUG) << __func__; }
~PresetReverbSw() {
diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp
new file mode 100644
index 0000000..e803420
--- /dev/null
+++ b/audio/aidl/default/usb/ModuleUsb.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2023 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 "AHAL_ModuleUsb"
+
+#include <vector>
+
+#include <Utils.h>
+#include <android-base/logging.h>
+#include <tinyalsa/asoundlib.h>
+
+#include "UsbAlsaUtils.h"
+#include "core-impl/ModuleUsb.h"
+
+extern "C" {
+#include "alsa_device_profile.h"
+}
+
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using android::hardware::audio::common::isUsbInputDeviceType;
+
+namespace aidl::android::hardware::audio::core {
+
+namespace {
+
+std::vector<AudioChannelLayout> populateChannelMasksFromProfile(const alsa_device_profile* profile,
+ bool isInput) {
+ std::vector<AudioChannelLayout> channels;
+ for (size_t i = 0; i < AUDIO_PORT_MAX_CHANNEL_MASKS && profile->channel_counts[i] != 0; ++i) {
+ auto layoutMask =
+ usb::getChannelLayoutMaskFromChannelCount(profile->channel_counts[i], isInput);
+ if (layoutMask.getTag() == AudioChannelLayout::Tag::layoutMask) {
+ channels.push_back(layoutMask);
+ }
+ auto indexMask = usb::getChannelIndexMaskFromChannelCount(profile->channel_counts[i]);
+ if (indexMask.getTag() == AudioChannelLayout::Tag::indexMask) {
+ channels.push_back(indexMask);
+ }
+ }
+ return channels;
+}
+
+std::vector<int> populateSampleRatesFromProfile(const alsa_device_profile* profile) {
+ std::vector<int> sampleRates;
+ for (int i = 0; i < std::min(MAX_PROFILE_SAMPLE_RATES, AUDIO_PORT_MAX_SAMPLING_RATES) &&
+ profile->sample_rates[i] != 0;
+ i++) {
+ sampleRates.push_back(profile->sample_rates[i]);
+ }
+ return sampleRates;
+}
+
+} // namespace
+
+ndk::ScopedAStatus ModuleUsb::getTelephony(std::shared_ptr<ITelephony>* _aidl_return) {
+ *_aidl_return = nullptr;
+ LOG(DEBUG) << __func__ << ": returning null";
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleUsb::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
+ *_aidl_return = nullptr;
+ LOG(DEBUG) << __func__ << ": returning null";
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleUsb::getMasterMute(bool* _aidl_return __unused) {
+ LOG(DEBUG) << __func__ << ": is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::setMasterMute(bool in_mute __unused) {
+ LOG(DEBUG) << __func__ << ": is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::getMasterVolume(float* _aidl_return __unused) {
+ LOG(DEBUG) << __func__ << ": is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::setMasterVolume(float in_volume __unused) {
+ LOG(DEBUG) << __func__ << ": is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::getMicMute(bool* _aidl_return __unused) {
+ LOG(DEBUG) << __func__ << ": is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::setMicMute(bool in_mute __unused) {
+ LOG(DEBUG) << __func__ << ": is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) {
+ if (audioPort->ext.getTag() != AudioPortExt::Tag::device) {
+ LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a device port";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ auto& devicePort = audioPort->ext.get<AudioPortExt::Tag::device>();
+ if (devicePort.device.type.connection != AudioDeviceDescription::CONNECTION_USB) {
+ LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a usb device port";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (devicePort.device.address.getTag() != AudioDeviceAddress::Tag::alsa) {
+ LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not using alsa address";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ auto& alsaAddress = devicePort.device.address.get<AudioDeviceAddress::Tag::alsa>();
+ if (alsaAddress.size() != 2 || alsaAddress[0] < 0 || alsaAddress[1] < 0) {
+ LOG(ERROR) << __func__ << ": port id " << audioPort->id << " invalid alsa address";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ const bool isInput = isUsbInputDeviceType(devicePort.device.type.type);
+ alsa_device_profile profile;
+ profile_init(&profile, isInput ? PCM_IN : PCM_OUT);
+ if (!profile_read_device_info(&profile)) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+ }
+
+ std::vector<AudioChannelLayout> channels = populateChannelMasksFromProfile(&profile, isInput);
+ std::vector<int> sampleRates = populateSampleRatesFromProfile(&profile);
+
+ for (size_t i = 0; i < std::min(MAX_PROFILE_FORMATS, AUDIO_PORT_MAX_AUDIO_PROFILES) &&
+ profile.formats[i] != 0;
+ ++i) {
+ auto audioFormatDescription =
+ usb::legacy2aidl_pcm_format_AudioFormatDescription(profile.formats[i]);
+ if (audioFormatDescription.type == AudioFormatType::DEFAULT) {
+ LOG(WARNING) << __func__ << ": unknown pcm type=" << profile.formats[i];
+ continue;
+ }
+ AudioProfile audioProfile = {.format = audioFormatDescription,
+ .channelMasks = channels,
+ .sampleRates = sampleRates};
+ audioPort->profiles.push_back(std::move(audioProfile));
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleUsb::checkAudioPatchEndpointsMatch(
+ const std::vector<AudioPortConfig*>& sources, const std::vector<AudioPortConfig*>& sinks) {
+ for (const auto& source : sources) {
+ for (const auto& sink : sinks) {
+ if (source->sampleRate != sink->sampleRate ||
+ source->channelMask != sink->channelMask || source->format != sink->format) {
+ LOG(ERROR) << __func__
+ << ": mismatch port configuration, source=" << source->toString()
+ << ", sink=" << sink->toString();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ }
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/usb/StreamUsb.cpp b/audio/aidl/default/usb/StreamUsb.cpp
new file mode 100644
index 0000000..bd53a0e
--- /dev/null
+++ b/audio/aidl/default/usb/StreamUsb.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2023 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 "AHAL_StreamUsb"
+#include <android-base/logging.h>
+
+#include "UsbAlsaUtils.h"
+#include "core-impl/Module.h"
+#include "core-impl/StreamUsb.h"
+
+extern "C" {
+#include "alsa_device_profile.h"
+}
+
+using aidl::android::hardware::audio::common::SinkMetadata;
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+
+namespace aidl::android::hardware::audio::core {
+
+DriverUsb::DriverUsb(const StreamContext& context, bool isInput)
+ : mFrameSizeBytes(context.getFrameSize()), mIsInput(isInput) {
+ struct pcm_config config;
+ config.channels = usb::getChannelCountFromChannelMask(context.getChannelLayout(), isInput);
+ if (config.channels == 0) {
+ LOG(ERROR) << __func__ << ": invalid channel=" << context.getChannelLayout().toString();
+ return;
+ }
+ config.format = usb::aidl2legacy_AudioFormatDescription_pcm_format(context.getFormat());
+ if (config.format == PCM_FORMAT_INVALID) {
+ LOG(ERROR) << __func__ << ": invalid format=" << context.getFormat().toString();
+ return;
+ }
+ config.rate = context.getSampleRate();
+ if (config.rate == 0) {
+ LOG(ERROR) << __func__ << ": invalid sample rate=" << config.rate;
+ return;
+ }
+ mConfig = config;
+}
+
+::android::status_t DriverUsb::init() {
+ return mConfig.has_value() ? ::android::OK : ::android::NO_INIT;
+}
+
+::android::status_t DriverUsb::setConnectedDevices(
+ const std::vector<AudioDevice>& connectedDevices) {
+ if (mIsInput && connectedDevices.size() > 1) {
+ LOG(ERROR) << __func__ << ": wrong device size(" << connectedDevices.size()
+ << ") for input stream";
+ return ::android::BAD_VALUE;
+ }
+ for (const auto& connectedDevice : connectedDevices) {
+ if (connectedDevice.address.getTag() != AudioDeviceAddress::alsa) {
+ LOG(ERROR) << __func__ << ": bad device address" << connectedDevice.address.toString();
+ return ::android::BAD_VALUE;
+ }
+ }
+ std::lock_guard guard(mLock);
+ mAlsaDeviceProxies.clear();
+ mConnectedDevices.clear();
+ for (const auto& connectedDevice : connectedDevices) {
+ mConnectedDevices.push_back(connectedDevice.address);
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverUsb::drain(StreamDescriptor::DrainMode) {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverUsb::flush() {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverUsb::pause() {
+ usleep(1000);
+ return ::android::OK;
+}
+
+::android::status_t DriverUsb::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+ int32_t* latencyMs) {
+ if (!mConfig.has_value() || mConnectedDevices.empty()) {
+ return ::android::NO_INIT;
+ }
+ if (mIsStandby) {
+ if (::android::status_t status = exitStandby(); status != ::android::OK) {
+ return status;
+ }
+ }
+ std::vector<std::shared_ptr<alsa_device_proxy>> alsaDeviceProxies;
+ {
+ std::lock_guard guard(mLock);
+ alsaDeviceProxies = mAlsaDeviceProxies;
+ }
+ const size_t bytesToTransfer = frameCount * mFrameSizeBytes;
+ if (mIsInput) {
+ // For input case, only support single device.
+ proxy_read(alsaDeviceProxies[0].get(), buffer, bytesToTransfer);
+ } else {
+ for (auto& proxy : alsaDeviceProxies) {
+ proxy_write(proxy.get(), buffer, bytesToTransfer);
+ }
+ }
+ *actualFrameCount = frameCount;
+ *latencyMs = Module::kLatencyMs;
+ return ::android::OK;
+}
+
+::android::status_t DriverUsb::standby() {
+ if (!mIsStandby) {
+ std::lock_guard guard(mLock);
+ mAlsaDeviceProxies.clear();
+ mIsStandby = true;
+ }
+ return ::android::OK;
+}
+
+::android::status_t DriverUsb::exitStandby() {
+ std::vector<AudioDeviceAddress> connectedDevices;
+ {
+ std::lock_guard guard(mLock);
+ connectedDevices = mConnectedDevices;
+ }
+ std::vector<std::shared_ptr<alsa_device_proxy>> alsaDeviceProxies;
+ for (const auto& device : connectedDevices) {
+ alsa_device_profile profile;
+ profile.card = device.get<AudioDeviceAddress::alsa>()[0];
+ profile.device = device.get<AudioDeviceAddress::alsa>()[1];
+ if (!profile_read_device_info(&profile)) {
+ LOG(ERROR) << __func__
+ << ": unable to read device info, device address=" << device.toString();
+ return ::android::UNKNOWN_ERROR;
+ }
+
+ auto proxy = std::shared_ptr<alsa_device_proxy>(new alsa_device_proxy(),
+ [](alsa_device_proxy* proxy) {
+ proxy_close(proxy);
+ free(proxy);
+ });
+ // Always ask for alsa configure as required since the configuration should be supported
+ // by the connected device. That is guaranteed by `setAudioPortConfig` and
+ // `setAudioPatch`.
+ if (int err =
+ proxy_prepare(proxy.get(), &profile, &mConfig.value(), true /*is_bit_perfect*/);
+ err != 0) {
+ LOG(ERROR) << __func__ << ": fail to prepare for device address=" << device.toString()
+ << " error=" << err;
+ return ::android::UNKNOWN_ERROR;
+ }
+ alsaDeviceProxies.push_back(std::move(proxy));
+ }
+ {
+ std::lock_guard guard(mLock);
+ mAlsaDeviceProxies = alsaDeviceProxies;
+ }
+ mIsStandby = false;
+ return ::android::OK;
+}
+
+// static
+ndk::ScopedAStatus StreamInUsb::createInstance(const SinkMetadata& sinkMetadata,
+ StreamContext&& context,
+ const std::vector<MicrophoneInfo>& microphones,
+ std::shared_ptr<StreamIn>* result) {
+ std::shared_ptr<StreamIn> stream =
+ ndk::SharedRefBase::make<StreamInUsb>(sinkMetadata, std::move(context), microphones);
+ if (auto status = initInstance(stream); !status.isOk()) {
+ return status;
+ }
+ *result = std::move(stream);
+ return ndk::ScopedAStatus::ok();
+}
+
+StreamInUsb::StreamInUsb(const SinkMetadata& sinkMetadata, StreamContext&& context,
+ const std::vector<MicrophoneInfo>& microphones)
+ : StreamIn(
+ sinkMetadata, std::move(context),
+ [](const StreamContext& ctx) -> DriverInterface* {
+ return new DriverUsb(ctx, true /*isInput*/);
+ },
+ [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+ // The default worker implementation is used.
+ return new StreamInWorker(ctx, driver);
+ },
+ microphones) {}
+
+ndk::ScopedAStatus StreamInUsb::getActiveMicrophones(
+ std::vector<MicrophoneDynamicInfo>* _aidl_return __unused) {
+ LOG(DEBUG) << __func__ << ": not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+// static
+ndk::ScopedAStatus StreamOutUsb::createInstance(const SourceMetadata& sourceMetadata,
+ StreamContext&& context,
+ const std::optional<AudioOffloadInfo>& offloadInfo,
+ std::shared_ptr<StreamOut>* result) {
+ if (offloadInfo.has_value()) {
+ LOG(ERROR) << __func__ << ": offload is not supported";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ std::shared_ptr<StreamOut> stream =
+ ndk::SharedRefBase::make<StreamOutUsb>(sourceMetadata, std::move(context), offloadInfo);
+ if (auto status = initInstance(stream); !status.isOk()) {
+ return status;
+ }
+ *result = std::move(stream);
+ return ndk::ScopedAStatus::ok();
+}
+
+StreamOutUsb::StreamOutUsb(const SourceMetadata& sourceMetadata, StreamContext&& context,
+ const std::optional<AudioOffloadInfo>& offloadInfo)
+ : StreamOut(
+ sourceMetadata, std::move(context),
+ [](const StreamContext& ctx) -> DriverInterface* {
+ return new DriverUsb(ctx, false /*isInput*/);
+ },
+ [](const StreamContext& ctx, DriverInterface* driver) -> StreamWorkerInterface* {
+ // The default worker implementation is used.
+ return new StreamOutWorker(ctx, driver);
+ },
+ offloadInfo) {}
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/usb/UsbAlsaUtils.cpp b/audio/aidl/default/usb/UsbAlsaUtils.cpp
new file mode 100644
index 0000000..3c79e1d
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaUtils.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2023 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 <map>
+#include <set>
+
+#include <Utils.h>
+#include <aidl/android/media/audio/common/AudioFormatType.h>
+#include <aidl/android/media/audio/common/PcmType.h>
+
+#include "UsbAlsaUtils.h"
+#include "core-impl/utils.h"
+
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::PcmType;
+using android::hardware::audio::common::getChannelCount;
+
+namespace aidl::android::hardware::audio::core::usb {
+
+namespace {
+
+using AudioChannelCountToMaskMap = std::map<unsigned int, AudioChannelLayout>;
+using AudioFormatDescToPcmFormatMap = std::map<AudioFormatDescription, enum pcm_format>;
+using PcmFormatToAudioFormatDescMap = std::map<enum pcm_format, AudioFormatDescription>;
+
+static const AudioChannelLayout INVALID_CHANNEL_LAYOUT =
+ AudioChannelLayout::make<AudioChannelLayout::Tag::invalid>(0);
+
+#define DEFINE_CHANNEL_LAYOUT_MASK(n) \
+ AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(AudioChannelLayout::LAYOUT_##n)
+
+static const std::set<AudioChannelLayout> SUPPORTED_OUT_CHANNEL_LAYOUTS = {
+ DEFINE_CHANNEL_LAYOUT_MASK(MONO), DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
+ DEFINE_CHANNEL_LAYOUT_MASK(2POINT1), DEFINE_CHANNEL_LAYOUT_MASK(QUAD),
+ DEFINE_CHANNEL_LAYOUT_MASK(PENTA), DEFINE_CHANNEL_LAYOUT_MASK(5POINT1),
+ DEFINE_CHANNEL_LAYOUT_MASK(6POINT1), DEFINE_CHANNEL_LAYOUT_MASK(7POINT1),
+ DEFINE_CHANNEL_LAYOUT_MASK(7POINT1POINT4), DEFINE_CHANNEL_LAYOUT_MASK(22POINT2),
+};
+
+static const std::set<AudioChannelLayout> SUPPORTED_IN_CHANNEL_LAYOUTS = {
+ DEFINE_CHANNEL_LAYOUT_MASK(MONO),
+ DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
+};
+
+#define DEFINE_CHANNEL_INDEX_MASK(n) \
+ AudioChannelLayout::make<AudioChannelLayout::Tag::indexMask>(AudioChannelLayout::INDEX_MASK_##n)
+
+static const std::set<AudioChannelLayout> SUPPORTED_INDEX_CHANNEL_LAYOUTS = {
+ DEFINE_CHANNEL_INDEX_MASK(1), DEFINE_CHANNEL_INDEX_MASK(2), DEFINE_CHANNEL_INDEX_MASK(3),
+ DEFINE_CHANNEL_INDEX_MASK(4), DEFINE_CHANNEL_INDEX_MASK(5), DEFINE_CHANNEL_INDEX_MASK(6),
+ DEFINE_CHANNEL_INDEX_MASK(7), DEFINE_CHANNEL_INDEX_MASK(8), DEFINE_CHANNEL_INDEX_MASK(9),
+ DEFINE_CHANNEL_INDEX_MASK(10), DEFINE_CHANNEL_INDEX_MASK(11), DEFINE_CHANNEL_INDEX_MASK(12),
+ DEFINE_CHANNEL_INDEX_MASK(13), DEFINE_CHANNEL_INDEX_MASK(14), DEFINE_CHANNEL_INDEX_MASK(15),
+ DEFINE_CHANNEL_INDEX_MASK(16), DEFINE_CHANNEL_INDEX_MASK(17), DEFINE_CHANNEL_INDEX_MASK(18),
+ DEFINE_CHANNEL_INDEX_MASK(19), DEFINE_CHANNEL_INDEX_MASK(20), DEFINE_CHANNEL_INDEX_MASK(21),
+ DEFINE_CHANNEL_INDEX_MASK(22), DEFINE_CHANNEL_INDEX_MASK(23), DEFINE_CHANNEL_INDEX_MASK(24),
+};
+
+static AudioChannelCountToMaskMap make_ChannelCountToMaskMap(
+ const std::set<AudioChannelLayout>& channelMasks) {
+ AudioChannelCountToMaskMap channelMaskToCountMap;
+ for (const auto& channelMask : channelMasks) {
+ channelMaskToCountMap.emplace(getChannelCount(channelMask), channelMask);
+ }
+ return channelMaskToCountMap;
+}
+
+const AudioChannelCountToMaskMap& getSupportedChannelOutLayoutMap() {
+ static const AudioChannelCountToMaskMap outLayouts =
+ make_ChannelCountToMaskMap(SUPPORTED_OUT_CHANNEL_LAYOUTS);
+ return outLayouts;
+}
+
+const AudioChannelCountToMaskMap& getSupportedChannelInLayoutMap() {
+ static const AudioChannelCountToMaskMap inLayouts =
+ make_ChannelCountToMaskMap(SUPPORTED_IN_CHANNEL_LAYOUTS);
+ return inLayouts;
+}
+
+const AudioChannelCountToMaskMap& getSupportedChannelIndexLayoutMap() {
+ static const AudioChannelCountToMaskMap indexLayouts =
+ make_ChannelCountToMaskMap(SUPPORTED_INDEX_CHANNEL_LAYOUTS);
+ return indexLayouts;
+}
+
+AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
+ AudioFormatDescription result;
+ result.type = type;
+ return result;
+}
+
+AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
+ auto result = make_AudioFormatDescription(AudioFormatType::PCM);
+ result.pcm = pcm;
+ return result;
+}
+
+const AudioFormatDescToPcmFormatMap& getAudioFormatDescriptorToPcmFormatMap() {
+ static const AudioFormatDescToPcmFormatMap formatDescToPcmFormatMap = {
+ {make_AudioFormatDescription(PcmType::UINT_8_BIT), PCM_FORMAT_S8},
+ {make_AudioFormatDescription(PcmType::INT_16_BIT), PCM_FORMAT_S16_LE},
+ {make_AudioFormatDescription(PcmType::INT_24_BIT), PCM_FORMAT_S24_LE},
+ {make_AudioFormatDescription(PcmType::FIXED_Q_8_24), PCM_FORMAT_S24_3LE},
+ {make_AudioFormatDescription(PcmType::INT_32_BIT), PCM_FORMAT_S32_LE},
+ {make_AudioFormatDescription(PcmType::FLOAT_32_BIT), PCM_FORMAT_FLOAT_LE},
+ };
+ return formatDescToPcmFormatMap;
+}
+
+static PcmFormatToAudioFormatDescMap make_PcmFormatToAudioFormatDescMap(
+ const AudioFormatDescToPcmFormatMap& formatDescToPcmFormatMap) {
+ PcmFormatToAudioFormatDescMap result;
+ for (const auto& formatPair : formatDescToPcmFormatMap) {
+ result.emplace(formatPair.second, formatPair.first);
+ }
+ return result;
+}
+
+const PcmFormatToAudioFormatDescMap& getPcmFormatToAudioFormatDescMap() {
+ static const PcmFormatToAudioFormatDescMap pcmFormatToFormatDescMap =
+ make_PcmFormatToAudioFormatDescMap(getAudioFormatDescriptorToPcmFormatMap());
+ return pcmFormatToFormatDescMap;
+}
+
+} // namespace
+
+AudioChannelLayout getChannelLayoutMaskFromChannelCount(unsigned int channelCount, int isInput) {
+ return findValueOrDefault(
+ isInput ? getSupportedChannelInLayoutMap() : getSupportedChannelOutLayoutMap(),
+ channelCount, INVALID_CHANNEL_LAYOUT);
+}
+
+AudioChannelLayout getChannelIndexMaskFromChannelCount(unsigned int channelCount) {
+ return findValueOrDefault(getSupportedChannelIndexLayoutMap(), channelCount,
+ INVALID_CHANNEL_LAYOUT);
+}
+
+unsigned int getChannelCountFromChannelMask(const AudioChannelLayout& channelMask, bool isInput) {
+ switch (channelMask.getTag()) {
+ case AudioChannelLayout::Tag::layoutMask: {
+ return findKeyOrDefault(
+ isInput ? getSupportedChannelInLayoutMap() : getSupportedChannelOutLayoutMap(),
+ (unsigned int)getChannelCount(channelMask), 0u /*defaultValue*/);
+ }
+ case AudioChannelLayout::Tag::indexMask: {
+ return findKeyOrDefault(getSupportedChannelIndexLayoutMap(),
+ (unsigned int)getChannelCount(channelMask),
+ 0u /*defaultValue*/);
+ }
+ case AudioChannelLayout::Tag::none:
+ case AudioChannelLayout::Tag::invalid:
+ case AudioChannelLayout::Tag::voiceMask:
+ default:
+ return 0;
+ }
+}
+
+AudioFormatDescription legacy2aidl_pcm_format_AudioFormatDescription(enum pcm_format legacy) {
+ return findValueOrDefault(getPcmFormatToAudioFormatDescMap(), legacy, AudioFormatDescription());
+}
+
+pcm_format aidl2legacy_AudioFormatDescription_pcm_format(const AudioFormatDescription& aidl) {
+ return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
+}
+
+} // namespace aidl::android::hardware::audio::core::usb
\ No newline at end of file
diff --git a/audio/aidl/default/usb/UsbAlsaUtils.h b/audio/aidl/default/usb/UsbAlsaUtils.h
new file mode 100644
index 0000000..2d2f0f4
--- /dev/null
+++ b/audio/aidl/default/usb/UsbAlsaUtils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioFormatDescription.h>
+
+extern "C" {
+#include <tinyalsa/pcm.h>
+}
+
+namespace aidl::android::hardware::audio::core::usb {
+
+::aidl::android::media::audio::common::AudioChannelLayout getChannelLayoutMaskFromChannelCount(
+ unsigned int channelCount, int isInput);
+::aidl::android::media::audio::common::AudioChannelLayout getChannelIndexMaskFromChannelCount(
+ unsigned int channelCount);
+unsigned int getChannelCountFromChannelMask(
+ const ::aidl::android::media::audio::common::AudioChannelLayout& channelMask, bool isInput);
+::aidl::android::media::audio::common::AudioFormatDescription
+legacy2aidl_pcm_format_AudioFormatDescription(enum pcm_format legacy);
+pcm_format aidl2legacy_AudioFormatDescription_pcm_format(
+ const ::aidl::android::media::audio::common::AudioFormatDescription& aidl);
+
+} // namespace aidl::android::hardware::audio::core::usb
\ No newline at end of file
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index cc51937..d75e4e0 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -30,6 +30,9 @@
using aidl::android::hardware::audio::effect::kVirtualizerSwImplUUID;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::audio::effect::VirtualizerSw;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioUuid;
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
@@ -60,9 +63,16 @@
namespace aidl::android::hardware::audio::effect {
const std::string VirtualizerSw::kEffectName = "VirtualizerSw";
-const bool VirtualizerSw::kStrengthSupported = true;
-const Virtualizer::Capability VirtualizerSw::kCapability = {
- .maxStrengthPm = 1000, .strengthSupported = kStrengthSupported};
+
+const std::vector<Range::VirtualizerRange> VirtualizerSw::kRanges = {
+ MAKE_RANGE(Virtualizer, strengthPm, 0, 1000),
+ /* speakerAngle is get-only, set min > max */
+ MAKE_RANGE(Virtualizer, speakerAngles, {Virtualizer::ChannelAngle({.channel = 1})},
+ {Virtualizer::ChannelAngle({.channel = 0})})};
+
+const Capability VirtualizerSw::kCapability = {
+ .range = Range::make<Range::virtualizer>(VirtualizerSw::kRanges)};
+
const Descriptor VirtualizerSw::kDescriptor = {
.common = {.id = {.type = kVirtualizerTypeUUID,
.uuid = kVirtualizerSwImplUUID,
@@ -72,7 +82,7 @@
.volume = Flags::Volume::CTRL},
.name = VirtualizerSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::virtualizer>(VirtualizerSw::kCapability)};
+ .capability = VirtualizerSw::kCapability};
ndk::ScopedAStatus VirtualizerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -85,18 +95,25 @@
"EffectNotSupported");
auto& vrParam = specific.get<Parameter::Specific::virtualizer>();
+ RETURN_IF(!inRange(vrParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = vrParam.getTag();
switch (tag) {
case Virtualizer::strengthPm: {
- RETURN_IF(!kStrengthSupported, EX_ILLEGAL_ARGUMENT, "SettingStrengthNotSupported");
-
RETURN_IF(mContext->setVrStrength(vrParam.get<Virtualizer::strengthPm>()) !=
RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "strengthPmNotSupported");
+ EX_ILLEGAL_ARGUMENT, "setStrengthPmFailed");
return ndk::ScopedAStatus::ok();
}
- default: {
+ case Virtualizer::device: {
+ RETURN_IF(mContext->setForcedDevice(vrParam.get<Virtualizer::device>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setDeviceFailed");
+ return ndk::ScopedAStatus::ok();
+ }
+ case Virtualizer::speakerAngles:
+ FALLTHROUGH_INTENDED;
+ case Virtualizer::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
@@ -113,10 +130,13 @@
switch (vrIdTag) {
case Virtualizer::Id::commonTag:
return getParameterVirtualizer(vrId.get<Virtualizer::Id::commonTag>(), specific);
- default:
+ case Virtualizer::Id::speakerAnglesPayload:
+ return getSpeakerAngles(vrId.get<Virtualizer::Id::speakerAnglesPayload>(), specific);
+ case Virtualizer::Id::vendorExtensionTag: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
+ }
}
}
@@ -130,7 +150,13 @@
vrParam.set<Virtualizer::strengthPm>(mContext->getVrStrength());
break;
}
- default: {
+ case Virtualizer::device: {
+ vrParam.set<Virtualizer::device>(mContext->getForcedDevice());
+ break;
+ }
+ case Virtualizer::speakerAngles:
+ FALLTHROUGH_INTENDED;
+ case Virtualizer::vendor: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
"VirtualizerTagNotSupported");
@@ -141,6 +167,31 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus VirtualizerSw::getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
+ Parameter::Specific* specific) {
+ std::vector<Virtualizer::ChannelAngle> angles;
+ const auto chNum = ::android::hardware::audio::common::getChannelCount(payload.layout);
+ if (chNum == 1) {
+ angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
+ .azimuthDegree = 0,
+ .elevationDegree = 0}};
+ } else if (chNum == 2) {
+ angles = {{.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_LEFT,
+ .azimuthDegree = -90,
+ .elevationDegree = 0},
+ {.channel = (int32_t)AudioChannelLayout::CHANNEL_FRONT_RIGHT,
+ .azimuthDegree = 90,
+ .elevationDegree = 0}};
+ } else {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "supportUpTo2Ch");
+ }
+
+ Virtualizer param = Virtualizer::make<Virtualizer::speakerAngles>(angles);
+ specific->set<Parameter::Specific::virtualizer>(param);
+ return ndk::ScopedAStatus::ok();
+}
+
std::shared_ptr<EffectContext> VirtualizerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
@@ -173,11 +224,6 @@
}
RetCode VirtualizerSwContext::setVrStrength(int strength) {
- if (strength < 0 || strength > VirtualizerSw::kCapability.maxStrengthPm) {
- LOG(ERROR) << __func__ << " invalid strength: " << strength;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new strength
mStrength = strength;
return RetCode::SUCCESS;
}
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index 0f294cd..5c5b616 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -34,16 +34,24 @@
}
RetCode setVrStrength(int strength);
int getVrStrength() const { return mStrength; }
+ RetCode setForcedDevice(
+ const ::aidl::android::media::audio::common::AudioDeviceDescription& device) {
+ mForceDevice = device;
+ return RetCode::SUCCESS;
+ }
+ aidl::android::media::audio::common::AudioDeviceDescription getForcedDevice() const {
+ return mForceDevice;
+ }
private:
int mStrength = 0;
+ ::aidl::android::media::audio::common::AudioDeviceDescription mForceDevice;
};
class VirtualizerSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const bool kStrengthSupported;
- static const Virtualizer::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
VirtualizerSw() { LOG(DEBUG) << __func__; }
~VirtualizerSw() {
@@ -64,9 +72,12 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const std::vector<Range::VirtualizerRange> kRanges;
std::shared_ptr<VirtualizerSwContext> mContext;
ndk::ScopedAStatus getParameterVirtualizer(const Virtualizer::Tag& tag,
Parameter::Specific* specific);
+ ndk::ScopedAStatus getSpeakerAngles(const Virtualizer::SpeakerAnglesPayload payload,
+ Parameter::Specific* specific);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 614988c..deb3204 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -55,12 +55,15 @@
namespace aidl::android::hardware::audio::effect {
const std::string VisualizerSw::kEffectName = "VisualizerSw";
+
/* capabilities */
-const Visualizer::CaptureSamplesRange VisualizerSwContext::kCaptureSamplesRange = {
- VisualizerSwContext::kMinCaptureSize, VisualizerSwContext::kMaxCaptureSize};
-const Visualizer::Capability VisualizerSw::kCapability = {
- .maxLatencyMs = VisualizerSwContext::kMaxLatencyMs,
- .captureSampleRange = VisualizerSwContext::kCaptureSamplesRange};
+const std::vector<Range::VisualizerRange> VisualizerSw::kRanges = {
+ MAKE_RANGE(Visualizer, latencyMs, 0, VisualizerSwContext::kMaxLatencyMs),
+ MAKE_RANGE(Visualizer, captureSamples, VisualizerSwContext::kMinCaptureSize,
+ VisualizerSwContext::kMaxCaptureSize)};
+
+const Capability VisualizerSw::kCapability = {
+ .range = Range::make<Range::visualizer>(VisualizerSw::kRanges)};
const Descriptor VisualizerSw::kDescriptor = {
.common = {.id = {.type = kVisualizerTypeUUID,
@@ -71,7 +74,7 @@
.volume = Flags::Volume::CTRL},
.name = VisualizerSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::visualizer>(VisualizerSw::kCapability)};
+ .capability = VisualizerSw::kCapability};
ndk::ScopedAStatus VisualizerSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -84,34 +87,33 @@
"EffectNotSupported");
auto& vsParam = specific.get<Parameter::Specific::visualizer>();
+ RETURN_IF(!inRange(vsParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = vsParam.getTag();
switch (tag) {
case Visualizer::captureSamples: {
RETURN_IF(mContext->setVsCaptureSize(vsParam.get<Visualizer::captureSamples>()) !=
RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "captureSizeNotSupported");
+ EX_ILLEGAL_ARGUMENT, "setCaptureSizeFailed");
return ndk::ScopedAStatus::ok();
}
case Visualizer::scalingMode: {
RETURN_IF(mContext->setVsScalingMode(vsParam.get<Visualizer::scalingMode>()) !=
RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "scalingModeNotSupported");
+ EX_ILLEGAL_ARGUMENT, "setScalingModeFailed");
return ndk::ScopedAStatus::ok();
}
case Visualizer::measurementMode: {
RETURN_IF(mContext->setVsMeasurementMode(vsParam.get<Visualizer::measurementMode>()) !=
RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "measurementModeNotSupported");
+ EX_ILLEGAL_ARGUMENT, "setMeasurementModeFailed");
return ndk::ScopedAStatus::ok();
}
- case Visualizer::setOnlyParameters: {
- return setSetOnlyParameterVisualizer(vsParam.get<Visualizer::setOnlyParameters>());
- }
- case Visualizer::getOnlyParameters: {
- LOG(ERROR) << __func__ << " unsupported settable getOnlyParam";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "SetofGetOnlyParamsNotSupported");
+ case Visualizer::latencyMs: {
+ RETURN_IF(mContext->setVsLatency(vsParam.get<Visualizer::latencyMs>()) !=
+ RetCode::SUCCESS,
+ EX_ILLEGAL_ARGUMENT, "setLatencyFailed");
+ return ndk::ScopedAStatus::ok();
}
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
@@ -121,18 +123,6 @@
}
}
-ndk::ScopedAStatus VisualizerSw::setSetOnlyParameterVisualizer(
- Visualizer::SetOnlyParameters setOnlyParam) {
- auto tag = setOnlyParam.getTag();
- RETURN_IF(Visualizer::SetOnlyParameters::latencyMs != tag, EX_ILLEGAL_ARGUMENT,
- "SetOnlyParametersTagNotSupported");
- RETURN_IF(
- mContext->setVsLatency(setOnlyParam.get<Visualizer::SetOnlyParameters::latencyMs>()) !=
- RetCode::SUCCESS,
- EX_ILLEGAL_ARGUMENT, "latencyNotSupported");
- return ndk::ScopedAStatus::ok();
-}
-
ndk::ScopedAStatus VisualizerSw::getParameterSpecific(const Parameter::Id& id,
Parameter::Specific* specific) {
auto tag = id.getTag();
@@ -142,14 +132,6 @@
switch (vsIdTag) {
case Visualizer::Id::commonTag:
return getParameterVisualizer(vsId.get<Visualizer::Id::commonTag>(), specific);
- case Visualizer::Id::getOnlyParamTag:
- return getGetOnlyParameterVisualizer(vsId.get<Visualizer::Id::getOnlyParamTag>(),
- specific);
- case Visualizer::Id::setOnlyParamTag: {
- LOG(ERROR) << __func__ << " unsupported gettable setOnlyParam";
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "GetofSetOnlyParamsNotSupported");
- }
default:
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -174,6 +156,18 @@
vsParam.set<Visualizer::measurementMode>(mContext->getVsMeasurementMode());
break;
}
+ case Visualizer::measurement: {
+ vsParam.set<Visualizer::measurement>(mContext->getVsMeasurement());
+ break;
+ }
+ case Visualizer::captureSampleBuffer: {
+ vsParam.set<Visualizer::captureSampleBuffer>(mContext->getVsCaptureSampleBuffer());
+ break;
+ }
+ case Visualizer::latencyMs: {
+ vsParam.set<Visualizer::latencyMs>(mContext->getVsLatency());
+ break;
+ }
default: {
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
@@ -184,32 +178,6 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus VisualizerSw::getGetOnlyParameterVisualizer(
- const Visualizer::GetOnlyParameters::Tag& tag, Parameter::Specific* specific) {
- Visualizer::GetOnlyParameters getOnlyParam;
- switch (tag) {
- case Visualizer::GetOnlyParameters::measurement: {
- getOnlyParam.set<Visualizer::GetOnlyParameters::measurement>(
- mContext->getVsMeasurement());
- break;
- }
- case Visualizer::GetOnlyParameters::captureSampleBuffer: {
- getOnlyParam.set<Visualizer::GetOnlyParameters::captureSampleBuffer>(
- mContext->getVsCaptureSampleBuffer());
- break;
- }
- default: {
- LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
- return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
- EX_ILLEGAL_ARGUMENT, "GetOnlyParameterTagNotSupported");
- }
- }
- Visualizer vsParam;
- vsParam.set<Visualizer::getOnlyParameters>(getOnlyParam);
- specific->set<Parameter::Specific::visualizer>(vsParam);
- return ndk::ScopedAStatus::ok();
-}
-
std::shared_ptr<EffectContext> VisualizerSw::createContext(const Parameter::Common& common) {
if (mContext) {
LOG(DEBUG) << __func__ << " context already exist";
@@ -242,34 +210,21 @@
}
RetCode VisualizerSwContext::setVsCaptureSize(int captureSize) {
- if (captureSize < VisualizerSw::kCapability.captureSampleRange.min ||
- captureSize > VisualizerSw::kCapability.captureSampleRange.max) {
- LOG(ERROR) << __func__ << " invalid captureSize " << captureSize;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new captureSize
mCaptureSize = captureSize;
return RetCode::SUCCESS;
}
RetCode VisualizerSwContext::setVsScalingMode(Visualizer::ScalingMode scalingMode) {
- // TODO : Add implementation to apply new scalingMode
mScalingMode = scalingMode;
return RetCode::SUCCESS;
}
RetCode VisualizerSwContext::setVsMeasurementMode(Visualizer::MeasurementMode measurementMode) {
- // TODO : Add implementation to apply new measurementMode
mMeasurementMode = measurementMode;
return RetCode::SUCCESS;
}
RetCode VisualizerSwContext::setVsLatency(int latency) {
- if (latency < 0 || latency > VisualizerSw::kCapability.maxLatencyMs) {
- LOG(ERROR) << __func__ << " invalid latency " << latency;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to modify latency
mLatency = latency;
return RetCode::SUCCESS;
}
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index e9d46d7..ee7276a 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -30,7 +30,6 @@
static const int kMaxCaptureSize = 0x400;
static const int kMaxLatencyMs = 3000;
static const int kMaxCaptureBufSize = 0xffff;
- static const Visualizer::CaptureSamplesRange kCaptureSamplesRange;
VisualizerSwContext(int statusDepth, const Parameter::Common& common)
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
@@ -48,8 +47,9 @@
Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
RetCode setVsLatency(int latency);
+ int getVsLatency() const { return mLatency; }
- Visualizer::GetOnlyParameters::Measurement getVsMeasurement() const { return mMeasurement; }
+ Visualizer::Measurement getVsMeasurement() const { return mMeasurement; }
std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
private:
@@ -57,14 +57,14 @@
Visualizer::ScalingMode mScalingMode = Visualizer::ScalingMode::NORMALIZED;
Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
int mLatency = 0;
- const Visualizer::GetOnlyParameters::Measurement mMeasurement = {0, 0};
+ const Visualizer::Measurement mMeasurement = {0, 0};
std::vector<uint8_t> mCaptureSampleBuffer;
};
class VisualizerSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const Visualizer::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
VisualizerSw() { LOG(DEBUG) << __func__; }
~VisualizerSw() {
@@ -85,12 +85,9 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const std::vector<Range::VisualizerRange> kRanges;
std::shared_ptr<VisualizerSwContext> mContext;
-
- ndk::ScopedAStatus setSetOnlyParameterVisualizer(Visualizer::SetOnlyParameters setOnlyParam);
ndk::ScopedAStatus getParameterVisualizer(const Visualizer::Tag& tag,
Parameter::Specific* specific);
- ndk::ScopedAStatus getGetOnlyParameterVisualizer(const Visualizer::GetOnlyParameters::Tag& tag,
- Parameter::Specific* specific);
};
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 64301dc..796c332 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -60,7 +60,11 @@
namespace aidl::android::hardware::audio::effect {
const std::string VolumeSw::kEffectName = "VolumeSw";
-const Volume::Capability VolumeSw::kCapability = {.minLevelDb = -9600, .maxLevelDb = 0};
+
+const std::vector<Range::VolumeRange> VolumeSw::kRanges = {MAKE_RANGE(Volume, levelDb, -9600, 0)};
+
+const Capability VolumeSw::kCapability = {.range = Range::make<Range::volume>(VolumeSw::kRanges)};
+
const Descriptor VolumeSw::kDescriptor = {
.common = {.id = {.type = kVolumeTypeUUID,
.uuid = kVolumeSwImplUUID,
@@ -70,7 +74,7 @@
.volume = Flags::Volume::CTRL},
.name = VolumeSw::kEffectName,
.implementor = "The Android Open Source Project"},
- .capability = Capability::make<Capability::volume>(VolumeSw::kCapability)};
+ .capability = VolumeSw::kCapability};
ndk::ScopedAStatus VolumeSw::getDescriptor(Descriptor* _aidl_return) {
LOG(DEBUG) << __func__ << kDescriptor.toString();
@@ -83,6 +87,7 @@
"EffectNotSupported");
auto& volParam = specific.get<Parameter::Specific::volume>();
+ RETURN_IF(!inRange(volParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
auto tag = volParam.getTag();
switch (tag) {
@@ -177,11 +182,6 @@
}
RetCode VolumeSwContext::setVolLevel(int level) {
- if (level < VolumeSw::kCapability.minLevelDb || level > VolumeSw::kCapability.maxLevelDb) {
- LOG(ERROR) << __func__ << " invalid level " << level;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new level
mLevel = level;
return RetCode::SUCCESS;
}
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index b6f6077..2dd4324 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -49,7 +49,7 @@
class VolumeSw final : public EffectImpl {
public:
static const std::string kEffectName;
- static const Volume::Capability kCapability;
+ static const Capability kCapability;
static const Descriptor kDescriptor;
VolumeSw() { LOG(DEBUG) << __func__; }
~VolumeSw() {
@@ -70,6 +70,7 @@
std::string getEffectName() override { return kEffectName; }
private:
+ static const std::vector<Range::VolumeRange> kRanges;
std::shared_ptr<VolumeSwContext> mContext;
ndk::ScopedAStatus getParameterVolume(const Volume::Tag& tag, Parameter::Specific* specific);
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index f9d12dd..8db8eaf 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -141,9 +141,15 @@
}
cc_test {
- name: "VtsHalAGCTargetTest",
+ name: "VtsHalAGC1TargetTest",
defaults: ["VtsHalAudioTargetTestDefaults"],
- srcs: ["VtsHalAGCTargetTest.cpp"],
+ srcs: ["VtsHalAGC1TargetTest.cpp"],
+}
+
+cc_test {
+ name: "VtsHalAGC2TargetTest",
+ defaults: ["VtsHalAudioTargetTestDefaults"],
+ srcs: ["VtsHalAGC2TargetTest.cpp"],
}
cc_test {
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 7222d4f..5ed8e1f 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -19,6 +19,7 @@
#include <algorithm>
#include <memory>
#include <string>
+#include <type_traits>
#include <unordered_map>
#include <vector>
@@ -27,6 +28,7 @@
#include <aidl/android/media/audio/common/AudioChannelLayout.h>
#include <android/binder_auto_utils.h>
#include <fmq/AidlMessageQueue.h>
+#include <system/audio_effects/aidl_effects_utils.h>
#include "AudioHalBinderServiceUtil.h"
#include "EffectFactoryHelper.h"
@@ -37,6 +39,7 @@
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
using aidl::android::hardware::audio::effect::State;
using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using aidl::android::media::audio::common::AudioChannelLayout;
@@ -148,16 +151,22 @@
}
static void readFromFmq(std::unique_ptr<StatusMQ>& statusMq, size_t statusNum,
std::unique_ptr<DataMQ>& dataMq, size_t expectFloats,
- std::vector<float>& buffer) {
+ std::vector<float>& buffer,
+ std::optional<int> expectStatus = STATUS_OK) {
+ if (0 == statusNum) {
+ ASSERT_EQ(0ul, statusMq->availableToRead());
+ return;
+ }
IEffect::Status status{};
ASSERT_TRUE(statusMq->readBlocking(&status, statusNum));
- ASSERT_EQ(STATUS_OK, status.status);
- if (statusNum != 0) {
- ASSERT_EQ(expectFloats, (unsigned)status.fmqProduced);
- ASSERT_EQ(expectFloats, dataMq->availableToRead());
- if (expectFloats != 0) {
- ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
- }
+ if (expectStatus.has_value()) {
+ ASSERT_EQ(expectStatus.value(), status.status);
+ }
+
+ ASSERT_EQ(expectFloats, (unsigned)status.fmqProduced);
+ ASSERT_EQ(expectFloats, dataMq->availableToRead());
+ if (expectFloats != 0) {
+ ASSERT_TRUE(dataMq->read(buffer.data(), expectFloats));
}
}
static Parameter::Common createParamCommon(
@@ -199,4 +208,58 @@
std::unique_ptr<DataMQ> inputMQ;
std::unique_ptr<DataMQ> outputMQ;
};
+
+ template <typename T, Range::Tag tag>
+ static bool isParameterValid(const T& target, const Descriptor& desc) {
+ if (desc.capability.range.getTag() != tag) {
+ return true;
+ }
+ const auto& ranges = desc.capability.range.get<tag>();
+ return inRange(target, ranges);
+ }
+
+ /**
+ * Add to test value set: (min+max)/2, minimum/maximum numeric limits, and min-1/max+1 if
+ * result still in numeric limits after -1/+1.
+ * Only use this when the type of test value is basic type (std::is_arithmetic return true).
+ */
+ template <typename S, typename = std::enable_if_t<std::is_arithmetic_v<S>>>
+ static std::set<S> expandTestValueBasic(std::set<S>& s) {
+ const auto min = *s.begin(), max = *s.rbegin();
+ const auto minLimit = std::numeric_limits<S>::min(),
+ maxLimit = std::numeric_limits<S>::max();
+ if (s.size()) {
+ s.insert(min + (max - min) / 2);
+ if (min != minLimit) {
+ s.insert(min - 1);
+ }
+ if (max != maxLimit) {
+ s.insert(max + 1);
+ }
+ }
+ s.insert(minLimit);
+ s.insert(maxLimit);
+ return s;
+ }
+
+ template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+ static std::set<S> getTestValueSet(
+ std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList,
+ Functor functor) {
+ std::set<S> result;
+ for (const auto& [_, desc] : kFactoryDescList) {
+ if (desc.capability.range.getTag() == R) {
+ const auto& ranges = desc.capability.range.get<R>();
+ for (const auto& range : ranges) {
+ if (range.min.getTag() == tag) {
+ result.insert(range.min.template get<tag>());
+ }
+ if (range.max.getTag() == tag) {
+ result.insert(range.max.template get<tag>());
+ }
+ }
+ }
+ }
+ return functor(result);
+ }
};
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index c3427c8..39be191 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -23,16 +23,17 @@
#define LOG_TAG "VtsHalAECParamTest"
#include "EffectHelper.h"
+#include "effect-impl/EffectTypes.h"
using namespace android;
using aidl::android::hardware::audio::effect::AcousticEchoCanceler;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::hardware::audio::effect::kAcousticEchoCancelerTypeUUID;
using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
enum ParamName { PARAM_INSTANCE_NAME, PARAM_ECHO_DELAY, PARAM_MOBILE_MODE };
using AECParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
@@ -87,7 +88,8 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(tag, aec, desc);
+ const bool valid =
+ isParameterValid<AcousticEchoCanceler, Range::acousticEchoCanceler>(aec, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -124,54 +126,6 @@
mTags.push_back({AcousticEchoCanceler::mobileMode, aec});
}
- bool isTagInRange(const AcousticEchoCanceler::Tag& tag, const AcousticEchoCanceler& aec,
- const Descriptor& desc) const {
- const AcousticEchoCanceler::Capability& aecCap =
- desc.capability.get<Capability::acousticEchoCanceler>();
- switch (tag) {
- case AcousticEchoCanceler::echoDelayUs: {
- return isEchoDelayInRange(aecCap, aec.get<AcousticEchoCanceler::echoDelayUs>());
- }
- case AcousticEchoCanceler::mobileMode: {
- bool mode = aec.get<AcousticEchoCanceler::mobileMode>();
- return isMobileModeValid(aecCap, mode);
- }
- default:
- return false;
- }
- }
-
- bool isEchoDelayInRange(const AcousticEchoCanceler::Capability& cap, int delay) const {
- return (delay >= 0 && delay <= cap.maxEchoDelayUs);
- }
-
- bool isMobileModeValid(const AcousticEchoCanceler::Capability& cap, bool mode) const {
- if (cap.supportMobileMode) {
- return true;
- } else {
- return mode == false;
- }
- }
-
- static std::unordered_set<int> getEchoDelayTestValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kAcousticEchoCancelerTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::acousticEchoCanceler>()
- .maxEchoDelayUs <
- b.second.capability.get<Capability::acousticEchoCanceler>()
- .maxEchoDelayUs;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxDelay =
- max->second.capability.get<Capability::acousticEchoCanceler>().maxEchoDelayUs;
- return {-1, 0, maxDelay - 1, maxDelay, maxDelay + 1};
- }
static std::unordered_set<bool> getMobileModeValues() { return {true, false}; }
private:
@@ -189,12 +143,20 @@
SetAndGetParameters();
}
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
AECParamTest, AECParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kAcousticEchoCancelerTypeUUID)),
- testing::ValuesIn(AECParamTest::getEchoDelayTestValues()),
- testing::ValuesIn(AECParamTest::getMobileModeValues())),
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kAcousticEchoCancelerTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<AcousticEchoCanceler, int,
+ Range::acousticEchoCanceler,
+ AcousticEchoCanceler::echoDelayUs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<AcousticEchoCanceler, bool,
+ Range::acousticEchoCanceler,
+ AcousticEchoCanceler::mobileMode>(
+ kDescPair, EffectHelper::expandTestValueBasic<bool>))),
[](const testing::TestParamInfo<AECParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string echoDelay = std::to_string(std::get<PARAM_ECHO_DELAY>(info.param));
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
new file mode 100644
index 0000000..a6fc1aa
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2023 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 <Utils.h>
+#include <aidl/Vintf.h>
+
+#define LOG_TAG "VtsHalAGC1ParamTest"
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV1;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kAutomaticGainControlV1TypeUUID;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName {
+ PARAM_INSTANCE_NAME,
+ PARAM_TARGET_PEAK_LEVEL,
+ PARAM_MAX_COMPRESSION_GAIN,
+ PARAM_ENABLE_LIMITER
+};
+using AGC1ParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* targetPeakLevel */,
+ int /* maxCompressionGain */, bool /* enableLimiter */>;
+
+class AGC1ParamTest : public ::testing::TestWithParam<AGC1ParamTestParam>, public EffectHelper {
+ public:
+ AGC1ParamTest()
+ : mTargetPeakLevel(std::get<PARAM_TARGET_PEAK_LEVEL>(GetParam())),
+ mMaxCompressionGain(std::get<PARAM_MAX_COMPRESSION_GAIN>(GetParam())),
+ mEnableLimiter(std::get<PARAM_ENABLE_LIMITER>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ ASSERT_NE(nullptr, mFactory);
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+ Parameter::Specific specific = getDefaultParamSpecific();
+ Parameter::Common common = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ ASSERT_NE(nullptr, mEffect);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ }
+
+ Parameter::Specific getDefaultParamSpecific() {
+ AutomaticGainControlV1 AGC1 =
+ AutomaticGainControlV1::make<AutomaticGainControlV1::targetPeakLevelDbFs>(0);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::automaticGainControlV1>(AGC1);
+ return specific;
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor mDescriptor;
+ int mTargetPeakLevel;
+ int mMaxCompressionGain;
+ bool mEnableLimiter;
+
+ void SetAndGetParameters() {
+ for (auto& it : mTags) {
+ auto& tag = it.first;
+ auto& AGC1 = it.second;
+
+ // validate parameter
+ Descriptor desc;
+ ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+ const bool valid =
+ isParameterValid<AutomaticGainControlV1, Range::automaticGainControlV1>(AGC1,
+ desc);
+ const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+ // set parameter
+ Parameter expectParam;
+ Parameter::Specific specific;
+ specific.set<Parameter::Specific::automaticGainControlV1>(AGC1);
+ expectParam.set<Parameter::specific>(specific);
+ EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+ // only get if parameter in range and set success
+ if (expected == EX_NONE) {
+ Parameter getParam;
+ Parameter::Id id;
+ AutomaticGainControlV1::Id specificId;
+ specificId.set<AutomaticGainControlV1::Id::commonTag>(tag);
+ id.set<Parameter::Id::automaticGainControlV1Tag>(specificId);
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+ EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+ << "\ngetParam:" << getParam.toString();
+ }
+ }
+ }
+
+ void addTargetPeakLevelParam(int targetPeakLevel) {
+ AutomaticGainControlV1 AGC1;
+ AGC1.set<AutomaticGainControlV1::targetPeakLevelDbFs>(targetPeakLevel);
+ mTags.push_back({AutomaticGainControlV1::targetPeakLevelDbFs, AGC1});
+ }
+ void addMaxCompressionGainParam(int maxCompressionGainDb) {
+ AutomaticGainControlV1 AGC1;
+ AGC1.set<AutomaticGainControlV1::maxCompressionGainDb>(maxCompressionGainDb);
+ mTags.push_back({AutomaticGainControlV1::maxCompressionGainDb, AGC1});
+ }
+ void addEnableLimiterParam(bool enableLimiter) {
+ AutomaticGainControlV1 AGC1;
+ AGC1.set<AutomaticGainControlV1::enableLimiter>(enableLimiter);
+ mTags.push_back({AutomaticGainControlV1::enableLimiter, AGC1});
+ }
+
+ private:
+ std::vector<std::pair<AutomaticGainControlV1::Tag, AutomaticGainControlV1>> mTags;
+ void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AGC1ParamTest, SetAndGetTargetPeakLevelParam) {
+ EXPECT_NO_FATAL_FAILURE(addTargetPeakLevelParam(mTargetPeakLevel));
+ SetAndGetParameters();
+}
+
+TEST_P(AGC1ParamTest, SetAndGetMaxCompressionGain) {
+ EXPECT_NO_FATAL_FAILURE(addMaxCompressionGainParam(mMaxCompressionGain));
+ SetAndGetParameters();
+}
+
+TEST_P(AGC1ParamTest, SetAndGetEnableLimiter) {
+ EXPECT_NO_FATAL_FAILURE(addEnableLimiterParam(mEnableLimiter));
+ SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+ AGC1ParamTest, AGC1ParamTest,
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kAutomaticGainControlV1TypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ AutomaticGainControlV1, int, Range::automaticGainControlV1,
+ AutomaticGainControlV1::targetPeakLevelDbFs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ AutomaticGainControlV1, int, Range::automaticGainControlV1,
+ AutomaticGainControlV1::maxCompressionGainDb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::Bool()),
+ [](const testing::TestParamInfo<AGC1ParamTest::ParamType>& info) {
+ auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+ std::string targetPeakLevel =
+ std::to_string(std::get<PARAM_TARGET_PEAK_LEVEL>(info.param));
+ std::string maxCompressionGain =
+ std::to_string(std::get<PARAM_MAX_COMPRESSION_GAIN>(info.param));
+ std::string enableLimiter = std::to_string(std::get<PARAM_ENABLE_LIMITER>(info.param));
+
+ std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+ descriptor.common.name + "_UUID_" +
+ descriptor.common.id.uuid.toString() + "_target_peak_level_" +
+ targetPeakLevel + "_max_compression_gain_" + maxCompressionGain +
+ "_enable_limiter_" + enableLimiter;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGC1ParamTest);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
new file mode 100644
index 0000000..fd3a866
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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 <Utils.h>
+#include <aidl/Vintf.h>
+#include <android/binder_enums.h>
+#include <unordered_set>
+
+#define LOG_TAG "VtsHalAGC2ParamTest"
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::AutomaticGainControlV2;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kAutomaticGainControlV2TypeUUID;
+using aidl::android::hardware::audio::effect::Parameter;
+
+enum ParamName {
+ PARAM_INSTANCE_NAME,
+ PARAM_DIGITAL_GAIN,
+ PARAM_SATURATION_MARGIN,
+ PARAM_LEVEL_ESTIMATOR
+};
+using AGC2ParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* gain */,
+ int /* margin */, AutomaticGainControlV2::LevelEstimator>;
+
+class AGC2ParamTest : public ::testing::TestWithParam<AGC2ParamTestParam>, public EffectHelper {
+ public:
+ AGC2ParamTest()
+ : mGain(std::get<PARAM_DIGITAL_GAIN>(GetParam())),
+ mMargin(std::get<PARAM_SATURATION_MARGIN>(GetParam())),
+ mLevelEstimator(std::get<PARAM_LEVEL_ESTIMATOR>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ ASSERT_NE(nullptr, mFactory);
+ ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+ Parameter::Specific specific = getDefaultParamSpecific();
+ Parameter::Common common = EffectHelper::createParamCommon(
+ 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+ IEffect::OpenEffectReturn ret;
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ ASSERT_NE(nullptr, mEffect);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ }
+
+ Parameter::Specific getDefaultParamSpecific() {
+ AutomaticGainControlV2 AGC2 =
+ AutomaticGainControlV2::make<AutomaticGainControlV2::fixedDigitalGainMb>(0);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::automaticGainControlV2>(AGC2);
+ return specific;
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor mDescriptor;
+ int mGain;
+ int mMargin;
+ AutomaticGainControlV2::LevelEstimator mLevelEstimator;
+
+ void SetAndGetParameters() {
+ for (auto& it : mTags) {
+ auto& tag = it.first;
+ auto& AGC2 = it.second;
+
+ // validate parameter
+ Descriptor desc;
+ ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+ const bool valid =
+ isParameterValid<AutomaticGainControlV2, Range::automaticGainControlV2>(AGC2,
+ desc);
+ const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+ // set parameter
+ Parameter expectParam;
+ Parameter::Specific specific;
+ specific.set<Parameter::Specific::automaticGainControlV2>(AGC2);
+ expectParam.set<Parameter::specific>(specific);
+ EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+ // only get if parameter in range and set success
+ if (expected == EX_NONE) {
+ Parameter getParam;
+ Parameter::Id id;
+ AutomaticGainControlV2::Id specificId;
+ specificId.set<AutomaticGainControlV2::Id::commonTag>(tag);
+ id.set<Parameter::Id::automaticGainControlV2Tag>(specificId);
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+
+ EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
+ << "\ngetParam:" << getParam.toString();
+ }
+ }
+ }
+
+ void addDigitalGainParam(int gain) {
+ AutomaticGainControlV2 AGC2;
+ AGC2.set<AutomaticGainControlV2::fixedDigitalGainMb>(gain);
+ mTags.push_back({AutomaticGainControlV2::fixedDigitalGainMb, AGC2});
+ }
+ void addSaturationMarginParam(int margin) {
+ AutomaticGainControlV2 AGC2;
+ AGC2.set<AutomaticGainControlV2::saturationMarginMb>(margin);
+ mTags.push_back({AutomaticGainControlV2::saturationMarginMb, AGC2});
+ }
+ void addLevelEstimatorParam(AutomaticGainControlV2::LevelEstimator levelEstimator) {
+ AutomaticGainControlV2 AGC2;
+ AGC2.set<AutomaticGainControlV2::levelEstimator>(levelEstimator);
+ mTags.push_back({AutomaticGainControlV2::levelEstimator, AGC2});
+ }
+
+ static std::set<AutomaticGainControlV2::LevelEstimator> getLevelEstimatorValues() {
+ return {ndk::enum_range<AutomaticGainControlV2::LevelEstimator>().begin(),
+ ndk::enum_range<AutomaticGainControlV2::LevelEstimator>().end()};
+ }
+
+ private:
+ std::vector<std::pair<AutomaticGainControlV2::Tag, AutomaticGainControlV2>> mTags;
+ void CleanUp() { mTags.clear(); }
+};
+
+TEST_P(AGC2ParamTest, SetAndGetDigitalGainParam) {
+ EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
+ SetAndGetParameters();
+}
+
+TEST_P(AGC2ParamTest, SetAndGetSaturationMargin) {
+ EXPECT_NO_FATAL_FAILURE(addSaturationMarginParam(mMargin));
+ SetAndGetParameters();
+}
+
+TEST_P(AGC2ParamTest, SetAndGetLevelEstimator) {
+ EXPECT_NO_FATAL_FAILURE(addLevelEstimatorParam(mLevelEstimator));
+ SetAndGetParameters();
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+ AGC2ParamTest, AGC2ParamTest,
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kAutomaticGainControlV2TypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ AutomaticGainControlV2, int, Range::automaticGainControlV2,
+ AutomaticGainControlV2::fixedDigitalGainMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ AutomaticGainControlV2, int, Range::automaticGainControlV2,
+ AutomaticGainControlV2::saturationMarginMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(AGC2ParamTest::getLevelEstimatorValues())),
+ [](const testing::TestParamInfo<AGC2ParamTest::ParamType>& info) {
+ auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+ std::string gain = std::to_string(std::get<PARAM_DIGITAL_GAIN>(info.param));
+ std::string estimator = aidl::android::hardware::audio::effect::toString(
+ std::get<PARAM_LEVEL_ESTIMATOR>(info.param));
+ std::string margin =
+ std::to_string(static_cast<int>(std::get<PARAM_SATURATION_MARGIN>(info.param)));
+
+ std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+ descriptor.common.name + "_UUID_" +
+ descriptor.common.id.uuid.toString() + "_digital_gain_" + gain +
+ "_level_estimator_" + estimator + "_margin_" + margin;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGC2ParamTest);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_setThreadPoolMaxThreadCount(1);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
\ No newline at end of file
diff --git a/audio/aidl/vts/VtsHalAGCTargetTest.cpp b/audio/aidl/vts/VtsHalAGCTargetTest.cpp
deleted file mode 100644
index 3448ae2..0000000
--- a/audio/aidl/vts/VtsHalAGCTargetTest.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * 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 <Utils.h>
-#include <aidl/Vintf.h>
-#include <android/binder_enums.h>
-#include <unordered_set>
-
-#define LOG_TAG "VtsHalAGCParamTest"
-
-#include "EffectHelper.h"
-
-using namespace android;
-
-using aidl::android::hardware::audio::effect::AutomaticGainControl;
-using aidl::android::hardware::audio::effect::Capability;
-using aidl::android::hardware::audio::effect::Descriptor;
-using aidl::android::hardware::audio::effect::IEffect;
-using aidl::android::hardware::audio::effect::IFactory;
-using aidl::android::hardware::audio::effect::kAutomaticGainControlTypeUUID;
-using aidl::android::hardware::audio::effect::Parameter;
-
-enum ParamName {
- PARAM_INSTANCE_NAME,
- PARAM_DIGITAL_GAIN,
- PARAM_SATURATION_MARGIN,
- PARAM_LEVEL_ESTIMATOR
-};
-using AGCParamTestParam =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* gain */,
- int /* margin */, AutomaticGainControl::LevelEstimator>;
-
-class AGCParamTest : public ::testing::TestWithParam<AGCParamTestParam>, public EffectHelper {
- public:
- AGCParamTest()
- : mGain(std::get<PARAM_DIGITAL_GAIN>(GetParam())),
- mMargin(std::get<PARAM_SATURATION_MARGIN>(GetParam())),
- mLevelEstimator(std::get<PARAM_LEVEL_ESTIMATOR>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
-
- void SetUp() override {
- ASSERT_NE(nullptr, mFactory);
- ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
-
- Parameter::Specific specific = getDefaultParamSpecific();
- Parameter::Common common = EffectHelper::createParamCommon(
- 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
- kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
- IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
- ASSERT_NE(nullptr, mEffect);
- }
-
- void TearDown() override {
- ASSERT_NO_FATAL_FAILURE(close(mEffect));
- ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
- }
-
- Parameter::Specific getDefaultParamSpecific() {
- AutomaticGainControl AGC =
- AutomaticGainControl::make<AutomaticGainControl::fixedDigitalGainMb>(0);
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::automaticGainControl>(AGC);
- return specific;
- }
-
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- int mGain;
- int mMargin;
- AutomaticGainControl::LevelEstimator mLevelEstimator;
-
- void SetAndGetParameters() {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& AGC = it.second;
-
- // validate parameter
- Descriptor desc;
- ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(tag, AGC, desc);
- const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
-
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::automaticGainControl>(AGC);
- expectParam.set<Parameter::specific>(specific);
- EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
-
- // only get if parameter in range and set success
- if (expected == EX_NONE) {
- Parameter getParam;
- Parameter::Id id;
- AutomaticGainControl::Id specificId;
- specificId.set<AutomaticGainControl::Id::commonTag>(tag);
- id.set<Parameter::Id::automaticGainControlTag>(specificId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
- EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
- << "\ngetParam:" << getParam.toString();
- }
- }
- }
-
- void addDigitalGainParam(int gain) {
- AutomaticGainControl AGC;
- AGC.set<AutomaticGainControl::fixedDigitalGainMb>(gain);
- mTags.push_back({AutomaticGainControl::fixedDigitalGainMb, AGC});
- }
- void addSaturationMarginParam(int margin) {
- AutomaticGainControl AGC;
- AGC.set<AutomaticGainControl::saturationMarginMb>(margin);
- mTags.push_back({AutomaticGainControl::saturationMarginMb, AGC});
- }
- void addLevelEstimatorParam(AutomaticGainControl::LevelEstimator levelEstimator) {
- AutomaticGainControl AGC;
- AGC.set<AutomaticGainControl::levelEstimator>(levelEstimator);
- mTags.push_back({AutomaticGainControl::levelEstimator, AGC});
- }
-
- bool isTagInRange(const AutomaticGainControl::Tag& tag, const AutomaticGainControl& AGC,
- const Descriptor& desc) const {
- const AutomaticGainControl::Capability& AGCCap =
- desc.capability.get<Capability::automaticGainControl>();
- switch (tag) {
- case AutomaticGainControl::fixedDigitalGainMb: {
- auto gain = AGC.get<AutomaticGainControl::fixedDigitalGainMb>();
- return gain >= 0 && gain <= AGCCap.maxFixedDigitalGainMb;
- }
- case AutomaticGainControl::levelEstimator: {
- return true;
- }
- case AutomaticGainControl::saturationMarginMb: {
- auto margin = AGC.get<AutomaticGainControl::saturationMarginMb>();
- return margin >= 0 && margin <= AGCCap.maxSaturationMarginMb;
- }
- default:
- return false;
- }
- }
- static std::unordered_set<int> getDigitalGainValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kAutomaticGainControlTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::automaticGainControl>()
- .maxFixedDigitalGainMb <
- b.second.capability.get<Capability::automaticGainControl>()
- .maxFixedDigitalGainMb;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxGain = max->second.capability.get<Capability::automaticGainControl>()
- .maxFixedDigitalGainMb;
- return {-1, 0, maxGain - 1, maxGain, maxGain + 1};
- }
- static std::unordered_set<int> getSaturationMarginValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kAutomaticGainControlTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::automaticGainControl>()
- .maxSaturationMarginMb <
- b.second.capability.get<Capability::automaticGainControl>()
- .maxSaturationMarginMb;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxMargin = max->second.capability.get<Capability::automaticGainControl>()
- .maxSaturationMarginMb;
- return {-1, 0, maxMargin - 1, maxMargin, maxMargin + 1};
- }
- static std::unordered_set<AutomaticGainControl::LevelEstimator> getLevelEstimatorValues() {
- return {ndk::enum_range<AutomaticGainControl::LevelEstimator>().begin(),
- ndk::enum_range<AutomaticGainControl::LevelEstimator>().end()};
- }
-
- private:
- std::vector<std::pair<AutomaticGainControl::Tag, AutomaticGainControl>> mTags;
- void CleanUp() { mTags.clear(); }
-};
-
-TEST_P(AGCParamTest, SetAndGetDigitalGainParam) {
- EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
- SetAndGetParameters();
-}
-
-TEST_P(AGCParamTest, SetAndGetSaturationMargin) {
- EXPECT_NO_FATAL_FAILURE(addSaturationMarginParam(mMargin));
- SetAndGetParameters();
-}
-
-TEST_P(AGCParamTest, SetAndGetLevelEstimator) {
- EXPECT_NO_FATAL_FAILURE(addLevelEstimatorParam(mLevelEstimator));
- SetAndGetParameters();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- AGCParamTest, AGCParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kAutomaticGainControlTypeUUID)),
- testing::ValuesIn(AGCParamTest::getDigitalGainValues()),
- testing::ValuesIn(AGCParamTest::getSaturationMarginValues()),
- testing::ValuesIn(AGCParamTest::getLevelEstimatorValues())),
- [](const testing::TestParamInfo<AGCParamTest::ParamType>& info) {
- auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
- std::string gain = std::to_string(std::get<PARAM_DIGITAL_GAIN>(info.param));
- std::string estimator = aidl::android::hardware::audio::effect::toString(
- std::get<PARAM_LEVEL_ESTIMATOR>(info.param));
- std::string margin =
- std::to_string(static_cast<int>(std::get<PARAM_SATURATION_MARGIN>(info.param)));
-
- std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
- descriptor.common.name + "_UUID_" +
- descriptor.common.id.uuid.toString() + "_digital_gain_" + gain +
- "_level_estimator_" + estimator + "_margin_" + margin;
- std::replace_if(
- name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
- return name;
- });
-
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGCParamTest);
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- ABinderProcess_setThreadPoolMaxThreadCount(1);
- ABinderProcess_startThreadPool();
- return RUN_ALL_TESTS();
-}
\ No newline at end of file
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 3ca51c7..b6015ff 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -25,6 +25,7 @@
#include <optional>
#include <set>
#include <string>
+#include <string_view>
#include <variant>
#include <vector>
@@ -64,8 +65,6 @@
using aidl::android::hardware::audio::core::IStreamIn;
using aidl::android::hardware::audio::core::IStreamOut;
using aidl::android::hardware::audio::core::ITelephony;
-using aidl::android::hardware::audio::core::MicrophoneDynamicInfo;
-using aidl::android::hardware::audio::core::MicrophoneInfo;
using aidl::android::hardware::audio::core::ModuleDebug;
using aidl::android::hardware::audio::core::StreamDescriptor;
using aidl::android::hardware::audio::core::VendorParameter;
@@ -74,6 +73,7 @@
using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
using aidl::android::media::audio::common::AudioDeviceType;
using aidl::android::media::audio::common::AudioDualMonoMode;
using aidl::android::media::audio::common::AudioFormatType;
@@ -88,11 +88,14 @@
using aidl::android::media::audio::common::AudioPortConfig;
using aidl::android::media::audio::common::AudioPortDeviceExt;
using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioPortMixExt;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioUsage;
using aidl::android::media::audio::common::Boolean;
using aidl::android::media::audio::common::Float;
using aidl::android::media::audio::common::Int;
+using aidl::android::media::audio::common::MicrophoneDynamicInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
using aidl::android::media::audio::common::Void;
using android::hardware::audio::common::getChannelCount;
using android::hardware::audio::common::isBitPositionFlagSet;
@@ -119,10 +122,49 @@
return nonExistentIds;
}
-AudioDeviceAddress GenerateUniqueDeviceAddress() {
- static int nextId = 1;
- // TODO: Use connection-specific ID.
- return AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(std::to_string(++nextId));
+AudioDeviceAddress::Tag suggestDeviceAddressTag(const AudioDeviceDescription& description) {
+ using Tag = AudioDeviceAddress::Tag;
+ if (std::string_view connection = description.connection;
+ connection == AudioDeviceDescription::CONNECTION_BT_A2DP ||
+ connection == AudioDeviceDescription::CONNECTION_BT_LE ||
+ connection == AudioDeviceDescription::CONNECTION_BT_SCO ||
+ connection == AudioDeviceDescription::CONNECTION_WIRELESS) {
+ return Tag::mac;
+ } else if (connection == AudioDeviceDescription::CONNECTION_IP_V4) {
+ return Tag::ipv4;
+ } else if (connection == AudioDeviceDescription::CONNECTION_USB) {
+ return Tag::alsa;
+ }
+ return Tag::id;
+}
+
+AudioPort GenerateUniqueDeviceAddress(const AudioPort& port) {
+ static int nextId = 0;
+ using Tag = AudioDeviceAddress::Tag;
+ AudioDeviceAddress address;
+ switch (suggestDeviceAddressTag(port.ext.get<AudioPortExt::Tag::device>().device.type)) {
+ case Tag::id:
+ address = AudioDeviceAddress::make<Tag::id>(std::to_string(++nextId));
+ break;
+ case Tag::mac:
+ address = AudioDeviceAddress::make<Tag::mac>(
+ std::vector<uint8_t>{1, 2, 3, 4, 5, static_cast<uint8_t>(++nextId & 0xff)});
+ break;
+ case Tag::ipv4:
+ address = AudioDeviceAddress::make<Tag::ipv4>(
+ std::vector<uint8_t>{192, 168, 0, static_cast<uint8_t>(++nextId & 0xff)});
+ break;
+ case Tag::ipv6:
+ address = AudioDeviceAddress::make<Tag::ipv6>(std::vector<int32_t>{
+ 0xfc00, 0x0123, 0x4567, 0x89ab, 0xcdef, 0, 0, ++nextId & 0xffff});
+ break;
+ case Tag::alsa:
+ address = AudioDeviceAddress::make<Tag::alsa>(std::vector<int32_t>{1, ++nextId});
+ break;
+ }
+ AudioPort result = port;
+ result.ext.get<AudioPortExt::Tag::device>().device.address = std::move(address);
+ return result;
}
// All 'With*' classes are move-only because they are associated with some
@@ -470,8 +512,6 @@
class WithDevicePortConnectedState {
public:
explicit WithDevicePortConnectedState(const AudioPort& idAndData) : mIdAndData(idAndData) {}
- WithDevicePortConnectedState(const AudioPort& id, const AudioDeviceAddress& address)
- : mIdAndData(setAudioPortAddress(id, address)) {}
WithDevicePortConnectedState(const WithDevicePortConnectedState&) = delete;
WithDevicePortConnectedState& operator=(const WithDevicePortConnectedState&) = delete;
~WithDevicePortConnectedState() {
@@ -491,12 +531,6 @@
const AudioPort& get() { return mConnectedPort; }
private:
- static AudioPort setAudioPortAddress(const AudioPort& id, const AudioDeviceAddress& address) {
- AudioPort result = id;
- result.ext.get<AudioPortExt::Tag::device>().device.address = address;
- return result;
- }
-
const AudioPort mIdAndData;
IModule* mModule = nullptr;
AudioPort mConnectedPort;
@@ -1378,9 +1412,7 @@
GTEST_SKIP() << "No external devices in the module.";
}
for (const auto& port : ports) {
- AudioPort portWithData = port;
- portWithData.ext.get<AudioPortExt::Tag::device>().device.address =
- GenerateUniqueDeviceAddress();
+ AudioPort portWithData = GenerateUniqueDeviceAddress(port);
WithDevicePortConnectedState portConnected(portWithData);
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
const int32_t connectedPortId = portConnected.getId();
@@ -1493,6 +1525,8 @@
AudioPortConfig portConfig;
AudioPortConfig suggestedConfig;
portConfig.portId = srcMixPort.value().id;
+ const int32_t kIoHandle = 42;
+ portConfig.ext = AudioPortMixExt{.handle = kIoHandle};
{
bool applied = true;
ASSERT_IS_OK(module->setAudioPortConfig(portConfig, &suggestedConfig, &applied))
@@ -1504,18 +1538,22 @@
EXPECT_TRUE(suggestedConfig.channelMask.has_value());
EXPECT_TRUE(suggestedConfig.format.has_value());
EXPECT_TRUE(suggestedConfig.flags.has_value());
+ ASSERT_EQ(AudioPortExt::Tag::mix, suggestedConfig.ext.getTag());
+ EXPECT_EQ(kIoHandle, suggestedConfig.ext.get<AudioPortExt::Tag::mix>().handle);
WithAudioPortConfig applied(suggestedConfig);
ASSERT_NO_FATAL_FAILURE(applied.SetUp(module.get()));
const AudioPortConfig& appliedConfig = applied.get();
EXPECT_NE(0, appliedConfig.id);
- EXPECT_TRUE(appliedConfig.sampleRate.has_value());
+ ASSERT_TRUE(appliedConfig.sampleRate.has_value());
EXPECT_EQ(suggestedConfig.sampleRate.value(), appliedConfig.sampleRate.value());
- EXPECT_TRUE(appliedConfig.channelMask.has_value());
+ ASSERT_TRUE(appliedConfig.channelMask.has_value());
EXPECT_EQ(suggestedConfig.channelMask.value(), appliedConfig.channelMask.value());
- EXPECT_TRUE(appliedConfig.format.has_value());
+ ASSERT_TRUE(appliedConfig.format.has_value());
EXPECT_EQ(suggestedConfig.format.value(), appliedConfig.format.value());
- EXPECT_TRUE(appliedConfig.flags.has_value());
+ ASSERT_TRUE(appliedConfig.flags.has_value());
EXPECT_EQ(suggestedConfig.flags.value(), appliedConfig.flags.value());
+ ASSERT_EQ(AudioPortExt::Tag::mix, appliedConfig.ext.getTag());
+ EXPECT_EQ(kIoHandle, appliedConfig.ext.get<AudioPortExt::Tag::mix>().handle);
}
TEST_P(AudioCoreModule, SetAllAttachedDevicePortConfigs) {
@@ -1531,7 +1569,7 @@
GTEST_SKIP() << "No external devices in the module.";
}
for (const auto& port : ports) {
- WithDevicePortConnectedState portConnected(port, GenerateUniqueDeviceAddress());
+ WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
ASSERT_NO_FATAL_FAILURE(
ApplyEveryConfig(moduleConfig->getPortConfigsForDevicePort(portConnected.get())));
@@ -1586,9 +1624,7 @@
doNotSimulateConnections.flags().simulateDeviceConnections = false;
ASSERT_NO_FATAL_FAILURE(doNotSimulateConnections.SetUp(module.get()));
for (const auto& port : ports) {
- AudioPort portWithData = port;
- portWithData.ext.get<AudioPortExt::Tag::device>().device.address =
- GenerateUniqueDeviceAddress();
+ AudioPort portWithData = GenerateUniqueDeviceAddress(port);
EXPECT_STATUS(EX_ILLEGAL_STATE, module->connectExternalDevice(portWithData, &ignored))
<< "static port " << portWithData.toString();
}
@@ -1600,7 +1636,7 @@
if (ports.empty()) {
GTEST_SKIP() << "No external devices in the module.";
}
- WithDevicePortConnectedState portConnected(*ports.begin(), GenerateUniqueDeviceAddress());
+ WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(*ports.begin()));
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
ModuleDebug midwayDebugChange = debug->flags();
midwayDebugChange.simulateDeviceConnections = false;
@@ -1654,9 +1690,7 @@
for (const auto& port : ports) {
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "when disconnecting already disconnected device port ID " << port.id;
- AudioPort portWithData = port;
- portWithData.ext.get<AudioPortExt::Tag::device>().device.address =
- GenerateUniqueDeviceAddress();
+ AudioPort portWithData = GenerateUniqueDeviceAddress(port);
WithDevicePortConnectedState portConnected(portWithData);
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
@@ -1679,7 +1713,7 @@
GTEST_SKIP() << "No external devices in the module.";
}
for (const auto& port : ports) {
- WithDevicePortConnectedState portConnected(port, GenerateUniqueDeviceAddress());
+ WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
const auto portConfig = moduleConfig->getSingleConfigForDevicePort(portConnected.get());
{
@@ -1707,7 +1741,7 @@
int32_t connectedPortId;
{
- WithDevicePortConnectedState portConnected(port, GenerateUniqueDeviceAddress());
+ WithDevicePortConnectedState portConnected(GenerateUniqueDeviceAddress(port));
ASSERT_NO_FATAL_FAILURE(portConnected.SetUp(module.get()));
connectedPortId = portConnected.getId();
std::vector<AudioRoute> connectedPortRoutes;
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index c5a0943..947d30e 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -82,7 +82,7 @@
Parameter get;
EXPECT_IS_OK(mEffect->setParameter(set));
EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(set, get) << set.toString() << " vs " << get.toString();
+ EXPECT_EQ(set, get) << set.toString() << "\n vs \n" << get.toString();
}
};
@@ -390,7 +390,7 @@
Parameter::Id id;
id.set<Parameter::Id::commonTag>(Parameter::common);
EXPECT_IS_OK(mEffect->getParameter(id, &get));
- EXPECT_EQ(expect, get) << expect.toString() << " vs " << get.toString();
+ EXPECT_EQ(expect, get) << expect.toString() << "\n vs \n" << get.toString();
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -590,12 +590,14 @@
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
std::vector<float> buffer;
- EffectHelper::allocateInputData(common, inputMQ, buffer);
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -617,20 +619,24 @@
auto outputMQ = std::make_unique<EffectHelper::DataMQ>(ret.outputDataMQ);
ASSERT_TRUE(outputMQ->isValid());
- ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
- ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
- ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
- ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
- ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
- ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
-
std::vector<float> buffer;
- EffectHelper::allocateInputData(common, inputMQ, buffer);
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 0, outputMQ, buffer.size(), buffer));
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
@@ -653,14 +659,14 @@
ASSERT_TRUE(outputMQ->isValid());
std::vector<float> buffer;
- EffectHelper::allocateInputData(common, inputMQ, buffer);
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
- EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
@@ -686,31 +692,30 @@
ASSERT_TRUE(outputMQ->isValid());
std::vector<float> buffer;
- EffectHelper::allocateInputData(common, inputMQ, buffer);
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
- EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
- // expect no status and data after consume
- EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
- // expect no status and data after consume
- EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
-// Send data to IDLE state effects and expect it not be consumed.
-TEST_P(AudioEffectTest, NotConsumeDataInIdleState) {
+// Send data to processing state effects, stop, and restart.
+TEST_P(AudioEffectTest, ConsumeDataAndRestart) {
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
Parameter::Common common = EffectHelper::createParamCommon(
@@ -727,17 +732,21 @@
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+ std::vector<float> buffer;
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
+
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
-
- std::vector<float> buffer;
- EffectHelper::allocateInputData(common, inputMQ, buffer);
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
- EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer);
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ, 1, outputMQ, buffer.size(), buffer));
ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
@@ -765,9 +774,9 @@
ASSERT_TRUE(outputMQ->isValid());
std::vector<float> buffer;
- EffectHelper::allocateInputData(common, inputMQ, buffer);
- EffectHelper::writeToFmq(inputMQ, buffer);
- EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common, inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ, buffer));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, buffer));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
@@ -800,9 +809,10 @@
ASSERT_TRUE(outputMQ1->isValid());
std::vector<float> buffer1, buffer2;
- EffectHelper::allocateInputData(common1, inputMQ1, buffer1);
- EffectHelper::writeToFmq(inputMQ1, buffer1);
- EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common1, inputMQ1, buffer1));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ1, buffer1));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ1, 1, outputMQ1, buffer1.size(), buffer1));
auto statusMQ2 = std::make_unique<EffectHelper::StatusMQ>(ret2.statusMQ);
ASSERT_TRUE(statusMQ2->isValid());
@@ -810,9 +820,10 @@
ASSERT_TRUE(inputMQ2->isValid());
auto outputMQ2 = std::make_unique<EffectHelper::DataMQ>(ret2.outputDataMQ);
ASSERT_TRUE(outputMQ2->isValid());
- EffectHelper::allocateInputData(common2, inputMQ2, buffer2);
- EffectHelper::writeToFmq(inputMQ2, buffer2);
- EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::allocateInputData(common2, inputMQ2, buffer2));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(inputMQ2, buffer2));
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::readFromFmq(statusMQ2, 1, outputMQ2, buffer2.size(), buffer2));
ASSERT_NO_FATAL_FAILURE(command(effect1, CommandId::STOP));
ASSERT_NO_FATAL_FAILURE(expectState(effect1, State::IDLE));
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index d49a865..a1862d2 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -31,6 +31,7 @@
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::hardware::audio::effect::kBassBoostTypeUUID;
using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
/**
* Here we focus on specific parameter checking, general IEffect interfaces testing performed in
@@ -92,7 +93,7 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(it.first, it.second, desc);
+ const bool valid = isParameterValid<BassBoost, Range::bassBoost>(it.second, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -122,46 +123,6 @@
mTags.push_back({BassBoost::strengthPm, bb});
}
- bool isTagInRange(const BassBoost::Tag& tag, const BassBoost& bb,
- const Descriptor& desc) const {
- const BassBoost::Capability& bbCap = desc.capability.get<Capability::bassBoost>();
- switch (tag) {
- case BassBoost::strengthPm: {
- int strength = bb.get<BassBoost::strengthPm>();
- return isStrengthInRange(bbCap, strength);
- }
- default:
- return false;
- }
- return false;
- }
-
- bool isStrengthInRange(const BassBoost::Capability& cap, int strength) const {
- return cap.strengthSupported && strength >= 0 && strength <= cap.maxStrengthPm;
- }
-
- static std::vector<int> getStrengthTestValues(
- std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList) {
- const auto max = std::max_element(
- kFactoryDescList.begin(), kFactoryDescList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::bassBoost>().maxStrengthPm <
- b.second.capability.get<Capability::bassBoost>().maxStrengthPm;
- });
- if (max == kFactoryDescList.end()) {
- return {0};
- }
- int maxStrength = max->second.capability.get<Capability::bassBoost>().maxStrengthPm;
- return {std::numeric_limits<int>::min(),
- -1,
- 0,
- maxStrength >> 1,
- maxStrength,
- maxStrength + 1,
- std::numeric_limits<int>::max()};
- }
-
private:
std::vector<std::pair<BassBoost::Tag, BassBoost>> mTags;
void CleanUp() { mTags.clear(); }
@@ -172,14 +133,15 @@
SetAndGetBassBoostParameters();
}
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
BassBoostTest, BassBoostParamTest,
::testing::Combine(
- testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kBassBoostTypeUUID)),
- testing::ValuesIn(BassBoostParamTest::getStrengthTestValues(
- EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kBassBoostTypeUUID)))),
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kBassBoostTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<BassBoost, int, Range::bassBoost,
+ BassBoost::strengthPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<BassBoostParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index 8612660..0601cc4 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -22,7 +22,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Downmix;
using aidl::android::hardware::audio::effect::IEffect;
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 9feff91..ece07f0 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -28,7 +28,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::DynamicsProcessing;
using aidl::android::hardware::audio::effect::IEffect;
@@ -82,31 +81,8 @@
}
// utils functions for parameter checking
- bool isParamValid(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dp,
- const Descriptor& desc);
bool isParamEqual(const DynamicsProcessing::Tag& tag, const DynamicsProcessing& dpRef,
const DynamicsProcessing& dpTest);
-
- bool isEnablementValid(const DynamicsProcessing::StageEnablement& enablement);
- bool isEngineConfigValid(const DynamicsProcessing::EngineArchitecture& cfg);
-
- bool isCutoffFrequencyValid(float freq, const DynamicsProcessing::Capability& cap);
- bool isChannelConfigValid(const std::vector<DynamicsProcessing::ChannelConfig>& cfgs,
- bool stageInUse);
-
- bool isPreEqBandConfigValid(const DynamicsProcessing::Capability& cap,
- const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
- bool stageInUse, int bandCount);
- bool isPostEqBandConfigValid(const DynamicsProcessing::Capability& cap,
- const std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
- bool stageInUse, int bandCount);
- bool isMbcBandConfigValid(const DynamicsProcessing::Capability& cap,
- const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
- bool stageInUse, int bandCount);
- bool isLimiterConfigValid(const std::vector<DynamicsProcessing::LimiterConfig>& cfgs,
- bool stageInUse);
- bool isInputGainValid(const std::vector<DynamicsProcessing::InputGain>& cfgs);
-
bool isEngineConfigEqual(const DynamicsProcessing::EngineArchitecture& refCfg,
const DynamicsProcessing::EngineArchitecture& testCfg);
@@ -201,56 +177,6 @@
{{.channel = -1, .gainDb = 10.f}, {.channel = 0, .gainDb = -10.f}}};
-bool DynamicsProcessingTestHelper::isParamValid(const DynamicsProcessing::Tag& tag,
- const DynamicsProcessing& dp,
- const Descriptor& desc) {
- const DynamicsProcessing::Capability& dpCap =
- desc.capability.get<Capability::dynamicsProcessing>();
- switch (tag) {
- case DynamicsProcessing::engineArchitecture: {
- return isEngineConfigValid(dp.get<DynamicsProcessing::engineArchitecture>());
- }
- case DynamicsProcessing::preEq: {
- return isChannelConfigValid(dp.get<DynamicsProcessing::preEq>(),
- mEngineConfigApplied.preEqStage.inUse);
- }
- case DynamicsProcessing::postEq: {
- return isChannelConfigValid(dp.get<DynamicsProcessing::postEq>(),
- mEngineConfigApplied.postEqStage.inUse);
- }
- case DynamicsProcessing::mbc: {
- return isChannelConfigValid(dp.get<DynamicsProcessing::mbc>(),
- mEngineConfigApplied.mbcStage.inUse);
- }
- case DynamicsProcessing::preEqBand: {
- return isPreEqBandConfigValid(dpCap, dp.get<DynamicsProcessing::preEqBand>(),
- mEngineConfigApplied.preEqStage.inUse,
- mEngineConfigApplied.preEqStage.bandCount);
- }
- case DynamicsProcessing::postEqBand: {
- return isPostEqBandConfigValid(dpCap, dp.get<DynamicsProcessing::postEqBand>(),
- mEngineConfigApplied.postEqStage.inUse,
- mEngineConfigApplied.postEqStage.bandCount);
- }
- case DynamicsProcessing::mbcBand: {
- return isMbcBandConfigValid(dpCap, dp.get<DynamicsProcessing::mbcBand>(),
- mEngineConfigApplied.mbcStage.inUse,
- mEngineConfigApplied.mbcStage.bandCount);
- }
- case DynamicsProcessing::limiter: {
- return isLimiterConfigValid(dp.get<DynamicsProcessing::limiter>(),
- mEngineConfigApplied.limiterInUse);
- }
- case DynamicsProcessing::inputGain: {
- return isInputGainValid(dp.get<DynamicsProcessing::inputGain>());
- }
- case DynamicsProcessing::vendorExtension: {
- return true;
- }
- }
- return true;
-}
-
bool DynamicsProcessingTestHelper::isParamEqual(const DynamicsProcessing::Tag& tag,
const DynamicsProcessing& dpRef,
const DynamicsProcessing& dpTest) {
@@ -304,117 +230,6 @@
}
}
-bool DynamicsProcessingTestHelper::isEnablementValid(
- const DynamicsProcessing::StageEnablement& enablement) {
- return !enablement.inUse || (enablement.inUse && enablement.bandCount > 0);
-}
-
-bool DynamicsProcessingTestHelper::isEngineConfigValid(
- const DynamicsProcessing::EngineArchitecture& cfg) {
- return cfg.preferredProcessingDurationMs >= 0 && isEnablementValid(cfg.preEqStage) &&
- isEnablementValid(cfg.postEqStage) && isEnablementValid(cfg.mbcStage);
-}
-
-bool DynamicsProcessingTestHelper::isChannelConfigValid(
- const std::vector<DynamicsProcessing::ChannelConfig>& cfgs, bool stageInUse) {
- std::unordered_set<int> channelSet;
- if (!stageInUse) return false;
- for (auto cfg : cfgs) {
- if (cfg.channel < 0 || cfg.channel >= mChannelCount || 0 != channelSet.count(cfg.channel)) {
- return false;
- }
- channelSet.insert(cfg.channel);
- }
- return true;
-}
-
-bool DynamicsProcessingTestHelper::isCutoffFrequencyValid(
- float freq, const DynamicsProcessing::Capability& cap) {
- return freq >= cap.minCutOffFreq && freq <= cap.maxCutOffFreq;
-}
-
-bool DynamicsProcessingTestHelper::isPreEqBandConfigValid(
- const DynamicsProcessing::Capability& cap,
- const std::vector<DynamicsProcessing::EqBandConfig>& cfgs, bool stageInUse, int bandCount) {
- std::set<std::pair<int /* channelID */, int /* bandID */>> bandSet;
- if (!stageInUse) return false;
- for (auto cfg : cfgs) {
- if (0 == mPreEqChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
- cfg.channel >= mChannelCount || cfg.band < 0 || cfg.band >= bandCount ||
- !isCutoffFrequencyValid(cfg.cutoffFrequencyHz, cap) ||
- 0 != bandSet.count({cfg.channel, cfg.band})) {
- return false;
- }
- bandSet.insert({cfg.channel, cfg.band});
- }
- return true;
-}
-
-bool DynamicsProcessingTestHelper::isPostEqBandConfigValid(
- const DynamicsProcessing::Capability& cap,
- const std::vector<DynamicsProcessing::EqBandConfig>& cfgs, bool stageInUse, int bandCount) {
- std::set<std::pair<int /* channelID */, int /* bandID */>> bandSet;
- // not able to set/get parameter when stage not in use.
- if (!stageInUse) return false;
- for (auto cfg : cfgs) {
- if (0 == mPostEqChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
- cfg.channel >= mChannelCount || cfg.band < 0 || cfg.band >= bandCount ||
- !isCutoffFrequencyValid(cfg.cutoffFrequencyHz, cap) ||
- 0 != bandSet.count({cfg.channel, cfg.band})) {
- return false;
- }
- bandSet.insert({cfg.channel, cfg.band});
- }
- return true;
-}
-
-bool DynamicsProcessingTestHelper::isMbcBandConfigValid(
- const DynamicsProcessing::Capability& cap,
- const std::vector<DynamicsProcessing::MbcBandConfig>& cfgs, bool stageInUse,
- int bandCount) {
- std::set<std::pair<int /* channelID */, int /* bandID */>> bandSet;
- if (!stageInUse) return false;
- for (auto cfg : cfgs) {
- if (0 == mMbcChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
- cfg.channel >= mChannelCount || cfg.band < 0 || cfg.band >= bandCount ||
- (cfg.attackTimeMs < 0) || cfg.releaseTimeMs < 0 || cfg.ratio < 0 ||
- cfg.thresholdDb > 0 || cfg.kneeWidthDb < 0 || cfg.noiseGateThresholdDb > 0 ||
- cfg.expanderRatio < 0 || !isCutoffFrequencyValid(cfg.cutoffFrequencyHz, cap) ||
- 0 != bandSet.count({cfg.channel, cfg.band})) {
- return false;
- }
- bandSet.insert({cfg.channel, cfg.band});
- }
- return true;
-}
-
-bool DynamicsProcessingTestHelper::isLimiterConfigValid(
- const std::vector<DynamicsProcessing::LimiterConfig>& cfgs, bool stageInUse) {
- std::set<int> channelSet;
- if (!stageInUse) return false;
- for (auto cfg : cfgs) {
- if (0 == mLimiterChannelEnable.count(cfg.channel) || cfg.channel < 0 ||
- cfg.channel >= mChannelCount || cfg.attackTimeMs < 0 || cfg.releaseTimeMs < 0 ||
- cfg.ratio < 0 || cfg.thresholdDb > 0 || 0 != channelSet.count(cfg.channel)) {
- return false;
- }
- channelSet.insert(cfg.channel);
- }
- return true;
-}
-
-bool DynamicsProcessingTestHelper::isInputGainValid(
- const std::vector<DynamicsProcessing::InputGain>& cfgs) {
- std::set<int> channelSet;
- for (auto cfg : cfgs) {
- if (cfg.channel < 0 || cfg.channel >= mChannelCount || 0 != channelSet.count(cfg.channel)) {
- return false;
- }
- channelSet.insert(cfg.channel);
- }
- return true;
-}
-
bool DynamicsProcessingTestHelper::isEngineConfigEqual(
const DynamicsProcessing::EngineArchitecture& ref,
const DynamicsProcessing::EngineArchitecture& test) {
@@ -455,7 +270,8 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isParamValid(tag, dp, desc);
+ const bool valid =
+ isParameterValid<DynamicsProcessing, Range::dynamicsProcessing>(dp, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -463,7 +279,10 @@
Parameter::Specific specific;
specific.set<Parameter::Specific::dynamicsProcessing>(dp);
expectParam.set<Parameter::specific>(specific);
- ASSERT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+ ASSERT_STATUS(expected, mEffect->setParameter(expectParam))
+ << "\n"
+ << expectParam.toString() << "\n"
+ << desc.toString();
// only get if parameter in range and set success
if (expected == EX_NONE) {
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 82c8757..fea41cb 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -23,7 +23,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::EnvironmentalReverb;
using aidl::android::hardware::audio::effect::IEffect;
@@ -93,7 +92,8 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(it.first, it.second, desc);
+ const bool valid = isParameterValid<EnvironmentalReverb, Range::environmentalReverb>(
+ it.second, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set
@@ -171,239 +171,6 @@
mTags.push_back({EnvironmentalReverb::bypass, er});
}
- bool isTagInRange(const EnvironmentalReverb::Tag& tag, const EnvironmentalReverb er,
- const Descriptor& desc) const {
- const EnvironmentalReverb::Capability& erCap =
- desc.capability.get<Capability::environmentalReverb>();
- switch (tag) {
- case EnvironmentalReverb::roomLevelMb: {
- int roomLevel = er.get<EnvironmentalReverb::roomLevelMb>();
- return isRoomLevelInRange(erCap, roomLevel);
- }
- case EnvironmentalReverb::roomHfLevelMb: {
- int roomHfLevel = er.get<EnvironmentalReverb::roomHfLevelMb>();
- return isRoomHfLevelInRange(erCap, roomHfLevel);
- }
- case EnvironmentalReverb::decayTimeMs: {
- int decayTime = er.get<EnvironmentalReverb::decayTimeMs>();
- return isDecayTimeInRange(erCap, decayTime);
- }
- case EnvironmentalReverb::decayHfRatioPm: {
- int decayHfRatio = er.get<EnvironmentalReverb::decayHfRatioPm>();
- return isDecayHfRatioInRange(erCap, decayHfRatio);
- }
- case EnvironmentalReverb::levelMb: {
- int level = er.get<EnvironmentalReverb::levelMb>();
- return isLevelInRange(erCap, level);
- }
- case EnvironmentalReverb::delayMs: {
- int delay = er.get<EnvironmentalReverb::delayMs>();
- return isDelayInRange(erCap, delay);
- }
- case EnvironmentalReverb::diffusionPm: {
- int diffusion = er.get<EnvironmentalReverb::diffusionPm>();
- return isDiffusionInRange(erCap, diffusion);
- }
- case EnvironmentalReverb::densityPm: {
- int density = er.get<EnvironmentalReverb::densityPm>();
- return isDensityInRange(erCap, density);
- }
- case EnvironmentalReverb::bypass: {
- return true;
- }
- default:
- return false;
- }
- return false;
- }
-
- bool isRoomLevelInRange(const EnvironmentalReverb::Capability& cap, int roomLevel) const {
- return roomLevel >= cap.minRoomLevelMb && roomLevel <= cap.maxRoomLevelMb;
- }
-
- bool isRoomHfLevelInRange(const EnvironmentalReverb::Capability& cap, int roomHfLevel) const {
- return roomHfLevel >= cap.minRoomHfLevelMb && roomHfLevel <= cap.maxRoomHfLevelMb;
- }
-
- bool isDecayTimeInRange(const EnvironmentalReverb::Capability& cap, int decayTime) const {
- return decayTime >= 0 && decayTime <= cap.maxDecayTimeMs;
- }
-
- bool isDecayHfRatioInRange(const EnvironmentalReverb::Capability& cap, int decayHfRatio) const {
- return decayHfRatio >= cap.minDecayHfRatioPm && decayHfRatio <= cap.maxDecayHfRatioPm;
- }
-
- bool isLevelInRange(const EnvironmentalReverb::Capability& cap, int level) const {
- return level >= cap.minLevelMb && level <= cap.maxLevelMb;
- }
-
- bool isDelayInRange(const EnvironmentalReverb::Capability& cap, int delay) const {
- return delay >= 0 && delay <= cap.maxDelayMs;
- }
-
- bool isDiffusionInRange(const EnvironmentalReverb::Capability& cap, int diffusion) const {
- return diffusion >= 0 && diffusion <= cap.maxDiffusionPm;
- }
-
- bool isDensityInRange(const EnvironmentalReverb::Capability& cap, int density) const {
- return density >= 0 && density <= cap.maxDensityPm;
- }
-
- static std::unordered_set<int> getRoomLevelValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- int minRoomLevelMb = std::numeric_limits<int>::max();
- int maxRoomLevelMb = std::numeric_limits<int>::min();
- for (const auto& it : descList) {
- maxRoomLevelMb = std::max(
- it.second.capability.get<Capability::environmentalReverb>().maxRoomLevelMb,
- maxRoomLevelMb);
- minRoomLevelMb = std::min(
- it.second.capability.get<Capability::environmentalReverb>().minRoomLevelMb,
- minRoomLevelMb);
- }
- return {std::numeric_limits<int>::min(), minRoomLevelMb - 1, minRoomLevelMb,
- (minRoomLevelMb + maxRoomLevelMb) >> 1, maxRoomLevelMb, maxRoomLevelMb + 1,
- std::numeric_limits<int>::max()};
- }
-
- static std::unordered_set<int> getRoomHfLevelValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- int minRoomHfLevelMb = std::numeric_limits<int>::max();
- int maxRoomHfLevelMb = std::numeric_limits<int>::min();
- for (const auto& it : descList) {
- maxRoomHfLevelMb = std::max(
- it.second.capability.get<Capability::environmentalReverb>().maxRoomHfLevelMb,
- maxRoomHfLevelMb);
- minRoomHfLevelMb = std::min(
- it.second.capability.get<Capability::environmentalReverb>().minRoomHfLevelMb,
- minRoomHfLevelMb);
- }
- return {std::numeric_limits<int>::min(),
- minRoomHfLevelMb - 1,
- minRoomHfLevelMb,
- (minRoomHfLevelMb + maxRoomHfLevelMb) >> 1,
- maxRoomHfLevelMb,
- maxRoomHfLevelMb + 1,
- std::numeric_limits<int>::max()};
- }
-
- static std::unordered_set<int> getDecayTimeValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::environmentalReverb>()
- .maxDecayTimeMs <
- b.second.capability.get<Capability::environmentalReverb>()
- .maxDecayTimeMs;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxDecayTimeMs =
- max->second.capability.get<Capability::environmentalReverb>().maxDecayTimeMs;
- return {-1, 0, maxDecayTimeMs >> 1, maxDecayTimeMs - 1, maxDecayTimeMs, maxDecayTimeMs + 1};
- }
-
- static std::unordered_set<int> getDecayHfRatioValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- int minDecayHfRatioPm = std::numeric_limits<int>::max();
- int maxDecayHfRatioPm = std::numeric_limits<int>::min();
- for (const auto& it : descList) {
- maxDecayHfRatioPm = std::max(
- it.second.capability.get<Capability::environmentalReverb>().maxDecayHfRatioPm,
- maxDecayHfRatioPm);
- minDecayHfRatioPm = std::min(
- it.second.capability.get<Capability::environmentalReverb>().minDecayHfRatioPm,
- minDecayHfRatioPm);
- }
- return {std::numeric_limits<int>::min(),
- minDecayHfRatioPm - 1,
- minDecayHfRatioPm,
- (minDecayHfRatioPm + maxDecayHfRatioPm) >> 1,
- maxDecayHfRatioPm,
- maxDecayHfRatioPm + 1,
- std::numeric_limits<int>::max()};
- }
-
- static std::unordered_set<int> getLevelValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- int minLevelMb = std::numeric_limits<int>::max();
- int maxLevelMb = std::numeric_limits<int>::min();
- for (const auto& it : descList) {
- maxLevelMb =
- std::max(it.second.capability.get<Capability::environmentalReverb>().maxLevelMb,
- maxLevelMb);
- minLevelMb =
- std::min(it.second.capability.get<Capability::environmentalReverb>().minLevelMb,
- minLevelMb);
- }
- return {std::numeric_limits<int>::min(), minLevelMb - 1, minLevelMb,
- (minLevelMb + maxLevelMb) >> 1, maxLevelMb, maxLevelMb + 1,
- std::numeric_limits<int>::max()};
- }
-
- static std::unordered_set<int> getDelayValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::environmentalReverb>().maxDelayMs <
- b.second.capability.get<Capability::environmentalReverb>().maxDelayMs;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxDelayMs = max->second.capability.get<Capability::environmentalReverb>().maxDelayMs;
- return {-1, 0, maxDelayMs >> 1, maxDelayMs - 1, maxDelayMs, maxDelayMs + 1};
- }
-
- static std::unordered_set<int> getDiffusionValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::environmentalReverb>()
- .maxDiffusionPm <
- b.second.capability.get<Capability::environmentalReverb>()
- .maxDiffusionPm;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxDiffusionPm =
- max->second.capability.get<Capability::environmentalReverb>().maxDiffusionPm;
- return {-1, 0, maxDiffusionPm >> 1, maxDiffusionPm - 1, maxDiffusionPm, maxDiffusionPm + 1};
- }
-
- static std::unordered_set<int> getDensityValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kEnvReverbTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::environmentalReverb>().maxDensityPm <
- b.second.capability.get<Capability::environmentalReverb>().maxDensityPm;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxDensityPm =
- max->second.capability.get<Capability::environmentalReverb>().maxDensityPm;
- return {-1, 0, maxDensityPm >> 1, maxDensityPm - 1, maxDensityPm, maxDensityPm + 1};
- }
-
private:
std::vector<std::pair<EnvironmentalReverb::Tag, EnvironmentalReverb>> mTags;
void CleanUp() { mTags.clear(); }
@@ -428,11 +195,17 @@
SetAndGetReverbParameters();
}
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbRoomLevelTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getRoomLevelValues())),
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::roomLevelMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbRoomLevelTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string roomLevel = std::to_string(std::get<1>(info.param));
@@ -467,9 +240,13 @@
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbRoomHfLevelTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getRoomHfLevelValues())),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::roomHfLevelMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbRoomHfLevelTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string roomHfLevel = std::to_string(std::get<1>(info.param));
@@ -504,9 +281,13 @@
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbDecayTimeTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getDecayTimeValues())),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::decayTimeMs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbDecayTimeTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string decayTime = std::to_string(std::get<1>(info.param));
@@ -543,7 +324,10 @@
EnvironmentalReverbTest, EnvironmentalReverbDecayHfRatioTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getDecayHfRatioValues())),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ EnvironmentalReverb, int, Range::environmentalReverb,
+ EnvironmentalReverb::decayHfRatioPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string decayHfRatio = std::to_string(std::get<1>(info.param));
@@ -579,9 +363,13 @@
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbLevelTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getLevelValues())),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::levelMb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbDecayHfRatioTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string level = std::to_string(std::get<1>(info.param));
@@ -616,9 +404,13 @@
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbDelayTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getDelayValues())),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::delayMs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbDelayTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string delay = std::to_string(std::get<1>(info.param));
@@ -653,9 +445,13 @@
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbDiffusionTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getDiffusionValues())),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::diffusionPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbDiffusionTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string diffusion = std::to_string(std::get<1>(info.param));
@@ -690,9 +486,13 @@
INSTANTIATE_TEST_SUITE_P(
EnvironmentalReverbTest, EnvironmentalReverbDensityTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEnvReverbTypeUUID)),
- testing::ValuesIn(EnvironmentalReverbHelper::getDensityValues())),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kEnvReverbTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<EnvironmentalReverb, int,
+ Range::environmentalReverb,
+ EnvironmentalReverb::densityPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<EnvironmentalReverbDensityTest::ParamType>& info) {
auto descriptor = std::get<0>(info.param).second;
std::string density = std::to_string(std::get<1>(info.param));
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index e11a936..54d00a7 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -18,6 +18,7 @@
#include <limits>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <vector>
@@ -43,7 +44,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Equalizer;
using aidl::android::hardware::audio::effect::IEffect;
@@ -56,8 +56,9 @@
* testing performed in VtsAudioEfectTargetTest.
*/
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int>;
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET, PARAM_BAND_LEVEL };
+using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
+ std::vector<Equalizer::BandLevel>>;
/*
Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -69,7 +70,9 @@
class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
public EffectHelper {
public:
- EqualizerTest() : mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
+ EqualizerTest()
+ : mPresetIndex(std::get<PARAM_PRESET>(GetParam())),
+ mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
@@ -77,48 +80,24 @@
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
- Parameter::Specific specific = getDefaultParamSpecific();
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
ASSERT_NE(nullptr, mEffect);
- ASSERT_NO_FATAL_FAILURE(setTagRange());
}
void TearDown() override {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
- std::pair<int, int> setPresetIndexRange(const Equalizer::Capability& cap) const {
- const auto [min, max] =
- std::minmax_element(cap.presets.begin(), cap.presets.end(),
- [](const auto& a, const auto& b) { return a.index < b.index; });
- return {min->index, max->index};
- }
- std::pair<int, int> setBandIndexRange(const Equalizer::Capability& cap) const {
- const auto [min, max] =
- std::minmax_element(cap.bandFrequencies.begin(), cap.bandFrequencies.end(),
- [](const auto& a, const auto& b) { return a.index < b.index; });
- return {min->index, max->index};
- }
- void setTagRange() {
- Descriptor desc;
- ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- Equalizer::Capability& eqCap = desc.capability.get<Capability::equalizer>();
- mPresetIndex = setPresetIndexRange(eqCap);
- mBandIndex = setBandIndexRange(eqCap);
- }
-
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
- std::pair<int, int> mPresetIndex;
- std::pair<int, int> mBandIndex;
- const int mBandLevel;
- Descriptor mDesc;
+ int mPresetIndex;
+ std::vector<Equalizer::BandLevel> mBandLevel;
void SetAndGetEqualizerParameters() {
ASSERT_NE(nullptr, mEffect);
@@ -127,25 +106,22 @@
auto& eq = it.second;
// validate parameter
- const bool valid = isTagInRange(it.first, it.second);
+ const bool valid = isParameterValid<Equalizer, Range::equalizer>(eq, mDescriptor);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::equalizer>(eq);
- expectParam.set<Parameter::specific>(specific);
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
+ Parameter expectParam = Parameter::make<Parameter::specific>(specific);
EXPECT_STATUS(expected, mEffect->setParameter(expectParam))
<< expectParam.toString() << "\n"
- << mDesc.toString();
+ << mDescriptor.toString();
// only get if parameter in range and set success
if (expected == EX_NONE) {
Parameter getParam;
- Parameter::Id id;
- Equalizer::Id eqId;
- eqId.set<Equalizer::Id::commonTag>(tag);
- id.set<Parameter::Id::equalizerTag>(eqId);
+ Equalizer::Id eqId = Equalizer::Id::make<Equalizer::Id::commonTag>(tag);
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::equalizerTag>(eqId);
// if set success, then get should match
EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
EXPECT_TRUE(isEqParameterExpected(expectParam, getParam))
@@ -197,140 +173,51 @@
}
void addPresetParam(int preset) {
- Equalizer eq;
- eq.set<Equalizer::preset>(preset);
- mTags.push_back({Equalizer::preset, eq});
+ mTags.push_back({Equalizer::preset, Equalizer::make<Equalizer::preset>(preset)});
}
void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
- Equalizer eq;
- eq.set<Equalizer::bandLevels>(bandLevels);
- mTags.push_back({Equalizer::bandLevels, eq});
- }
-
- bool isTagInRange(const Equalizer::Tag& tag, const Equalizer& eq) const {
- switch (tag) {
- case Equalizer::preset: {
- int index = eq.get<Equalizer::preset>();
- return index >= mPresetIndex.first && index <= mPresetIndex.second;
- }
- case Equalizer::bandLevels: {
- auto& bandLevel = eq.get<Equalizer::bandLevels>();
- return isBandInRange(bandLevel);
- }
- default:
- return false;
- }
- return false;
- }
-
- bool isBandInRange(const std::vector<Equalizer::BandLevel>& bandLevel) const {
- for (auto& it : bandLevel) {
- if (it.index < mBandIndex.first || it.index > mBandIndex.second) return false;
- }
- return true;
- }
-
- Parameter::Specific getDefaultParamSpecific() {
- Equalizer eq = Equalizer::make<Equalizer::preset>(0);
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::equalizer>(eq);
- return specific;
+ mTags.push_back(
+ {Equalizer::bandLevels, Equalizer::make<Equalizer::bandLevels>(bandLevels)});
}
private:
std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
- bool validCapabilityTag(Capability& cap) { return cap.getTag() == Capability::equalizer; }
-
void CleanUp() { mTags.clear(); }
};
-TEST_P(EqualizerTest, SetAndGetPresetOutOfLowerBound) {
- addPresetParam(mPresetIndex.second - 1);
- ASSERT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetPresetOutOfUpperBound) {
- addPresetParam(mPresetIndex.second + 1);
+TEST_P(EqualizerTest, SetAndGetParams) {
+ addBandLevelsParam(mBandLevel);
+ addPresetParam(mPresetIndex);
EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
}
-TEST_P(EqualizerTest, SetAndGetPresetAtLowerBound) {
- addPresetParam(mPresetIndex.first);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetPresetAtHigherBound) {
- addPresetParam(mPresetIndex.second);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetPresetInBound) {
- addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandOutOfLowerBound) {
- std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first - 1, mBandLevel}};
- addBandLevelsParam(bandLevels);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandOutOfUpperBound) {
- std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second + 1, mBandLevel}};
- addBandLevelsParam(bandLevels);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandAtLowerBound) {
- std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.first, mBandLevel}};
- addBandLevelsParam(bandLevels);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandAtHigherBound) {
- std::vector<Equalizer::BandLevel> bandLevels{{mBandIndex.second, mBandLevel}};
- addBandLevelsParam(bandLevels);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetBandInBound) {
- std::vector<Equalizer::BandLevel> bandLevels{
- {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
- addBandLevelsParam(bandLevels);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetMultiBands) {
- addPresetParam(mPresetIndex.first);
- std::vector<Equalizer::BandLevel> bandLevels{
- {mBandIndex.first, mBandLevel},
- {mBandIndex.second, mBandLevel},
- {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
- addBandLevelsParam(bandLevels);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
-TEST_P(EqualizerTest, SetAndGetMultipleParams) {
- std::vector<Equalizer::BandLevel> bandLevels{
- {(mBandIndex.first + mBandIndex.second) >> 1, mBandLevel}};
- addBandLevelsParam(bandLevels);
- addPresetParam((mPresetIndex.first + mPresetIndex.second) >> 1);
- EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
-}
-
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
EqualizerTest, EqualizerTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kEqualizerTypeUUID)),
- testing::ValuesIn(kBandLevels)),
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kEqualizerTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<Equalizer, int, Range::equalizer,
+ Equalizer::preset>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(
+ EffectHelper::getTestValueSet<Equalizer, std::vector<Equalizer::BandLevel>,
+ Range::equalizer, Equalizer::bandLevels>(
+ kDescPair,
+ [](std::set<std::vector<Equalizer::BandLevel>>& bandLevels) {
+ return bandLevels;
+ }))),
[](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
- std::string bandLevel = std::to_string(std::get<PARAM_BAND_LEVEL>(info.param));
+ std::string bandLevel =
+ ::android::internal::ToString(std::get<PARAM_BAND_LEVEL>(info.param));
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
descriptor.common.name + "_UUID_" +
- descriptor.common.id.uuid.toString() + "_bandLevel_" + bandLevel;
+ descriptor.common.id.uuid.toString() + "_preset_" +
+ std::to_string(std::get<PARAM_PRESET>(info.param)) + "_bandLevel_" +
+ bandLevel;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index b8ea9c1..6c3016e 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -27,7 +27,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::HapticGenerator;
using aidl::android::hardware::audio::effect::IEffect;
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 305c243..75941ff 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -24,7 +24,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 93ad86d..16c79e3 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -26,7 +26,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
@@ -34,13 +33,14 @@
using aidl::android::hardware::audio::effect::NoiseSuppression;
using aidl::android::hardware::audio::effect::Parameter;
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL };
-using NSParamTestParam =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, NoiseSuppression::Level>;
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_TYPE };
+using NSParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+ NoiseSuppression::Level, NoiseSuppression::Type>;
class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public EffectHelper {
public:
- NSParamTest() : mLevel(std::get<PARAM_LEVEL>(GetParam())) {
+ NSParamTest()
+ : mLevel(std::get<PARAM_LEVEL>(GetParam())), mType(std::get<PARAM_TYPE>(GetParam())) {
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
@@ -75,6 +75,7 @@
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
NoiseSuppression::Level mLevel;
+ NoiseSuppression::Type mType;
void SetAndGetParameters() {
for (auto& it : mTags) {
@@ -113,10 +114,19 @@
ns.set<NoiseSuppression::level>(level);
mTags.push_back({NoiseSuppression::level, ns});
}
+ void addTypeParam(NoiseSuppression::Type type) {
+ NoiseSuppression ns;
+ ns.set<NoiseSuppression::type>(type);
+ mTags.push_back({NoiseSuppression::type, ns});
+ }
static std::unordered_set<NoiseSuppression::Level> getLevelValues() {
return {ndk::enum_range<NoiseSuppression::Level>().begin(),
ndk::enum_range<NoiseSuppression::Level>().end()};
}
+ static std::unordered_set<NoiseSuppression::Type> getTypeValues() {
+ return {ndk::enum_range<NoiseSuppression::Type>().begin(),
+ ndk::enum_range<NoiseSuppression::Type>().end()};
+ }
private:
std::vector<std::pair<NoiseSuppression::Tag, NoiseSuppression>> mTags;
@@ -128,18 +138,27 @@
SetAndGetParameters();
}
+TEST_P(NSParamTest, SetAndGetType) {
+ EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
+ SetAndGetParameters();
+}
+
INSTANTIATE_TEST_SUITE_P(
NSParamTest, NSParamTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kNoiseSuppressionTypeUUID)),
- testing::ValuesIn(NSParamTest::getLevelValues())),
+ testing::ValuesIn(NSParamTest::getLevelValues()),
+ testing::ValuesIn(NSParamTest::getTypeValues())),
[](const testing::TestParamInfo<NSParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string level = aidl::android::hardware::audio::effect::toString(
std::get<PARAM_LEVEL>(info.param));
+ std::string type = aidl::android::hardware::audio::effect::toString(
+ std::get<PARAM_TYPE>(info.param));
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
descriptor.common.name + "_UUID_" +
- descriptor.common.id.uuid.toString() + "_level_" + level;
+ descriptor.common.id.uuid.toString() + "_level_" + level + "_type_" +
+ type;
std::replace_if(
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 19d5747..c9c2a31 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -23,7 +23,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
@@ -84,7 +83,7 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(it.first, it.second, desc);
+ const bool valid = isParameterValid<PresetReverb, Range::presetReverb>(it.second, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -113,27 +112,6 @@
mTags.push_back({PresetReverb::preset, pr});
}
- bool isTagInRange(const PresetReverb::Tag& tag, const PresetReverb& pr,
- const Descriptor& desc) const {
- const PresetReverb::Capability& prCap = desc.capability.get<Capability::presetReverb>();
- switch (tag) {
- case PresetReverb::preset: {
- PresetReverb::Presets preset = pr.get<PresetReverb::preset>();
- return isPresetInRange(prCap, preset);
- }
- default:
- return false;
- }
- return false;
- }
-
- bool isPresetInRange(const PresetReverb::Capability& cap, PresetReverb::Presets preset) const {
- for (auto i : cap.supportedPresets) {
- if (preset == i) return true;
- }
- return false;
- }
-
Parameter::Specific getDefaultParamSpecific() {
PresetReverb pr = PresetReverb::make<PresetReverb::preset>(PresetReverb::Presets::NONE);
Parameter::Specific specific =
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 090de17..8b0210c 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -22,7 +22,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
@@ -90,7 +89,7 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(it.first, it.second, desc);
+ const bool valid = isParameterValid<Virtualizer, Range::virtualizer>(it.second, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -120,46 +119,6 @@
mTags.push_back({Virtualizer::strengthPm, vr});
}
- bool isTagInRange(const Virtualizer::Tag& tag, const Virtualizer& vr,
- const Descriptor& desc) const {
- const Virtualizer::Capability& vrCap = desc.capability.get<Capability::virtualizer>();
- switch (tag) {
- case Virtualizer::strengthPm: {
- int strength = vr.get<Virtualizer::strengthPm>();
- return isStrengthInRange(vrCap, strength);
- }
- default:
- return false;
- }
- return false;
- }
-
- bool isStrengthInRange(const Virtualizer::Capability& cap, int strength) const {
- return cap.strengthSupported && strength >= 0 && strength <= cap.maxStrengthPm;
- }
-
- static std::vector<int> getStrengthTestValues(
- std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList) {
- const auto max = std::max_element(
- kFactoryDescList.begin(), kFactoryDescList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::virtualizer>().maxStrengthPm <
- b.second.capability.get<Capability::virtualizer>().maxStrengthPm;
- });
- if (max == kFactoryDescList.end()) {
- return {0};
- }
- int maxStrength = max->second.capability.get<Capability::virtualizer>().maxStrengthPm;
- return {std::numeric_limits<int>::min(),
- -1,
- 0,
- maxStrength >> 1,
- maxStrength,
- maxStrength + 1,
- std::numeric_limits<int>::max()};
- }
-
private:
std::vector<std::pair<Virtualizer::Tag, Virtualizer>> mTags;
void CleanUp() { mTags.clear(); }
@@ -170,13 +129,15 @@
SetAndGetVirtualizerParameters();
}
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
VirtualizerTest, VirtualizerParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kVirtualizerTypeUUID)),
- testing::ValuesIn(VirtualizerParamTest::getStrengthTestValues(
- EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kVirtualizerTypeUUID)))),
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kVirtualizerTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<
+ Virtualizer, int, Range::virtualizer, Virtualizer::strengthPm>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<VirtualizerParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string strength = std::to_string(std::get<PARAM_STRENGTH>(info.param));
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index 242be3f..e2625cb 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -26,7 +26,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
@@ -64,12 +63,11 @@
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
- Parameter::Specific specific = getDefaultParamSpecific();
Parameter::Common common = EffectHelper::createParamCommon(
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
IEffect::OpenEffectReturn ret;
- ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
@@ -77,13 +75,6 @@
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
- Parameter::Specific getDefaultParamSpecific() {
- Visualizer vs = Visualizer::make<Visualizer::captureSamples>(
- mDescriptor.capability.get<Capability::visualizer>().captureSampleRange.max);
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::visualizer>(vs);
- return specific;
- }
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
std::shared_ptr<IFactory> mFactory;
@@ -94,7 +85,7 @@
Visualizer::MeasurementMode mMeasurementMode = Visualizer::MeasurementMode::NONE;
int mLatency = 0;
- void SetAndGetCommonParameters() {
+ void SetAndGetParameters() {
for (auto& it : mCommonTags) {
auto& tag = it.first;
auto& vs = it.second;
@@ -102,7 +93,7 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isTagInRange(tag, vs, desc);
+ const bool valid = isParameterValid<Visualizer, Range::visualizer>(vs, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -119,170 +110,39 @@
Visualizer::Id vsId;
vsId.set<Visualizer::Id::commonTag>(tag);
id.set<Parameter::Id::visualizerTag>(vsId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam))
+ << " with: " << id.toString();
EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
<< "\ngetParam:" << getParam.toString();
}
}
}
- void SetAndGetSetOnlyParameters() {
- for (auto& it : mSetOnlyParamTags) {
- auto& tag = it.first;
- auto& vs = it.second;
-
- // validate parameter
- Descriptor desc;
- ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- const bool valid = isSetOnlyParamTagInRange(vs, desc);
- const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
-
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::visualizer>(vs);
- expectParam.set<Parameter::specific>(specific);
- ASSERT_STATUS(expected, mEffect->setParameter(expectParam));
-
- // parameter defined in this setOnlyParameter union must be settable via
- // setParameter(), but must not be gettable
- Parameter getParam;
- Parameter::Id id;
- Visualizer::Id vsId;
- vsId.set<Visualizer::Id::setOnlyParamTag>(tag);
- id.set<Parameter::Id::visualizerTag>(vsId);
- EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, mEffect->getParameter(id, &getParam));
- }
- }
-
- void GetandSetGetOnlyParameters() {
- for (auto& tag : mGetOnlyParamTags) {
- // get parameter
- Parameter getParam;
- Parameter::Id id;
- Visualizer::Id vsId;
- vsId.set<Visualizer::Id::getOnlyParamTag>(tag);
- id.set<Parameter::Id::visualizerTag>(vsId);
- ASSERT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
- // parameter defined in this getOnlyParameter union must be gettable via
- // getParameter(), but must not be settable
- // set parameter
- ASSERT_STATUS(EX_ILLEGAL_ARGUMENT, mEffect->setParameter(getParam));
- }
- }
-
void addCaptureSizeParam(int captureSize) {
- Visualizer vs;
- vs.set<Visualizer::captureSamples>(captureSize);
- mCommonTags.push_back({Visualizer::captureSamples, vs});
+ mCommonTags.push_back({Visualizer::captureSamples,
+ Visualizer::make<Visualizer::captureSamples>(captureSize)});
}
void addScalingModeParam(Visualizer::ScalingMode scalingMode) {
- Visualizer vs;
- vs.set<Visualizer::scalingMode>(scalingMode);
- mCommonTags.push_back({Visualizer::scalingMode, vs});
+ mCommonTags.push_back(
+ {Visualizer::scalingMode, Visualizer::make<Visualizer::scalingMode>(scalingMode)});
}
void addMeasurementModeParam(Visualizer::MeasurementMode measurementMode) {
- Visualizer vs;
- vs.set<Visualizer::measurementMode>(measurementMode);
- mCommonTags.push_back({Visualizer::measurementMode, vs});
+ mCommonTags.push_back({Visualizer::measurementMode,
+ Visualizer::make<Visualizer::measurementMode>(measurementMode)});
}
void addLatencyParam(int latency) {
- Visualizer vs;
- Visualizer::SetOnlyParameters setOnlyParam;
- setOnlyParam.set<Visualizer::SetOnlyParameters::latencyMs>(latency);
- vs.set<Visualizer::setOnlyParameters>(setOnlyParam);
- mSetOnlyParamTags.push_back({Visualizer::SetOnlyParameters::latencyMs, vs});
+ mCommonTags.push_back(
+ {Visualizer::latencyMs, Visualizer::make<Visualizer::latencyMs>(latency)});
}
- void addMeasurementTag() {
- mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::measurement);
- }
-
- void addCaptureBytesTag() {
- mGetOnlyParamTags.push_back(Visualizer::GetOnlyParameters::captureSampleBuffer);
- }
-
- bool isTagInRange(const Visualizer::Tag& tag, const Visualizer& vs,
- const Descriptor& desc) const {
- const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
- switch (tag) {
- case Visualizer::captureSamples: {
- int captureSize = vs.get<Visualizer::captureSamples>();
- return captureSize >= vsCap.captureSampleRange.min &&
- captureSize <= vsCap.captureSampleRange.max;
- }
- case Visualizer::scalingMode:
- case Visualizer::measurementMode:
- return true;
- case Visualizer::setOnlyParameters: {
- auto setOnly = vs.get<Visualizer::setOnlyParameters>();
- if (setOnly.getTag() != Visualizer::SetOnlyParameters::latencyMs) {
- return false;
- }
- auto latencyMs = setOnly.get<Visualizer::SetOnlyParameters::latencyMs>();
- return latencyMs >= 0 && latencyMs <= vsCap.maxLatencyMs;
- }
- default:
- return false;
- }
- }
-
- bool isSetOnlyParamTagInRange(const Visualizer& vs, const Descriptor& desc) const {
- const Visualizer::Capability& vsCap = desc.capability.get<Capability::visualizer>();
- if (vs.getTag() != Visualizer::setOnlyParameters) return false;
- Visualizer::SetOnlyParameters setOnlyParam = vs.get<Visualizer::setOnlyParameters>();
- if (setOnlyParam.getTag() != Visualizer::SetOnlyParameters::latencyMs) return false;
- int latency = setOnlyParam.get<Visualizer::SetOnlyParameters::latencyMs>();
- return isLatencyInRange(vsCap, latency);
- }
-
- bool isLatencyInRange(const Visualizer::Capability& cap, int latency) const {
- return (latency >= 0 && latency <= cap.maxLatencyMs);
- }
-
- static std::unordered_set<int> getCaptureSizeValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kVisualizerTypeUUID);
- int minCaptureSize = std::numeric_limits<int>::max();
- int maxCaptureSize = std::numeric_limits<int>::min();
- for (const auto& it : descList) {
- maxCaptureSize = std::max(
- it.second.capability.get<Capability::visualizer>().captureSampleRange.max,
- maxCaptureSize);
- minCaptureSize = std::min(
- it.second.capability.get<Capability ::visualizer>().captureSampleRange.min,
- minCaptureSize);
- }
- return {std::numeric_limits<int>::min(), minCaptureSize - 1, minCaptureSize,
- (minCaptureSize + maxCaptureSize) >> 1, maxCaptureSize, maxCaptureSize + 1,
- std::numeric_limits<int>::max()};
- }
-
- static std::unordered_set<int> getLatencyValues() {
- auto descList = EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kVisualizerTypeUUID);
- const auto max = std::max_element(
- descList.begin(), descList.end(),
- [](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
- const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
- return a.second.capability.get<Capability::visualizer>().maxLatencyMs <
- b.second.capability.get<Capability::visualizer>().maxLatencyMs;
- });
- if (max == descList.end()) {
- return {0};
- }
- int maxDelay = max->second.capability.get<Capability::visualizer>().maxLatencyMs;
- return {-1, 0, maxDelay >> 1, maxDelay - 1, maxDelay, maxDelay + 1};
- }
static std::unordered_set<Visualizer::MeasurementMode> getMeasurementModeValues() {
return {ndk::enum_range<Visualizer::MeasurementMode>().begin(),
ndk::enum_range<Visualizer::MeasurementMode>().end()};
}
+
static std::unordered_set<Visualizer::ScalingMode> getScalingModeValues() {
return {ndk::enum_range<Visualizer::ScalingMode>().begin(),
ndk::enum_range<Visualizer::ScalingMode>().end()};
@@ -290,53 +150,43 @@
private:
std::vector<std::pair<Visualizer::Tag, Visualizer>> mCommonTags;
- std::vector<std::pair<Visualizer::SetOnlyParameters::Tag, Visualizer>> mSetOnlyParamTags;
- std::vector<Visualizer::GetOnlyParameters::Tag> mGetOnlyParamTags;
- void CleanUp() {
- mCommonTags.clear();
- mSetOnlyParamTags.clear();
- mGetOnlyParamTags.clear();
- }
+ void CleanUp() { mCommonTags.clear(); }
};
TEST_P(VisualizerParamTest, SetAndGetCaptureSize) {
EXPECT_NO_FATAL_FAILURE(addCaptureSizeParam(mCaptureSize));
- SetAndGetCommonParameters();
+ SetAndGetParameters();
}
TEST_P(VisualizerParamTest, SetAndGetScalingMode) {
EXPECT_NO_FATAL_FAILURE(addScalingModeParam(mScalingMode));
- SetAndGetCommonParameters();
+ SetAndGetParameters();
}
TEST_P(VisualizerParamTest, SetAndGetMeasurementMode) {
EXPECT_NO_FATAL_FAILURE(addMeasurementModeParam(mMeasurementMode));
- SetAndGetCommonParameters();
+ SetAndGetParameters();
}
TEST_P(VisualizerParamTest, SetAndGetLatency) {
EXPECT_NO_FATAL_FAILURE(addLatencyParam(mLatency));
- SetAndGetSetOnlyParameters();
+ SetAndGetParameters();
}
-TEST_P(VisualizerParamTest, GetAndSetMeasurement) {
- EXPECT_NO_FATAL_FAILURE(addMeasurementTag());
- GetandSetGetOnlyParameters();
-}
-
-TEST_P(VisualizerParamTest, GetAndSetCaptureBytes) {
- EXPECT_NO_FATAL_FAILURE(addCaptureBytesTag());
- GetandSetGetOnlyParameters();
-}
-
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
VisualizerParamTest, VisualizerParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kVisualizerTypeUUID)),
- testing::ValuesIn(VisualizerParamTest::getCaptureSizeValues()),
- testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
- testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
- testing::ValuesIn(VisualizerParamTest::getLatencyValues())),
+ ::testing::Combine(
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kVisualizerTypeUUID)),
+ testing::ValuesIn(EffectHelper::getTestValueSet<Visualizer, int, Range::visualizer,
+ Visualizer::captureSamples>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
+ testing::ValuesIn(VisualizerParamTest::getScalingModeValues()),
+ testing::ValuesIn(VisualizerParamTest::getMeasurementModeValues()),
+ testing::ValuesIn(EffectHelper::getTestValueSet<Visualizer, int, Range::visualizer,
+ Visualizer::latencyMs>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>))),
[](const testing::TestParamInfo<VisualizerParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
std::string captureSize = std::to_string(std::get<PARAM_CAPTURE_SIZE>(info.param));
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 34625e7..44ce146 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -22,7 +22,6 @@
using namespace android;
-using aidl::android::hardware::audio::effect::Capability;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
@@ -84,9 +83,7 @@
// validate parameter
Descriptor desc;
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
- // only set and get parameter if capability is valid
- ASSERT_TRUE(isCapabilityValid(desc));
- const bool valid = isTagInRange(it.first, it.second, desc);
+ const bool valid = isParameterValid<Volume, Range::volume>(it.second, desc);
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
// set parameter
@@ -123,42 +120,6 @@
mTags.push_back({Volume::mute, vol});
}
- bool isCapabilityValid(const Descriptor& desc) {
- const Volume::Capability& volCap = desc.capability.get<Capability::volume>();
- return (volCap.minLevelDb <= volCap.maxLevelDb);
- }
-
- bool isTagInRange(const Volume::Tag& tag, const Volume& vol, const Descriptor& desc) const {
- const Volume::Capability& volCap = desc.capability.get<Capability::volume>();
- switch (tag) {
- case Volume::levelDb: {
- int level = vol.get<Volume::levelDb>();
- return isLevelInRange(volCap, level);
- }
- case Volume::mute:
- return true;
- default:
- return false;
- }
- }
-
- static std::vector<int> getLevelTestValues(
- std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList) {
- int minLevelDb = std::numeric_limits<int>::max();
- int maxLevelDb = std::numeric_limits<int>::min();
- for (const auto& it : kFactoryDescList) {
- maxLevelDb =
- std::max(it.second.capability.get<Capability::volume>().maxLevelDb, maxLevelDb);
- minLevelDb = std::min(it.second.capability.get<Capability ::volume>().minLevelDb,
- minLevelDb);
- }
- return {minLevelDb - 1, minLevelDb, -100, maxLevelDb, maxLevelDb + 1};
- }
-
- bool isLevelInRange(const Volume::Capability& volCap, int level) const {
- return level >= volCap.minLevelDb && level <= volCap.maxLevelDb;
- }
-
private:
std::vector<std::pair<Volume::Tag, Volume>> mTags;
void CleanUp() { mTags.clear(); }
@@ -174,14 +135,15 @@
SetAndGetParameters();
}
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
INSTANTIATE_TEST_SUITE_P(
VolumeTest, VolumeParamTest,
::testing::Combine(
- testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kVolumeTypeUUID)),
- testing::ValuesIn(VolumeParamTest::getLevelTestValues(
- EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
- kVolumeTypeUUID))),
+ testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kVolumeTypeUUID)),
+ testing::ValuesIn(
+ EffectHelper::getTestValueSet<Volume, int, Range::volume, Volume::levelDb>(
+ kDescPair, EffectHelper::expandTestValueBasic<int>)),
testing::Bool() /* mute */),
[](const testing::TestParamInfo<VolumeParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
diff --git a/audio/common/all-versions/default/service/service.cpp b/audio/common/all-versions/default/service/service.cpp
index e79ad75..7b5a932 100644
--- a/audio/common/all-versions/default/service/service.cpp
+++ b/audio/common/all-versions/default/service/service.cpp
@@ -81,9 +81,10 @@
int main(int /* argc */, char* /* argv */ []) {
signal(SIGPIPE, SIG_IGN);
- ::android::ProcessState::initWithDriver("/dev/vndbinder");
- // start a threadpool for vndbinder interactions
- ::android::ProcessState::self()->startThreadPool();
+ if (::android::ProcessState::isVndservicemanagerEnabled()) {
+ ::android::ProcessState::initWithDriver("/dev/vndbinder");
+ ::android::ProcessState::self()->startThreadPool();
+ }
ABinderProcess_setThreadPoolMaxThreadCount(1);
ABinderProcess_startThreadPool();
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 98e49a2..478482d 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -1698,26 +1698,6 @@
ASSERT_EQ(0U, framesLost);
}
-TEST_P(InputStreamTest, getCapturePosition) {
- doc::test(
- "The capture position of a non prepared stream should not be "
- "retrievable or 0");
- uint64_t frames;
- uint64_t time;
- ASSERT_OK(stream->getCapturePosition(returnIn(res, frames, time)));
- // Although 'getCapturePosition' is mandatory in V7, legacy implementations
- // may return -ENOSYS (which is translated to NOT_SUPPORTED) in cases when
- // the capture position can't be retrieved, e.g. when the stream isn't
- // running. Because of this, we don't fail when getting NOT_SUPPORTED
- // in this test. Behavior of 'getCapturePosition' for running streams is
- // tested in 'PcmOnlyConfigInputStreamTest' for V7.
- ASSERT_RESULT(okOrInvalidStateOrNotSupported, res);
- if (res == Result::OK) {
- ASSERT_EQ(0U, frames);
- ASSERT_LE(0U, time);
- }
-}
-
//////////////////////////////////////////////////////////////////////////////
///////////////////////////////// StreamOut //////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
diff --git a/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl
index db12986..ff1f735 100644
--- a/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl
+++ b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHci.aidl
@@ -35,6 +35,9 @@
/**
* Initialize the Bluetooth interface and set the callbacks.
+ * Only one client can initialize the interface at a time. When a
+ * call to initialize fails, the Status parameter of the callback
+ * will indicate the reason for the failure.
*/
void initialize(in IBluetoothHciCallbacks callback);
diff --git a/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
index 000333e..0148c6f 100644
--- a/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
+++ b/bluetooth/aidl/android/hardware/bluetooth/IBluetoothHciCallbacks.aidl
@@ -39,6 +39,8 @@
/**
* Invoked when the Bluetooth controller initialization has been
* completed.
+ * @param status contains a return code indicating success, or the
+ * reason the initialization failed.
*/
void initializationComplete(in Status status);
diff --git a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
index 7b9e211..3704c3d 100644
--- a/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
+++ b/bluetooth/aidl/vts/VtsHalBluetoothTargetTest.cpp
@@ -867,6 +867,48 @@
wait_for_command_complete_event(set_event_mask);
}
+// Call initialize twice, second one should fail.
+TEST_P(BluetoothAidlTest, CallInitializeTwice) {
+ class SecondCb
+ : public aidl::android::hardware::bluetooth::BnBluetoothHciCallbacks {
+ public:
+ ndk::ScopedAStatus initializationComplete(Status status) {
+ EXPECT_EQ(status, Status::ALREADY_INITIALIZED);
+ init_promise.set_value();
+ return ScopedAStatus::ok();
+ };
+
+ ndk::ScopedAStatus hciEventReceived(const std::vector<uint8_t>& /*event*/) {
+ ADD_FAILURE();
+ return ScopedAStatus::ok();
+ };
+
+ ndk::ScopedAStatus aclDataReceived(const std::vector<uint8_t>& /*data*/) {
+ ADD_FAILURE();
+ return ScopedAStatus::ok();
+ };
+
+ ndk::ScopedAStatus scoDataReceived(const std::vector<uint8_t>& /*data*/) {
+ ADD_FAILURE();
+ return ScopedAStatus::ok();
+ };
+
+ ndk::ScopedAStatus isoDataReceived(const std::vector<uint8_t>& /*data*/) {
+ ADD_FAILURE();
+ return ScopedAStatus::ok();
+ };
+ std::promise<void> init_promise;
+ };
+
+ std::shared_ptr<SecondCb> second_cb = ndk::SharedRefBase::make<SecondCb>();
+ ASSERT_NE(second_cb, nullptr);
+
+ auto future = second_cb->init_promise.get_future();
+ ASSERT_TRUE(hci->initialize(second_cb).isOk());
+ auto status = future.wait_for(std::chrono::seconds(1));
+ ASSERT_EQ(status, std::future_status::ready);
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAidlTest);
INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
index 899b8ca..e548cd3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -39,4 +39,5 @@
android.hardware.bluetooth.audio.ChannelMode[] channelMode;
boolean variableBitRateSupported;
byte[] bitsPerSample;
+ boolean adaptiveBitRateSupported;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
index 6adef6d..29ab8ce 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -39,4 +39,5 @@
android.hardware.bluetooth.audio.ChannelMode channelMode;
boolean variableBitRateEnabled;
byte bitsPerSample;
+ boolean adaptiveBitRateSupported;
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
similarity index 79%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
index 50a5528..c9d3cde 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,15 +31,12 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+ byte[] pcmBitDepth;
+ int[] samplingFrequencyHz;
+ int[] frameDurationUs;
+ int[] octetsPerFrame;
+ byte[] blocksPerSdu;
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
similarity index 79%
rename from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
rename to bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
index 50a5528..76df4ed 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,15 +31,13 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.bluetooth.audio;
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+ byte pcmBitDepth;
+ int samplingFrequencyHz;
+ int frameDurationUs;
+ int octetsPerFrame;
+ byte blocksPerSdu;
+ int codecMode;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index d1723e6..3e204f9 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -44,4 +44,6 @@
VENDOR = 7,
APTX_ADAPTIVE = 8,
OPUS = 9,
+ APTX_ADAPTIVE_LE = 10,
+ APTX_ADAPTIVE_LEX = 11,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
index 5583679..1140f9e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -34,7 +34,9 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum LatencyMode {
- UNKNOWN = 0,
- LOW_LATENCY = 1,
- FREE = 2,
+ UNKNOWN,
+ LOW_LATENCY,
+ FREE,
+ DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+ DYNAMIC_SPATIAL_AUDIO_HARDWARE,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index 7d53b0c..2945710 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -41,5 +41,6 @@
char streamHandle;
int audioChannelAllocation;
android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+ char pcmStreamId;
}
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index bb3d7e4..031ee67 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -36,6 +36,7 @@
union LeAudioCodecConfiguration {
android.hardware.bluetooth.audio.Lc3Configuration lc3Config;
android.hardware.bluetooth.audio.LeAudioCodecConfiguration.VendorConfiguration vendorConfig;
+ android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
@VintfStability
parcelable VendorConfiguration {
ParcelableHolder extension;
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index edb6795..2d9ebae 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -38,9 +38,11 @@
android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
int peerDelayUs;
android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig;
+ @nullable byte[] vendorSpecificMetadata;
@VintfStability
parcelable StreamMap {
char streamHandle;
int audioChannelAllocation;
+ boolean isStreamActive;
}
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
index 2781893..2c04b0f 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusCapabilities.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
index 067690e..811d32a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/OpusConfiguration.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
index 130fef9..894a2f3 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -47,5 +47,6 @@
union LeAudioCodecCapabilities {
android.hardware.bluetooth.audio.Lc3Capabilities lc3Capabilities;
android.hardware.bluetooth.audio.UnicastCapability.VendorCapabilities vendorCapabillities;
+ android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
}
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
index c4153e9..d7d67de 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacCapabilities.aidl
@@ -29,4 +29,5 @@
ChannelMode[] channelMode;
boolean variableBitRateSupported;
byte[] bitsPerSample;
+ boolean adaptiveBitRateSupported;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
index 30338e7..34998cd 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AacConfiguration.aidl
@@ -29,4 +29,5 @@
ChannelMode channelMode;
boolean variableBitRateEnabled;
byte bitsPerSample;
+ boolean adaptiveBitRateSupported;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
new file mode 100644
index 0000000..b3fe71c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding Aptx Adaptive LE codec capabilities.
+ */
+@VintfStability
+parcelable AptxAdaptiveLeCapabilities {
+ /*
+ * PCM is Input for encoder, Output for decoder
+ */
+ byte[] pcmBitDepth;
+ /*
+ * codec-specific parameters
+ */
+ int[] samplingFrequencyHz;
+ /*
+ * FrameDuration based on microseconds.
+ */
+ int[] frameDurationUs;
+ /*
+ * length in octets of a codec frame
+ */
+ int[] octetsPerFrame;
+ /*
+ * Number of blocks of codec frames per single SDU (Service Data Unit)
+ */
+ byte[] blocksPerSdu;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
new file mode 100644
index 0000000..060d5d5
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Used for Hardware Encoding/Decoding Aptx Adaptive LE/LEX codec configuration.
+ */
+@VintfStability
+parcelable AptxAdaptiveLeConfiguration {
+ /*
+ * PCM is Input for encoder, Output for decoder
+ */
+ byte pcmBitDepth;
+ /*
+ * codec-specific parameters
+ */
+ int samplingFrequencyHz;
+ /*
+ * FrameDuration based on microseconds.
+ */
+ int frameDurationUs;
+ /*
+ * length in octets of a codec frame
+ */
+ int octetsPerFrame;
+ /*
+ * Number of blocks of codec frames per single SDU (Service Data Unit)
+ */
+ byte blocksPerSdu;
+ /*
+ * Currently being used for Aptx Adaptive LEX,
+ * RFU for Aptx Adaptive LE
+ * Based on this value, the codec will determine the quality of stream
+ * during initialization for Music/Game
+ */
+ int codecMode;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
index 3499155..1d8acdf 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecType.aidl
@@ -29,4 +29,6 @@
VENDOR,
APTX_ADAPTIVE,
OPUS,
+ APTX_ADAPTIVE_LE,
+ APTX_ADAPTIVE_LEX,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
index 0c354f7..ec181c1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LatencyMode.aidl
@@ -22,4 +22,6 @@
UNKNOWN,
LOW_LATENCY,
FREE,
+ DYNAMIC_SPATIAL_AUDIO_SOFTWARE,
+ DYNAMIC_SPATIAL_AUDIO_HARDWARE
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
index e9a1a0c..16503fb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl
@@ -35,6 +35,10 @@
*/
int audioChannelAllocation;
LeAudioCodecConfiguration leAudioCodecConfig;
+ /*
+ * Pcm stream id to identify the source for given streamHandle.
+ */
+ char pcmStreamId;
}
CodecType codecType;
BroadcastStreamMap[] streamMap;
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
index 421eeb2..7ce6ff3 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioCodecConfiguration.aidl
@@ -17,6 +17,7 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.Lc3Configuration;
+import android.hardware.bluetooth.audio.AptxAdaptiveLeConfiguration;
@VintfStability
union LeAudioCodecConfiguration {
@@ -26,4 +27,5 @@
}
Lc3Configuration lc3Config;
VendorConfiguration vendorConfig;
+ AptxAdaptiveLeConfiguration aptxAdaptiveLeConfig;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
index 0d1e3de..7302aea 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl
@@ -35,9 +35,25 @@
* Audio Location assigned number.
*/
int audioChannelAllocation;
+ /*
+ * The stream handle status
+ */
+ boolean isStreamActive;
}
CodecType codecType;
StreamMap[] streamMap;
int peerDelayUs;
LeAudioCodecConfiguration leAudioCodecConfig;
+
+ /*
+ * Bluetooth LTV format for vendor metadata is defined in the
+ * Section 6.12.6.9 Vendor_Specific of Bluetooth Assigned Numbers
+ *
+ * Octet 0 = Length
+ * Octet 1 = Type (Vendor specific - 0xFF)
+ * Octet 2-3 = Company_ID
+ * Company ID values are defined in Bluetooth Assigned Numbers.
+ * Octet 4 onwards = Vendor specific Metadata
+ */
+ @nullable byte[] vendorSpecificMetadata;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
index f8a924a..07688a7 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/UnicastCapability.aidl
@@ -19,6 +19,7 @@
import android.hardware.bluetooth.audio.AudioLocation;
import android.hardware.bluetooth.audio.CodecType;
import android.hardware.bluetooth.audio.Lc3Capabilities;
+import android.hardware.bluetooth.audio.AptxAdaptiveLeCapabilities;
/**
* Used to specify the le audio unicast codec capabilities for hardware offload.
@@ -33,6 +34,7 @@
union LeAudioCodecCapabilities {
Lc3Capabilities lc3Capabilities;
VendorCapabilities vendorCapabillities;
+ AptxAdaptiveLeCapabilities aptxAdaptiveLeCapabilities;
}
CodecType codecType;
AudioLocation supportedChannel;
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index cbf23dc..e4c2844 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -29,7 +29,7 @@
"libcutils",
"libfmq",
"liblog",
- "android.hardware.bluetooth.audio-V2-ndk",
+ "android.hardware.bluetooth.audio-V3-ndk",
"libbluetooth_audio_session_aidl",
],
}
diff --git a/bluetooth/audio/aidl/default/bluetooth_audio.xml b/bluetooth/audio/aidl/default/bluetooth_audio.xml
index c4b1872..c0bc55e 100644
--- a/bluetooth/audio/aidl/default/bluetooth_audio.xml
+++ b/bluetooth/audio/aidl/default/bluetooth_audio.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.bluetooth.audio</name>
- <version>2</version>
+ <version>3</version>
<fqname>IBluetoothAudioProviderFactory/default</fqname>
</hal>
</manifest>
diff --git a/bluetooth/audio/aidl/vts/Android.bp b/bluetooth/audio/aidl/vts/Android.bp
index 3aed1b3..e03fb58 100644
--- a/bluetooth/audio/aidl/vts/Android.bp
+++ b/bluetooth/audio/aidl/vts/Android.bp
@@ -17,7 +17,7 @@
srcs: ["VtsHalBluetoothAudioTargetTest.cpp"],
shared_libs: [
"android.hardware.audio.common-V1-ndk",
- "android.hardware.bluetooth.audio-V2-ndk",
+ "android.hardware.bluetooth.audio-V3-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
"libbase",
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index e9b74b7..858fa38 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -35,6 +35,8 @@
using aidl::android::hardware::audio::common::SourceMetadata;
using aidl::android::hardware::bluetooth::audio::AacCapabilities;
using aidl::android::hardware::bluetooth::audio::AacConfiguration;
+using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
+using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeConfiguration;
using aidl::android::hardware::bluetooth::audio::AptxCapabilities;
using aidl::android::hardware::bluetooth::audio::AptxConfiguration;
using aidl::android::hardware::bluetooth::audio::AudioCapabilities;
@@ -87,10 +89,6 @@
static constexpr int8_t a2dp_bits_per_samples[] = {0, 16, 24, 32};
static constexpr ChannelMode a2dp_channel_modes[] = {
ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
-static constexpr CodecType a2dp_codec_types[] = {
- CodecType::UNKNOWN, CodecType::SBC, CodecType::AAC,
- CodecType::APTX, CodecType::APTX_HD, CodecType::LDAC,
- CodecType::LC3, CodecType::APTX_ADAPTIVE};
static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
// Helpers
@@ -238,6 +236,8 @@
CodecCapabilities::Capabilities::opusCapabilities);
break;
case CodecType::APTX_ADAPTIVE:
+ case CodecType::APTX_ADAPTIVE_LE:
+ case CodecType::APTX_ADAPTIVE_LEX:
case CodecType::LC3:
case CodecType::VENDOR:
case CodecType::UNKNOWN:
@@ -387,6 +387,11 @@
variable_bit_rate_enableds.push_back(true);
}
+ std::vector<bool> adaptive_bit_rate_supporteds = {false};
+ if (aac_capability.adaptiveBitRateSupported) {
+ adaptive_bit_rate_supporteds.push_back(true);
+ }
+
// combine those parameters into one list of
// CodecConfiguration::CodecSpecific
for (auto object_type : aac_capability.objectType) {
@@ -394,14 +399,18 @@
for (auto channel_mode : aac_capability.channelMode) {
for (int8_t bits_per_sample : aac_capability.bitsPerSample) {
for (auto variable_bit_rate_enabled : variable_bit_rate_enableds) {
- AacConfiguration aac_data{
- .objectType = object_type,
- .sampleRateHz = sample_rate,
- .channelMode = channel_mode,
- .variableBitRateEnabled = variable_bit_rate_enabled,
- .bitsPerSample = bits_per_sample};
- aac_codec_specifics.push_back(
- CodecConfiguration::CodecSpecific(aac_data));
+ for (auto adaptive_bit_rate_supported :
+ adaptive_bit_rate_supporteds) {
+ AacConfiguration aac_data{
+ .objectType = object_type,
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .variableBitRateEnabled = variable_bit_rate_enabled,
+ .bitsPerSample = bits_per_sample,
+ .adaptiveBitRateSupported = adaptive_bit_rate_supported};
+ aac_codec_specifics.push_back(
+ CodecConfiguration::CodecSpecific(aac_data));
+ }
}
}
}
@@ -845,7 +854,7 @@
ASSERT_NE(audio_provider_, nullptr);
std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
- for (auto codec_type : a2dp_codec_types) {
+ for (auto codec_type : ndk::enum_range<CodecType>()) {
switch (codec_type) {
case CodecType::SBC:
codec_specifics = GetSbcCodecSpecificSupportedList(false);
@@ -866,6 +875,8 @@
codec_specifics = GetOpusCodecSpecificSupportedList(false);
continue;
case CodecType::APTX_ADAPTIVE:
+ case CodecType::APTX_ADAPTIVE_LE:
+ case CodecType::APTX_ADAPTIVE_LEX:
case CodecType::LC3:
case CodecType::VENDOR:
case CodecType::UNKNOWN:
@@ -1192,6 +1203,73 @@
return le_audio_codec_configs;
}
+ static constexpr int32_t apx_adaptive_le_config_codec_modes[] = {0, 1, 2, 3};
+
+ std::vector<AptxAdaptiveLeConfiguration>
+ GetUnicastAptxAdaptiveLeSupportedList(bool decoding, bool supported,
+ bool is_le_extended) {
+ std::vector<AptxAdaptiveLeConfiguration> le_audio_codec_configs;
+ if (!supported) {
+ AptxAdaptiveLeConfiguration aptx_adaptive_le_config{
+ .pcmBitDepth = 0, .samplingFrequencyHz = 0};
+ le_audio_codec_configs.push_back(aptx_adaptive_le_config);
+ return le_audio_codec_configs;
+ }
+
+ // There might be more than one LeAudioCodecCapabilitiesSetting
+ std::vector<AptxAdaptiveLeCapabilities> aptx_adaptive_le_capabilities;
+ for (auto& capability : temp_provider_capabilities_) {
+ if (capability.getTag() != AudioCapabilities::leAudioCapabilities) {
+ continue;
+ }
+ auto& le_audio_capability =
+ capability.get<AudioCapabilities::leAudioCapabilities>();
+ auto& unicast_capability =
+ decoding ? le_audio_capability.unicastDecodeCapability
+ : le_audio_capability.unicastEncodeCapability;
+ if ((!is_le_extended &&
+ unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LE) ||
+ (is_le_extended &&
+ unicast_capability.codecType != CodecType::APTX_ADAPTIVE_LEX)) {
+ continue;
+ }
+
+ auto& aptx_adaptive_le_capability =
+ unicast_capability.leAudioCodecCapabilities
+ .get<UnicastCapability::LeAudioCodecCapabilities::
+ aptxAdaptiveLeCapabilities>();
+
+ aptx_adaptive_le_capabilities.push_back(aptx_adaptive_le_capability);
+ }
+
+ for (auto& aptx_adaptive_le_capability : aptx_adaptive_le_capabilities) {
+ for (int32_t samplingFrequencyHz :
+ aptx_adaptive_le_capability.samplingFrequencyHz) {
+ for (int32_t frameDurationUs :
+ aptx_adaptive_le_capability.frameDurationUs) {
+ for (int32_t octetsPerFrame :
+ aptx_adaptive_le_capability.octetsPerFrame) {
+ for (int8_t blocksPerSdu :
+ aptx_adaptive_le_capability.blocksPerSdu) {
+ for (int32_t codecMode : apx_adaptive_le_config_codec_modes) {
+ AptxAdaptiveLeConfiguration aptx_adaptive_le_config = {
+ .samplingFrequencyHz = samplingFrequencyHz,
+ .frameDurationUs = frameDurationUs,
+ .octetsPerFrame = octetsPerFrame,
+ .blocksPerSdu = blocksPerSdu,
+ .codecMode = codecMode,
+ };
+ le_audio_codec_configs.push_back(aptx_adaptive_le_config);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return le_audio_codec_configs;
+ }
+
LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_;
};
@@ -1268,6 +1346,87 @@
}
}
+static std::vector<uint8_t> vendorMetadata = {0x0B, // Length
+ 0xFF, // Type: Vendor-specific
+ 0x0A, 0x00, // Company_ID
+ 0x01, 0x02, 0x03, 0x04, // Data
+ 0x05, 0x06, 0x07, 0x08};
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ StartAndEndLeAudioOutputSessionWithAptxAdaptiveLeUnicastConfig) {
+ if (!IsOffloadOutputSupported()) {
+ return;
+ }
+ for (auto codec_type :
+ {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+ bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
+ auto aptx_adaptive_le_codec_configs =
+ GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
+ LeAudioConfiguration le_audio_config = {
+ .codecType = codec_type,
+ .peerDelayUs = 0,
+ .vendorSpecificMetadata = vendorMetadata,
+ };
+
+ for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
+ aptx_adaptive_le_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+}
+
+/**
+ * Test whether each provider of type
+ * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
+ * stopped with Unicast hardware encoding config
+ */
+TEST_P(
+ BluetoothAudioProviderLeAudioOutputHardwareAidl,
+ BluetoothAudioProviderLeAudioOutputHardwareAidl_StartAndEndLeAudioOutputSessionWithInvalidAptxAdaptiveLeAudioConfiguration) {
+ if (!IsOffloadOutputSupported()) {
+ return;
+ }
+
+ for (auto codec_type :
+ {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+ bool is_le_extended = (codec_type == CodecType::APTX_ADAPTIVE_LEX);
+ auto aptx_adaptive_le_codec_configs =
+ GetUnicastAptxAdaptiveLeSupportedList(false, true, is_le_extended);
+ LeAudioConfiguration le_audio_config = {
+ .codecType = codec_type,
+ .peerDelayUs = 0,
+ .vendorSpecificMetadata = vendorMetadata,
+ };
+
+ for (auto& aptx_adaptive_le_config : aptx_adaptive_le_codec_configs) {
+ le_audio_config.leAudioCodecConfig
+ .set<LeAudioCodecConfiguration::aptxAdaptiveLeConfig>(
+ aptx_adaptive_le_config);
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(le_audio_config), latency_modes,
+ &mq_desc);
+
+ // AIDL call should fail on invalid codec
+ ASSERT_FALSE(aidl_retval.isOk());
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+}
+
/**
* openProvider LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH
*/
@@ -1566,9 +1725,14 @@
};
for (auto& lc3_config : lc3_codec_configs) {
+ le_audio_broadcast_config.streamMap.resize(1);
le_audio_broadcast_config.streamMap[0]
.leAudioCodecConfig.set<LeAudioCodecConfiguration::lc3Config>(
lc3_config);
+ le_audio_broadcast_config.streamMap[0].streamHandle = 0x0;
+ le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0;
+ le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0;
+
DataMQDesc mq_desc;
auto aidl_retval = audio_provider_->startSession(
audio_port_, AudioConfiguration(le_audio_broadcast_config),
@@ -1872,7 +2036,7 @@
ASSERT_NE(audio_provider_, nullptr);
std::vector<CodecConfiguration::CodecSpecific> codec_specifics;
- for (auto codec_type : a2dp_codec_types) {
+ for (auto codec_type : ndk::enum_range<CodecType>()) {
switch (codec_type) {
case CodecType::SBC:
codec_specifics = GetSbcCodecSpecificSupportedList(false);
@@ -1893,6 +2057,8 @@
codec_specifics = GetOpusCodecSpecificSupportedList(false);
continue;
case CodecType::APTX_ADAPTIVE:
+ case CodecType::APTX_ADAPTIVE_LE:
+ case CodecType::APTX_ADAPTIVE_LEX:
case CodecType::LC3:
case CodecType::VENDOR:
case CodecType::UNKNOWN:
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 70797a7..914d2b2 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -55,7 +55,7 @@
"libbinder_ndk",
"libfmq",
"liblog",
- "android.hardware.bluetooth.audio-V2-ndk",
+ "android.hardware.bluetooth.audio-V3-ndk",
"libhidlbase",
"libxml2",
],
@@ -75,7 +75,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.bluetooth.audio-V2-ndk",
+ "android.hardware.bluetooth.audio-V3-ndk",
"libxml2",
],
test_suites: [
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index faebbbf..3ed9e07 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -20,6 +20,8 @@
#include <aidl/android/hardware/bluetooth/audio/AacCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/AacObjectType.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeCapabilities.h>
+#include <aidl/android/hardware/bluetooth/audio/AptxAdaptiveLeConfiguration.h>
#include <aidl/android/hardware/bluetooth/audio/AptxCapabilities.h>
#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
#include <aidl/android/hardware/bluetooth/audio/LdacCapabilities.h>
@@ -98,6 +100,55 @@
std::vector<LeAudioCodecCapabilitiesSetting> kDefaultOffloadLeAudioCapabilities;
+static const UnicastCapability kInvalidUnicastCapability = {
+ .codecType = CodecType::UNKNOWN};
+
+static const AptxAdaptiveLeCapabilities
+ kDefaultOffloadAptxAdaptiveLeCapability_48k = {
+ .samplingFrequencyHz = {48000},
+ .frameDurationUs = {10000},
+ .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+ kDefaultOffloadAptxAdaptiveLeCapability_96k = {
+ .samplingFrequencyHz = {96000},
+ .frameDurationUs = {10000},
+ .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+ kDefaultOffloadAptxAdaptiveLeXCapability_48k = {
+ .samplingFrequencyHz = {48000},
+ .frameDurationUs = {10000},
+ .octetsPerFrame = {816}};
+
+static const AptxAdaptiveLeCapabilities
+ kDefaultOffloadAptxAdaptiveLeXCapability_96k = {
+ .samplingFrequencyHz = {96000},
+ .frameDurationUs = {10000},
+ .octetsPerFrame = {816}};
+
+static const BroadcastCapability kInvalidBroadcastCapability = {
+ .codecType = CodecType::UNKNOWN};
+
+static AudioLocation stereoAudio = static_cast<AudioLocation>(
+ static_cast<uint8_t>(AudioLocation::FRONT_LEFT) |
+ static_cast<uint8_t>(AudioLocation::FRONT_RIGHT));
+
+static const std::vector<AptxAdaptiveLeCapabilities>
+ supportedAptxAdaptiveLeCapabilityList = {
+ kDefaultOffloadAptxAdaptiveLeCapability_48k,
+ kDefaultOffloadAptxAdaptiveLeCapability_96k,
+ kDefaultOffloadAptxAdaptiveLeXCapability_48k,
+ kDefaultOffloadAptxAdaptiveLeXCapability_96k};
+
+// Stores the supported setting of audio location, connected device, and the
+// channel count for each device
+std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
+ supportedDeviceSetting = {
+ // Stereo, one connected device for both L and R
+ std::make_tuple(stereoAudio, 1, 2),
+};
+
template <class T>
bool BluetoothAudioCodecs::ContainedInVector(
const std::vector<T>& vector, const typename identity<T>::type& target) {
@@ -312,6 +363,8 @@
case CodecType::VENDOR:
case CodecType::LC3:
case CodecType::APTX_ADAPTIVE:
+ case CodecType::APTX_ADAPTIVE_LE:
+ case CodecType::APTX_ADAPTIVE_LEX:
break;
}
}
@@ -377,6 +430,8 @@
}
break;
case CodecType::APTX_ADAPTIVE:
+ case CodecType::APTX_ADAPTIVE_LE:
+ case CodecType::APTX_ADAPTIVE_LEX:
case CodecType::LC3:
case CodecType::UNKNOWN:
case CodecType::VENDOR:
@@ -403,8 +458,33 @@
kDefaultOffloadLeAudioCapabilities =
BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
le_audio_offload_setting);
- }
+ for (auto [audioLocation, deviceCnt, channelCount] :
+ supportedDeviceSetting) {
+ for (auto capability : supportedAptxAdaptiveLeCapabilityList) {
+ for (auto codec_type :
+ {CodecType::APTX_ADAPTIVE_LE, CodecType::APTX_ADAPTIVE_LEX}) {
+ if (session_type ==
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH) {
+ UnicastCapability aptx_adaptive_le_cap = {
+ .codecType = codec_type,
+ .supportedChannel = audioLocation,
+ .deviceCount = deviceCnt,
+ .channelCountPerDevice = channelCount,
+ .leAudioCodecCapabilities =
+ UnicastCapability::LeAudioCodecCapabilities(capability),
+ };
+
+ // Adds the capability for encode only
+ kDefaultOffloadLeAudioCapabilities.push_back(
+ {.unicastEncodeCapability = aptx_adaptive_le_cap,
+ .unicastDecodeCapability = kInvalidUnicastCapability,
+ .broadcastCapability = kInvalidBroadcastCapability});
+ }
+ }
+ }
+ }
+ }
return kDefaultOffloadLeAudioCapabilities;
}
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
index 1dec900..0a804bb 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
@@ -200,13 +200,21 @@
GetUnicastCapability(scenario.getEncode());
UnicastCapability unicast_decode_capability =
GetUnicastCapability(scenario.getDecode());
- // encode and decode cannot be unknown at the same time
- if (unicast_encode_capability.codecType == CodecType::UNKNOWN &&
- unicast_decode_capability.codecType == CodecType::UNKNOWN) {
- continue;
- }
BroadcastCapability broadcast_capability = {.codecType =
CodecType::UNKNOWN};
+
+ if (scenario.hasBroadcast()) {
+ broadcast_capability = GetBroadcastCapability(scenario.getBroadcast());
+ }
+
+ // At least one capability should be valid
+ if (unicast_encode_capability.codecType == CodecType::UNKNOWN &&
+ unicast_decode_capability.codecType == CodecType::UNKNOWN &&
+ broadcast_capability.codecType == CodecType::UNKNOWN) {
+ LOG(ERROR) << __func__ << ": None of the capability is valid.";
+ continue;
+ }
+
le_audio_codec_capabilities.push_back(
{.unicastEncodeCapability = unicast_encode_capability,
.unicastDecodeCapability = unicast_decode_capability,
@@ -252,6 +260,54 @@
return {.codecType = CodecType::UNKNOWN};
}
+BroadcastCapability BluetoothLeAudioCodecsProvider::GetBroadcastCapability(
+ const std::string& coding_direction) {
+ if (coding_direction == "invalid") {
+ return {.codecType = CodecType::UNKNOWN};
+ }
+
+ auto configuration_iter = configuration_map_.find(coding_direction);
+ if (configuration_iter == configuration_map_.end()) {
+ return {.codecType = CodecType::UNKNOWN};
+ }
+
+ auto codec_configuration_iter = codec_configuration_map_.find(
+ configuration_iter->second.getCodecConfiguration());
+ if (codec_configuration_iter == codec_configuration_map_.end()) {
+ return {.codecType = CodecType::UNKNOWN};
+ }
+
+ auto strategy_configuration_iter = strategy_configuration_map_.find(
+ configuration_iter->second.getStrategyConfiguration());
+ if (strategy_configuration_iter == strategy_configuration_map_.end()) {
+ return {.codecType = CodecType::UNKNOWN};
+ }
+
+ CodecType codec_type =
+ GetCodecType(codec_configuration_iter->second.getCodec());
+ std::vector<std::optional<Lc3Capabilities>> bcastLc3Cap(
+ 1, std::optional(ComposeLc3Capability(codec_configuration_iter->second)));
+
+ if (codec_type == CodecType::LC3) {
+ return ComposeBroadcastCapability(
+ codec_type,
+ GetAudioLocation(
+ strategy_configuration_iter->second.getAudioLocation()),
+ strategy_configuration_iter->second.getChannelCount(), bcastLc3Cap);
+ }
+ return {.codecType = CodecType::UNKNOWN};
+}
+
+template <class T>
+BroadcastCapability BluetoothLeAudioCodecsProvider::ComposeBroadcastCapability(
+ const CodecType& codec_type, const AudioLocation& audio_location,
+ const uint8_t& channel_count, const std::vector<T>& capability) {
+ return {.codecType = codec_type,
+ .supportedChannel = audio_location,
+ .channelCountPerStream = channel_count,
+ .leAudioCodecCapabilities = std::optional(capability)};
+}
+
template <class T>
UnicastCapability BluetoothLeAudioCodecsProvider::ComposeUnicastCapability(
const CodecType& codec_type, const AudioLocation& audio_location,
@@ -322,6 +378,10 @@
// 1. two connected device, one for L one for R
// 2. one connected device for both L and R
return true;
+ } else if (strategy_configuration.getConnectedDevice() == 0 &&
+ strategy_configuration.getChannelCount() == 2) {
+ // Broadcast
+ return true;
}
} else if (strategy_configuration.getAudioLocation() ==
setting::AudioLocation::MONO) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
index e879984..06e4595 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
@@ -20,6 +20,7 @@
#include <android-base/logging.h>
#include <unordered_map>
+#include <vector>
#include "aidl_android_hardware_bluetooth_audio_setting.h"
@@ -66,12 +67,20 @@
static UnicastCapability GetUnicastCapability(
const std::string& coding_direction);
+ static BroadcastCapability GetBroadcastCapability(
+ const std::string& coding_direction);
+
template <class T>
static inline UnicastCapability ComposeUnicastCapability(
const CodecType& codec_type, const AudioLocation& audio_location,
const uint8_t& device_cnt, const uint8_t& channel_count,
const T& capability);
+ template <class T>
+ static inline BroadcastCapability ComposeBroadcastCapability(
+ const CodecType& codec_type, const AudioLocation& audio_location,
+ const uint8_t& channel_count, const std::vector<T>& capability);
+
static inline Lc3Capabilities ComposeLc3Capability(
const setting::CodecConfiguration& codec_configuration);
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
index 5393cd7..dba2749 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
@@ -46,7 +46,11 @@
// Define valid components for each list
// Scenario
static const Scenario kValidScenario(std::make_optional("OneChanStereo_16_1"),
- std::make_optional("OneChanStereo_16_1"));
+ std::make_optional("OneChanStereo_16_1"),
+ std::nullopt);
+static const Scenario kValidBroadcastScenario(
+ std::nullopt, std::nullopt, std::make_optional("BcastStereo_16_2"));
+
// Configuration
static const Configuration kValidConfigOneChanStereo_16_1(
std::make_optional("OneChanStereo_16_1"), std::make_optional("LC3_16k_1"),
@@ -69,11 +73,15 @@
std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
std::make_optional(AudioLocation::MONO), std::make_optional(1),
std::make_optional(1));
+static const StrategyConfiguration kValidStrategyBroadcastStereo(
+ std::make_optional("BROADCAST_STEREO"),
+ std::make_optional(AudioLocation::STEREO), std::make_optional(0),
+ std::make_optional(2));
// Define valid test list built from above valid components
// Scenario, Configuration, CodecConfiguration, StrategyConfiguration
-static const std::vector<ScenarioList> kValidScenarioList = {
- ScenarioList(std::vector<Scenario>{kValidScenario})};
+static const std::vector<ScenarioList> kValidScenarioList = {ScenarioList(
+ std::vector<Scenario>{kValidScenario, kValidBroadcastScenario})};
static const std::vector<ConfigurationList> kValidConfigurationList = {
ConfigurationList(
std::vector<Configuration>{kValidConfigOneChanStereo_16_1})};
@@ -84,7 +92,7 @@
kValidStrategyConfigurationList = {
StrategyConfigurationList(std::vector<StrategyConfiguration>{
kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis,
- kValidStrategyMonoOneCis})};
+ kValidStrategyMonoOneCis, kValidStrategyBroadcastStereo})};
class BluetoothLeAudioCodecsProviderTest
: public ::testing::TestWithParam<OffloadSetting> {
@@ -151,13 +159,15 @@
static std::vector<ScenarioList> CreateInvalidScenarios() {
std::vector<ScenarioList> invalid_scenario_test_cases;
invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
- Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"))}));
-
- invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
- Scenario(std::make_optional("OneChanStereo_16_1"), std::nullopt)}));
+ Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"),
+ std::nullopt)}));
invalid_scenario_test_cases.push_back(ScenarioList(
- std::vector<Scenario>{Scenario(std::nullopt, std::nullopt)}));
+ std::vector<Scenario>{Scenario(std::make_optional("OneChanStereo_16_1"),
+ std::nullopt, std::nullopt)}));
+
+ invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
+ Scenario(std::nullopt, std::nullopt, std::nullopt)}));
invalid_scenario_test_cases.push_back(
ScenarioList(std::vector<Scenario>{}));
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml
index c7904b3..c8d1af0 100644
--- a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xml
@@ -40,6 +40,8 @@
<scenario encode="OneChanStereo_16_2" decode="OneChanMono_16_2"/>
<scenario encode="TwoChanStereo_16_2" decode="OneChanMono_16_2"/>
<scenario encode="OneChanMono_16_2" decode="OneChanMono_16_2"/>
+ <!-- broadcast -->
+ <scenario encode="invalid" decode="invalid" broadcast="BcastStereo_16_2"/>
</scenarioList>
<configurationList>
<configuration name="OneChanMono_16_1" codecConfiguration="LC3_16k_1" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
@@ -48,6 +50,7 @@
<configuration name="OneChanMono_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="MONO_ONE_CIS_PER_DEVICE"/>
<configuration name="TwoChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_TWO_CISES_PER_DEVICE"/>
<configuration name="OneChanStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="STEREO_ONE_CIS_PER_DEVICE"/>
+ <configuration name="BcastStereo_16_2" codecConfiguration="LC3_16k_2" strategyConfiguration="BROADCAST_STEREO"/>
</configurationList>
<codecConfigurationList>
<codecConfiguration name="LC3_16k_1" codec="LC3" samplingFrequency="16000" frameDurationUs="7500" octetsPerCodecFrame="30"/>
@@ -57,5 +60,6 @@
<strategyConfiguration name="STEREO_ONE_CIS_PER_DEVICE" audioLocation="STEREO" connectedDevice="2" channelCount="1"/>
<strategyConfiguration name="STEREO_TWO_CISES_PER_DEVICE" audioLocation="STEREO" connectedDevice="1" channelCount="2"/>
<strategyConfiguration name="MONO_ONE_CIS_PER_DEVICE" audioLocation="MONO" connectedDevice="1" channelCount="1"/>
+ <strategyConfiguration name="BROADCAST_STEREO" audioLocation="STEREO" connectedDevice="0" channelCount="2"/>
</strategyConfigurationList>
</leAudioOffloadSetting>
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd
index 213e597..8c2d6a1 100644
--- a/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/le_audio_codec_capabilities.xsd
@@ -32,6 +32,7 @@
<xs:complexType>
<xs:attribute name="encode" type="xs:string"/>
<xs:attribute name="decode" type="xs:string"/>
+ <xs:attribute name="broadcast" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="configuration">
diff --git a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
index 06aa21a..886350e 100644
--- a/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
+++ b/bluetooth/audio/utils/le_audio_codec_capabilities/schema/current.txt
@@ -64,8 +64,10 @@
public class Scenario {
ctor public Scenario();
+ method public String getBroadcast();
method public String getDecode();
method public String getEncode();
+ method public void setBroadcast(String);
method public void setDecode(String);
method public void setEncode(String);
}
diff --git a/bluetooth/hci/test/h4_protocol_unittest.cc b/bluetooth/hci/test/h4_protocol_unittest.cc
index d6f74fc..d3fab61 100644
--- a/bluetooth/hci/test/h4_protocol_unittest.cc
+++ b/bluetooth/hci/test/h4_protocol_unittest.cc
@@ -50,6 +50,9 @@
static char iso_data[100] =
"A plane angle is the inclination to one another of two lines in a ...";
+// 5 seconds. Just don't hang.
+static constexpr size_t kTimeoutMs = 5000;
+
MATCHER_P3(PacketMatches, header_, header_length, payload,
"Match header_length bytes of header and then the payload") {
size_t payload_length = strlen(payload);
@@ -131,9 +134,9 @@
.WillOnce(Notify(promise));
}
- void WaitForTimeout(size_t timeout_ms, std::promise<void>* promise) {
+ void WaitForTimeout(std::promise<void>* promise) {
auto future = promise->get_future();
- auto status = future.wait_for(std::chrono::milliseconds(timeout_ms));
+ auto status = future.wait_for(std::chrono::milliseconds(kTimeoutMs));
EXPECT_EQ(status, std::future_status::ready);
}
@@ -263,10 +266,10 @@
WriteInboundIsoData(iso_data);
CallDataReady();
- WaitForTimeout(100, &acl_promise);
- WaitForTimeout(100, &sco_promise);
- WaitForTimeout(100, &event_promise);
- WaitForTimeout(100, &iso_promise);
+ WaitForTimeout(&acl_promise);
+ WaitForTimeout(&sco_promise);
+ WaitForTimeout(&event_promise);
+ WaitForTimeout(&iso_promise);
}
TEST_F(H4ProtocolTest, TestMultiplePackets) {
@@ -363,28 +366,28 @@
std::promise<void> promise;
ExpectInboundAclData(payload, &promise);
WriteInboundAclData(payload);
- WaitForTimeout(100, &promise);
+ WaitForTimeout(&promise);
}
void WriteAndExpectInboundScoData(char* payload) {
std::promise<void> promise;
ExpectInboundScoData(payload, &promise);
WriteInboundScoData(payload);
- WaitForTimeout(100, &promise);
+ WaitForTimeout(&promise);
}
void WriteAndExpectInboundEvent(char* payload) {
std::promise<void> promise;
ExpectInboundEvent(payload, &promise);
WriteInboundEvent(payload);
- WaitForTimeout(100, &promise);
+ WaitForTimeout(&promise);
}
void WriteAndExpectInboundIsoData(char* payload) {
std::promise<void> promise;
ExpectInboundIsoData(payload, &promise);
WriteInboundIsoData(payload);
- WaitForTimeout(100, &promise);
+ WaitForTimeout(&promise);
}
void WriteAndExpectManyInboundAclDataPackets(char* payload) {
@@ -436,6 +439,5 @@
EXPECT_CALL(disconnect_cb_, Call()).WillOnce(Notify(&promise));
close(chip_uart_fd_);
- // Fail if it takes longer than 100 ms.
- WaitForTimeout(100, &promise);
+ WaitForTimeout(&promise);
}
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index b0ae20e..5ea6ae2 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -6318,8 +6318,6 @@
std::vector<AvailableStream>& outputStreams,
const AvailableStream* threshold,
bool maxResolution) {
- AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
- static_cast<int32_t>(PixelFormat::Y16)};
if (nullptr == staticMeta) {
return Status::ILLEGAL_ARGUMENT;
}
@@ -6345,8 +6343,12 @@
}
if(foundDepth == 0 && (0 == (depthEntry.count % 4))) {
- fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
- ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
+ AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+ static_cast<int32_t>(PixelFormat::Y16)};
+ const AvailableStream* depthThreshold =
+ (threshold != nullptr) ? threshold : &depthPreviewThreshold;
+ fillOutputStreams(&depthEntry, outputStreams, depthThreshold,
+ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
}
return Status::OK;
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 48816ad9..573b8f1 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -751,8 +751,6 @@
std::vector<AvailableStream>& outputStreams,
const AvailableStream* threshold,
bool maxResolution) {
- AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
- static_cast<int32_t>(PixelFormat::Y16)};
if (nullptr == staticMeta) {
return Status::ILLEGAL_ARGUMENT;
}
@@ -778,7 +776,11 @@
}
if (foundDepth == 0 && (0 == (depthEntry.count % 4))) {
- fillOutputStreams(&depthEntry, outputStreams, &depthPreviewThreshold,
+ AvailableStream depthPreviewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+ static_cast<int32_t>(PixelFormat::Y16)};
+ const AvailableStream* depthThreshold =
+ (threshold != nullptr) ? threshold : &depthPreviewThreshold;
+ fillOutputStreams(&depthEntry, outputStreams, depthThreshold,
ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT);
}
@@ -2332,6 +2334,7 @@
request.fmqSettingsSize = 0;
request.settings.metadata =
std::vector(rawMetadata, rawMetadata + get_camera_metadata_size(releasedMetadata));
+ overrideRotateAndCrop(&request.settings);
request.outputBuffers = std::vector<StreamBuffer>(1);
StreamBuffer& outputBuffer = request.outputBuffers[0];
if (useHalBufManager) {
diff --git a/cas/aidl/default/OWNERS b/cas/aidl/OWNERS
similarity index 100%
rename from cas/aidl/default/OWNERS
rename to cas/aidl/OWNERS
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl
index 28c9eb0..903ab92 100644
--- a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ICas.aidl
@@ -36,6 +36,7 @@
@VintfStability
interface ICas {
void closeSession(in byte[] sessionId);
+ byte[] openSessionDefault();
byte[] openSession(in android.hardware.cas.SessionIntent intent, in android.hardware.cas.ScramblingMode mode);
void processEcm(in byte[] sessionId, in byte[] ecm);
void processEmm(in byte[] emm);
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl
index a0b08c9..9d542cc 100644
--- a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/ScramblingMode.aidl
@@ -36,18 +36,18 @@
@Backing(type="int") @VintfStability
enum ScramblingMode {
RESERVED = 0,
- DVB_CSA1 = 1,
- DVB_CSA2 = 2,
- DVB_CSA3_STANDARD = 3,
- DVB_CSA3_MINIMAL = 4,
- DVB_CSA3_ENHANCE = 5,
- DVB_CISSA_V1 = 6,
- DVB_IDSA = 7,
- MULTI2 = 8,
- AES128 = 9,
- AES_ECB = 10,
- AES_SCTE52 = 11,
- TDES_ECB = 12,
- TDES_SCTE52 = 13,
- AES_CBC = 14,
+ DVB_CSA1,
+ DVB_CSA2,
+ DVB_CSA3_STANDARD,
+ DVB_CSA3_MINIMAL,
+ DVB_CSA3_ENHANCE,
+ DVB_CISSA_V1,
+ DVB_IDSA,
+ MULTI2,
+ AES128,
+ AES_ECB,
+ AES_SCTE52,
+ TDES_ECB,
+ TDES_SCTE52,
+ AES_CBC,
}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl
index ade3001..00a2fd7 100644
--- a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/SessionIntent.aidl
@@ -35,8 +35,8 @@
/* @hide */
@Backing(type="int") @VintfStability
enum SessionIntent {
- LIVE = 0,
- PLAYBACK = 1,
- RECORD = 2,
- TIMESHIFT = 3,
+ LIVE,
+ PLAYBACK,
+ RECORD,
+ TIMESHIFT,
}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl
index 343c810..3691009 100644
--- a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/Status.aidl
@@ -36,25 +36,25 @@
@VintfStability
parcelable Status {
const int OK = 0;
- const int ERROR_CAS_NO_LICENSE = -1;
- const int ERROR_CAS_LICENSE_EXPIRED = -2;
- const int ERROR_CAS_SESSION_NOT_OPENED = -3;
- const int ERROR_CAS_CANNOT_HANDLE = -4;
- const int ERROR_CAS_INVALID_STATE = -5;
- const int BAD_VALUE = -6;
- const int ERROR_CAS_NOT_PROVISIONED = -7;
- const int ERROR_CAS_RESOURCE_BUSY = -8;
- const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = -9;
- const int ERROR_CAS_TAMPER_DETECTED = -10;
- const int ERROR_CAS_DEVICE_REVOKED = -11;
- const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = -12;
- const int ERROR_CAS_DECRYPT = -13;
- const int ERROR_CAS_UNKNOWN = -14;
- const int ERROR_CAS_NEED_ACTIVATION = -15;
- const int ERROR_CAS_NEED_PAIRING = -16;
- const int ERROR_CAS_NO_CARD = -17;
- const int ERROR_CAS_CARD_MUTE = -18;
- const int ERROR_CAS_CARD_INVALID = -19;
- const int ERROR_CAS_BLACKOUT = -20;
- const int ERROR_CAS_REBOOTING = -21;
+ const int ERROR_CAS_NO_LICENSE = 1;
+ const int ERROR_CAS_LICENSE_EXPIRED = 2;
+ const int ERROR_CAS_SESSION_NOT_OPENED = 3;
+ const int ERROR_CAS_CANNOT_HANDLE = 4;
+ const int ERROR_CAS_INVALID_STATE = 5;
+ const int BAD_VALUE = 6;
+ const int ERROR_CAS_NOT_PROVISIONED = 7;
+ const int ERROR_CAS_RESOURCE_BUSY = 8;
+ const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 9;
+ const int ERROR_CAS_TAMPER_DETECTED = 10;
+ const int ERROR_CAS_DEVICE_REVOKED = 11;
+ const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = 12;
+ const int ERROR_CAS_DECRYPT = 13;
+ const int ERROR_CAS_UNKNOWN = 14;
+ const int ERROR_CAS_NEED_ACTIVATION = 15;
+ const int ERROR_CAS_NEED_PAIRING = 16;
+ const int ERROR_CAS_NO_CARD = 17;
+ const int ERROR_CAS_CARD_MUTE = 18;
+ const int ERROR_CAS_CARD_INVALID = 19;
+ const int ERROR_CAS_BLACKOUT = 20;
+ const int ERROR_CAS_REBOOTING = 21;
}
diff --git a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl
index 165c0d4..0cf37dd 100644
--- a/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl
+++ b/cas/aidl/aidl_api/android.hardware.cas/current/android/hardware/cas/StatusEvent.aidl
@@ -35,6 +35,6 @@
/* @hide */
@Backing(type="byte") @VintfStability
enum StatusEvent {
- PLUGIN_PHYSICAL_MODULE_CHANGED = 0,
- PLUGIN_SESSION_NUMBER_CHANGED = 1,
+ PLUGIN_PHYSICAL_MODULE_CHANGED,
+ PLUGIN_SESSION_NUMBER_CHANGED,
}
diff --git a/cas/aidl/android/hardware/cas/ICas.aidl b/cas/aidl/android/hardware/cas/ICas.aidl
index e6494ae..272cb10 100644
--- a/cas/aidl/android/hardware/cas/ICas.aidl
+++ b/cas/aidl/android/hardware/cas/ICas.aidl
@@ -35,6 +35,14 @@
void closeSession(in byte[] sessionId);
/**
+ * Open a session to descramble one or more streams without specifying intention
+ * and scrambling mode.
+ *
+ * @return sessionId The id of the newly opened session.
+ */
+ byte[] openSessionDefault();
+
+ /**
* Open a session to descramble one or more streams by specifying intention
* and scrambling mode.
*
diff --git a/cas/aidl/android/hardware/cas/Status.aidl b/cas/aidl/android/hardware/cas/Status.aidl
index e7ae8ff..ba0bd65 100644
--- a/cas/aidl/android/hardware/cas/Status.aidl
+++ b/cas/aidl/android/hardware/cas/Status.aidl
@@ -31,50 +31,50 @@
* The CAS plugin must return ERROR_CAS_NO_LICENSE, when descrambling is
* attempted and no license keys have been provided.
*/
- const int ERROR_CAS_NO_LICENSE = -1;
+ const int ERROR_CAS_NO_LICENSE = 1;
/**
* ERROR_CAS_LICENSE_EXPIRED must be returned when an attempt is made
* to use a license and the keys in that license have expired.
*/
- const int ERROR_CAS_LICENSE_EXPIRED = -2;
+ const int ERROR_CAS_LICENSE_EXPIRED = 2;
/**
* The CAS plugin must return ERROR_CAS_SESSION_NOT_OPENED when an
* attempt is made to use a session that has not been opened.
*/
- const int ERROR_CAS_SESSION_NOT_OPENED = -3;
+ const int ERROR_CAS_SESSION_NOT_OPENED = 3;
/**
* The CAS plugin must return ERROR_CAS_CANNOT_HANDLE when an unsupported
* data format or operation is attempted.
*/
- const int ERROR_CAS_CANNOT_HANDLE = -4;
+ const int ERROR_CAS_CANNOT_HANDLE = 4;
/**
* ERROR_CAS_INVALID_STATE must be returned when the device is in a state
* where it is not able to perform descrambling.
*/
- const int ERROR_CAS_INVALID_STATE = -5;
+ const int ERROR_CAS_INVALID_STATE = 5;
/**
* The CAS plugin must return BAD_VALUE whenever an illegal parameter is
* passed to one of the interface functions.
*/
- const int BAD_VALUE = -6;
+ const int BAD_VALUE = 6;
/**
* The CAS plugin must return ERROR_CAS_NOT_PROVISIONED when the device
* has not yet been provisioned.
*/
- const int ERROR_CAS_NOT_PROVISIONED = -7;
+ const int ERROR_CAS_NOT_PROVISIONED = 7;
/**
* ERROR_CAS_RESOURCE_BUSY must be returned when resources, such as CAS
* sessions or secure buffers are not available to perform a requested
* operation because they are already in use.
*/
- const int ERROR_CAS_RESOURCE_BUSY = -8;
+ const int ERROR_CAS_RESOURCE_BUSY = 8;
/**
* The CAS Plugin must return ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION
@@ -82,72 +82,72 @@
* sufficient to meet the requirements in the license policy. HDCP is an
* example of a form of output protection.
*/
- const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = -9;
+ const int ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 9;
/**
* The CAS Plugin must return ERROR_CAS_TAMPER_DETECTED if an attempt to
* tamper with the CAS system is detected.
*/
- const int ERROR_CAS_TAMPER_DETECTED = -10;
+ const int ERROR_CAS_TAMPER_DETECTED = 10;
/**
* The CAS Plugin must return ERROR_CAS_DEVICE_REVOKED if the response
* indicates that the device has been revoked. Device revocation means
* that the device is no longer permitted to play content.
*/
- const int ERROR_CAS_DEVICE_REVOKED = -11;
+ const int ERROR_CAS_DEVICE_REVOKED = 11;
/**
* The CAS plugin must return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED when
* descrambling is failing because the session is not initialized properly.
*/
- const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = -12;
+ const int ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED = 12;
/**
* The CAS Plugin must return ERROR_CAS_DECRYPT if the DescramblerPlugin's
* descramble operation fails.
*/
- const int ERROR_CAS_DECRYPT = -13;
+ const int ERROR_CAS_DECRYPT = 13;
/**
* ERROR_CAS_UNKNOWN must be returned when a fatal failure occurs and no
* other defined error is appropriate.
*/
- const int ERROR_CAS_UNKNOWN = -14;
+ const int ERROR_CAS_UNKNOWN = 14;
/**
* ERROR_CAS_NEED_ACTIVATION is used to trigger device activation process.
*/
- const int ERROR_CAS_NEED_ACTIVATION = -15;
+ const int ERROR_CAS_NEED_ACTIVATION = 15;
/**
* ERROR_CAS_NEED_PAIRING is used to trigger pairing process.
*/
- const int ERROR_CAS_NEED_PAIRING = -16;
+ const int ERROR_CAS_NEED_PAIRING = 16;
/**
* ERROR_CAS_NO_CARD is used to report no smart card for descrambling.
*/
- const int ERROR_CAS_NO_CARD = -17;
+ const int ERROR_CAS_NO_CARD = 17;
/**
* ERROR_CAS_CARD_MUTE is used to report smart card is muted for
* descrambling.
*/
- const int ERROR_CAS_CARD_MUTE = -18;
+ const int ERROR_CAS_CARD_MUTE = 18;
/**
* ERROR_CAS_CARD_INVALID is used to report smart card isn't valid.
*/
- const int ERROR_CAS_CARD_INVALID = -19;
+ const int ERROR_CAS_CARD_INVALID = 19;
/**
* ERROR_CAS_BLACKOUT is used to report geographical blackout.
*/
- const int ERROR_CAS_BLACKOUT = -20;
+ const int ERROR_CAS_BLACKOUT = 20;
/**
* ERROR_CAS_REBOOTING is used to report CAS is during rebooting.
*/
- const int ERROR_CAS_REBOOTING = -21;
+ const int ERROR_CAS_REBOOTING = 21;
}
diff --git a/cas/aidl/default/CasImpl.cpp b/cas/aidl/default/CasImpl.cpp
index 2d31b35..f08fcc0 100755
--- a/cas/aidl/default/CasImpl.cpp
+++ b/cas/aidl/default/CasImpl.cpp
@@ -128,6 +128,19 @@
return toStatus(holder->setPrivateData(pvtData));
}
+ScopedAStatus CasImpl::openSessionDefault(vector<uint8_t>* sessionId) {
+ ALOGV("%s", __FUNCTION__);
+
+ shared_ptr<CasPlugin> holder = atomic_load(&mPluginHolder);
+ status_t err = INVALID_OPERATION;
+ if (holder.get() != nullptr) {
+ err = holder->openSession(sessionId);
+ holder.reset();
+ }
+
+ return toStatus(err);
+}
+
ScopedAStatus CasImpl::openSession(SessionIntent intent, ScramblingMode mode,
vector<uint8_t>* sessionId) {
ALOGV("%s", __FUNCTION__);
diff --git a/cas/aidl/default/CasImpl.h b/cas/aidl/default/CasImpl.h
index 84a8115..2488a7f 100755
--- a/cas/aidl/default/CasImpl.h
+++ b/cas/aidl/default/CasImpl.h
@@ -53,6 +53,8 @@
virtual ScopedAStatus setPrivateData(const vector<uint8_t>& pvtData) override;
+ virtual ScopedAStatus openSessionDefault(vector<uint8_t>* sessionId) override;
+
virtual ScopedAStatus openSession(SessionIntent intent, ScramblingMode mode,
vector<uint8_t>* sessionId) override;
diff --git a/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp b/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp
index 266b55d..4c904a8 100644
--- a/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp
+++ b/cas/aidl/vts/functional/VtsHalCasAidlTargetTest.cpp
@@ -286,6 +286,7 @@
} OobInputTestParams;
AssertionResult createCasPlugin(int32_t caSystemId);
+ AssertionResult openCasSessionDefault(vector<uint8_t>* sessionId);
AssertionResult openCasSession(vector<uint8_t>* sessionId, SessionIntent intent,
ScramblingMode mode);
AssertionResult descrambleTestInputBuffer(const shared_ptr<IDescrambler>& descrambler,
@@ -331,6 +332,10 @@
return AssertionResult(mDescrambler != nullptr);
}
+AssertionResult MediaCasAidlTest::openCasSessionDefault(vector<uint8_t>* sessionId) {
+ return AssertionResult(mMediaCas->openSessionDefault(sessionId).isOk());
+}
+
AssertionResult MediaCasAidlTest::openCasSession(vector<uint8_t>* sessionId, SessionIntent intent,
ScramblingMode mode) {
return AssertionResult(mMediaCas->openSession(intent, mode, sessionId).isOk());
@@ -485,6 +490,32 @@
ADD_FAILURE() << "ClearKey plugin not installed";
}
+TEST_P(MediaCasAidlTest, TestClearKeyDefaultSessionClosedAfterRelease) {
+ description("Test that all sessions are closed after a MediaCas object is released");
+
+ ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
+
+ EXPECT_TRUE(mMediaCas->provision(PROVISION_STR).isOk());
+
+ vector<uint8_t> sessionId;
+ ASSERT_TRUE(openCasSessionDefault(&sessionId));
+
+ vector<uint8_t> streamSessionId;
+ ASSERT_TRUE(openCasSessionDefault(&streamSessionId));
+
+ EXPECT_TRUE(mMediaCas->release().isOk());
+
+ if (mDescrambler != nullptr) {
+ auto status = mDescrambler->setMediaCasSession(sessionId);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, status.getServiceSpecificError());
+
+ status = mDescrambler->setMediaCasSession(streamSessionId);
+ EXPECT_FALSE(status.isOk());
+ EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, status.getServiceSpecificError());
+ }
+}
+
TEST_P(MediaCasAidlTest, TestClearKeySessionClosedAfterRelease) {
description("Test that all sessions are closed after a MediaCas object is released");
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index e1ad1f3..622835e 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -78,7 +78,7 @@
"compatibility_matrix.8.xml",
],
kernel_configs: [
- "kernel_config_current_5.10",
"kernel_config_current_5.15",
+ "kernel_config_current_6.1",
],
}
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 8ef0b3a..c898aab 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -171,7 +171,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <hal format="hidl" optional="true">
<name>android.hardware.gatekeeper</name>
<version>1.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 12b85c7..c5a1dc2 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -192,7 +192,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <hal format="hidl" optional="true">
<name>android.hardware.gatekeeper</name>
<version>1.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml
index e19d2dd..1c76ee6 100644
--- a/compatibility_matrices/compatibility_matrix.6.xml
+++ b/compatibility_matrices/compatibility_matrix.6.xml
@@ -215,7 +215,7 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <hal format="hidl" optional="true">
<name>android.hardware.gatekeeper</name>
<version>1.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index c17cb15..c7b05e8 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -167,7 +167,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.bluetooth.audio</name>
- <version>2</version>
+ <version>3</version>
<interface>
<name>IBluetoothAudioProviderFactory</name>
<instance>default</instance>
@@ -756,14 +756,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
- <name>android.hardware.usb.gadget</name>
- <version>1.0-2</version>
- <interface>
- <name>IUsbGadget</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" optional="true">
<name>android.hardware.usb.gadget</name>
<interface>
diff --git a/graphics/mapper/3.0/utils/vts/MapperVts.cpp b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
index c470a4a..48e5736 100644
--- a/graphics/mapper/3.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
@@ -99,11 +99,7 @@
descriptor, count,
[&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
if (tmpError != Error::NONE) {
- if (base::GetIntProperty("ro.vendor.build.version.sdk", 0, 0, INT_MAX) < 33) {
- GTEST_SKIP() << "Old vendor grallocs may not support P010";
- } else {
- GTEST_FAIL() << "failed to allocate buffers";
- }
+ GTEST_FAIL() << "failed to allocate buffers";
}
ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
index 3b1bfab..997af97 100644
--- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
+++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
@@ -21,6 +21,7 @@
#include <vector>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
@@ -330,6 +331,9 @@
* Test IMapper::lockYCbCr. This locks a YCbCr_P010 buffer and verifies that it's initialized.
*/
TEST_P(GraphicsMapperHidlTest, LockYCbCrP010) {
+ if (base::GetIntProperty("ro.vendor.api_level", __ANDROID_API_FUTURE__) < __ANDROID_API_T__) {
+ GTEST_SKIP() << "Old vendor grallocs may not support P010";
+ }
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YCBCR_P010;
diff --git a/graphics/mapper/4.0/utils/vts/MapperVts.cpp b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
index c6c9834..d70c6ef 100644
--- a/graphics/mapper/4.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
@@ -111,11 +111,7 @@
}
if (error != Error::NONE) {
- if (base::GetIntProperty("ro.vendor.build.version.sdk", 0, 0, INT_MAX) < 33) {
- GTEST_SKIP() << "Old vendor grallocs may not support P010";
- } else {
- GTEST_FAIL() << "failed to allocate buffers";
- }
+ GTEST_FAIL() << "failed to allocate buffers";
}
ASSERT_EQ(count, buffers.size()) << "invalid buffer array";
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 5a450e3..2ec98d4 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -29,12 +29,14 @@
#include <aidlcommonsupport/NativeHandle.h>
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android-base/unique_fd.h>
#include <android/sync.h>
#include <gralloctypes/Gralloc4.h>
#include <gtest/gtest.h>
#include <hidl/GtestPrinter.h>
#include <hidl/ServiceManagement.h>
+
#include <mapper-vts/4.0/MapperVts.h>
#include <system/graphics.h>
@@ -1000,6 +1002,9 @@
}
TEST_P(GraphicsMapperHidlTest, Lock_YCBCR_P010) {
+ if (base::GetIntProperty("ro.vendor.api_level", __ANDROID_API_FUTURE__) < __ANDROID_API_T__) {
+ GTEST_SKIP() << "Old vendor grallocs may not support P010";
+ }
auto info = mDummyDescriptorInfo;
info.format = PixelFormat::YCBCR_P010;
diff --git a/health/aidl/OWNERS b/health/aidl/OWNERS
index fcad499..0f1bee2 100644
--- a/health/aidl/OWNERS
+++ b/health/aidl/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 30545
elsk@google.com
smoreland@google.com
-stayfan@google.com
+wjack@google.com
+apelosi@google.com
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
index e543886..4d70588 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryCapacityLevel.aidl
@@ -34,11 +34,11 @@
package android.hardware.health;
@Backing(type="int") @VintfStability
enum BatteryCapacityLevel {
- UNSUPPORTED = -1,
- UNKNOWN = 0,
- CRITICAL = 1,
- LOW = 2,
- NORMAL = 3,
- HIGH = 4,
- FULL = 5,
+ UNSUPPORTED = (-1) /* -1 */,
+ UNKNOWN,
+ CRITICAL,
+ LOW,
+ NORMAL,
+ HIGH,
+ FULL,
}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
index d523fad..2dd01b1 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -36,4 +36,5 @@
parcelable BatteryHealthData {
long batteryManufacturingDateSeconds;
long batteryFirstUsageSeconds;
+ long batteryStateOfHealth;
}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
index 664cc70..bfa1475 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
@@ -57,9 +57,8 @@
android.hardware.health.BatteryCapacityLevel batteryCapacityLevel;
long batteryChargeTimeToFullNowSeconds;
int batteryFullChargeDesignCapacityUah;
- int batteryStateOfHealth;
android.hardware.health.BatteryChargingState chargingState;
android.hardware.health.BatteryChargingPolicy chargingPolicy;
@nullable android.hardware.health.BatteryHealthData batteryHealthData;
- const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = -1;
+ const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = (-1) /* -1 */;
}
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
index fb17f63..594bcce 100644
--- a/health/aidl/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -29,4 +29,11 @@
* The date of first usage is reported in epoch.
*/
long batteryFirstUsageSeconds;
+ /**
+ * Measured battery state of health (remaining estimate full charge capacity
+ * relative to the rated capacity in %).
+ * Value must be 0 if batteryStatus is UNKNOWN.
+ * Otherwise, value must be in the range 0 to 100.
+ */
+ long batteryStateOfHealth;
}
diff --git a/health/aidl/android/hardware/health/HealthInfo.aidl b/health/aidl/android/hardware/health/HealthInfo.aidl
index 238f524..af84089 100644
--- a/health/aidl/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/android/hardware/health/HealthInfo.aidl
@@ -137,13 +137,6 @@
*/
int batteryFullChargeDesignCapacityUah;
/**
- * Measured battery state of health (remaining estimate full charge capacity
- * relative to the rated capacity in %).
- * Value must be 0 if batteryStatus is UNKNOWN.
- * Otherwise, value must be in the range 0 to 100.
- */
- int batteryStateOfHealth;
- /**
* Battery charging state
*/
BatteryChargingState chargingState;
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 15a3dbc..f401643 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -148,6 +148,11 @@
!res.isOk()) {
LOG(WARNING) << "Cannot get First_usage_date: " << res.getDescription();
}
+ if (auto res = GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_STATE_OF_HEALTH,
+ 0, &out->batteryStateOfHealth);
+ !res.isOk()) {
+ LOG(WARNING) << "Cannot get Battery_state_of_health: " << res.getDescription();
+ }
return ndk::ScopedAStatus::ok();
}
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index dd0bd81..69d4789 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -229,8 +229,14 @@
* Tests the values returned by getChargingPolicy() from interface IHealth.
*/
TEST_P(HealthAidl, getChargingPolicy) {
+ int32_t version = 0;
+ auto status = health->getInterfaceVersion(&version);
+ ASSERT_TRUE(status.isOk()) << status;
+ if (version < 2) {
+ GTEST_SKIP() << "Support in health hal v2 for EU Ecodesign";
+ }
BatteryChargingPolicy value;
- auto status = health->getChargingPolicy(&value);
+ status = health->getChargingPolicy(&value);
ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
if (!status.isOk()) return;
ASSERT_THAT(value, IsValidEnum<BatteryChargingPolicy>());
@@ -241,10 +247,17 @@
* value by getChargingPolicy() from interface IHealth.
*/
TEST_P(HealthAidl, setChargingPolicy) {
+ int32_t version = 0;
+ auto status = health->getInterfaceVersion(&version);
+ ASSERT_TRUE(status.isOk()) << status;
+ if (version < 2) {
+ GTEST_SKIP() << "Support in health hal v2 for EU Ecodesign";
+ }
+
BatteryChargingPolicy value;
/* set ChargingPolicy*/
- auto status = health->setChargingPolicy(static_cast<BatteryChargingPolicy>(2)); // LONG_LIFE
+ status = health->setChargingPolicy(static_cast<BatteryChargingPolicy>(2)); // LONG_LIFE
ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
if (!status.isOk()) return;
@@ -265,6 +278,10 @@
*result_listener << " for batteryFirstUsageSeconds.";
return false;
}
+ if (!ExplainMatchResult(Ge(-1), arg.batteryStateOfHealth, result_listener)) {
+ *result_listener << " for batteryStateOfHealth.";
+ return false;
+ }
return true;
}
@@ -273,8 +290,15 @@
* Tests the values returned by getBatteryHealthData() from interface IHealth.
*/
TEST_P(HealthAidl, getBatteryHealthData) {
+ int32_t version = 0;
+ auto status = health->getInterfaceVersion(&version);
+ ASSERT_TRUE(status.isOk()) << status;
+ if (version < 2) {
+ GTEST_SKIP() << "Support in health hal v2 for EU Ecodesign";
+ }
+
BatteryHealthData value;
- auto status = health->getBatteryHealthData(&value);
+ status = health->getBatteryHealthData(&value);
ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
if (!status.isOk()) return;
ASSERT_THAT(value, IsValidHealthData());
diff --git a/neuralnetworks/1.2/utils/src/BurstUtils.cpp b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
index b589c46..c4c096d 100644
--- a/neuralnetworks/1.2/utils/src/BurstUtils.cpp
+++ b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
@@ -190,12 +190,13 @@
size_t index = 0;
// validate packet information
- if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::packetInformation) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage packet information
- const FmqRequestDatum::PacketInformation& packetInfo = data[index].packetInformation();
+ const FmqRequestDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
index++;
const uint32_t packetSize = packetInfo.packetSize;
const uint32_t numberOfInputOperands = packetInfo.numberOfInputOperands;
@@ -212,13 +213,14 @@
inputs.reserve(numberOfInputOperands);
for (size_t operand = 0; operand < numberOfInputOperands; ++operand) {
// validate input operand information
- if (data[index].getDiscriminator() != discriminator::inputOperandInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::inputOperandInformation) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage operand information
const FmqRequestDatum::OperandInformation& operandInfo =
- data[index].inputOperandInformation();
+ data.at(index).inputOperandInformation();
index++;
const bool hasNoValue = operandInfo.hasNoValue;
const V1_0::DataLocation location = operandInfo.location;
@@ -229,12 +231,13 @@
dimensions.reserve(numberOfDimensions);
for (size_t i = 0; i < numberOfDimensions; ++i) {
// validate dimension
- if (data[index].getDiscriminator() != discriminator::inputOperandDimensionValue) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::inputOperandDimensionValue) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage dimension
- const uint32_t dimension = data[index].inputOperandDimensionValue();
+ const uint32_t dimension = data.at(index).inputOperandDimensionValue();
index++;
// store result
@@ -251,13 +254,14 @@
outputs.reserve(numberOfOutputOperands);
for (size_t operand = 0; operand < numberOfOutputOperands; ++operand) {
// validate output operand information
- if (data[index].getDiscriminator() != discriminator::outputOperandInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::outputOperandInformation) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage operand information
const FmqRequestDatum::OperandInformation& operandInfo =
- data[index].outputOperandInformation();
+ data.at(index).outputOperandInformation();
index++;
const bool hasNoValue = operandInfo.hasNoValue;
const V1_0::DataLocation location = operandInfo.location;
@@ -268,12 +272,13 @@
dimensions.reserve(numberOfDimensions);
for (size_t i = 0; i < numberOfDimensions; ++i) {
// validate dimension
- if (data[index].getDiscriminator() != discriminator::outputOperandDimensionValue) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::outputOperandDimensionValue) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage dimension
- const uint32_t dimension = data[index].outputOperandDimensionValue();
+ const uint32_t dimension = data.at(index).outputOperandDimensionValue();
index++;
// store result
@@ -290,12 +295,13 @@
slots.reserve(numberOfPools);
for (size_t pool = 0; pool < numberOfPools; ++pool) {
// validate input operand information
- if (data[index].getDiscriminator() != discriminator::poolIdentifier) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::poolIdentifier) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage operand information
- const int32_t poolId = data[index].poolIdentifier();
+ const int32_t poolId = data.at(index).poolIdentifier();
index++;
// store result
@@ -303,17 +309,17 @@
}
// validate measureTiming
- if (data[index].getDiscriminator() != discriminator::measureTiming) {
+ if (index >= data.size() || data.at(index).getDiscriminator() != discriminator::measureTiming) {
return NN_ERROR() << "FMQ Request packet ill-formed";
}
// unpackage measureTiming
- const V1_2::MeasureTiming measure = data[index].measureTiming();
+ const V1_2::MeasureTiming measure = data.at(index).measureTiming();
index++;
// validate packet information
if (index != packetSize) {
- return NN_ERROR() << "FMQ Result packet ill-formed";
+ return NN_ERROR() << "FMQ Request packet ill-formed";
}
// return request
@@ -328,12 +334,13 @@
size_t index = 0;
// validate packet information
- if (data.size() == 0 || data[index].getDiscriminator() != discriminator::packetInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::packetInformation) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage packet information
- const FmqResultDatum::PacketInformation& packetInfo = data[index].packetInformation();
+ const FmqResultDatum::PacketInformation& packetInfo = data.at(index).packetInformation();
index++;
const uint32_t packetSize = packetInfo.packetSize;
const V1_0::ErrorStatus errorStatus = packetInfo.errorStatus;
@@ -349,12 +356,13 @@
outputShapes.reserve(numberOfOperands);
for (size_t operand = 0; operand < numberOfOperands; ++operand) {
// validate operand information
- if (data[index].getDiscriminator() != discriminator::operandInformation) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::operandInformation) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage operand information
- const FmqResultDatum::OperandInformation& operandInfo = data[index].operandInformation();
+ const FmqResultDatum::OperandInformation& operandInfo = data.at(index).operandInformation();
index++;
const bool isSufficient = operandInfo.isSufficient;
const uint32_t numberOfDimensions = operandInfo.numberOfDimensions;
@@ -364,12 +372,13 @@
dimensions.reserve(numberOfDimensions);
for (size_t i = 0; i < numberOfDimensions; ++i) {
// validate dimension
- if (data[index].getDiscriminator() != discriminator::operandDimensionValue) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::operandDimensionValue) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage dimension
- const uint32_t dimension = data[index].operandDimensionValue();
+ const uint32_t dimension = data.at(index).operandDimensionValue();
index++;
// store result
@@ -381,12 +390,13 @@
}
// validate execution timing
- if (data[index].getDiscriminator() != discriminator::executionTiming) {
+ if (index >= data.size() ||
+ data.at(index).getDiscriminator() != discriminator::executionTiming) {
return NN_ERROR() << "FMQ Result packet ill-formed";
}
// unpackage execution timing
- const V1_2::Timing timing = data[index].executionTiming();
+ const V1_2::Timing timing = data.at(index).executionTiming();
index++;
// validate packet information
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index b0b984c..8f357a0 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -232,7 +232,8 @@
EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
ALOGI("setPreferredNetworkTypeBitmap, rspInfo.error = %s\n",
toString(radioRsp_v1_4->rspInfo.error).c_str());
- EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::MODE_NOT_SUPPORTED}));
if (radioRsp_v1_4->rspInfo.error == RadioError::NONE) {
// give some time for modem to set the value.
sleep(3);
diff --git a/scripts/anapic_hidl2aidl_review.sh b/scripts/anapic_hidl2aidl_review.sh
index 330ae32..ce72160 100755
--- a/scripts/anapic_hidl2aidl_review.sh
+++ b/scripts/anapic_hidl2aidl_review.sh
@@ -1,4 +1,11 @@
#!/bin/bash
+#
+# Create two CLs for the given HIDL interface to see the diff between the
+# hidl2aidl output and the source at the tip-of-tree.
+# The first CL contains the hidl2aidl output after removing all existing AIDL
+# files.
+# The second CL contains all of the changes on top of the raw hidl2aidl output
+# that can be used for review.
if [[ $# -ne 1 ]]; then
echo "Usage: $0 INTERFACE_NAME"
@@ -23,5 +30,6 @@
git commit -am "convert $1" --no-edit
git revert HEAD --no-edit
git commit --amend --no-edit
-repo upload . --no-verify
+git diff HEAD~1 --stat
+repo upload . --no-verify --wip --hashtag=anapic_release_review
popd
diff --git a/scripts/anapic_release_diff.sh b/scripts/anapic_release_diff.sh
new file mode 100755
index 0000000..c22d9e5
--- /dev/null
+++ b/scripts/anapic_release_diff.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Create a CL that contains the changes between this branch and a newer branch
+# for a given AIDL interface.
+# Be sure that BRANCH_BASE is the current upstream branch in order to get a CL.
+
+if [[ $# -ne 3 ]]; then
+ echo "Usage: $0 BRANCH_BASE BRANCH_NEW PACKAGE_NAME"
+ echo "- BRANCH_BASE current branch, typically a previous release's dev branch"
+ echo "- BRANCH_NEW end branch, typically goog/master as the latest branch"
+ echo "- PACKAGE_NAME this is the AIDL package name"
+ echo "example of creating the diffs for android.hardware.boot"
+ echo "$ git checkout tm-dev ; repo start review"
+ echo "$ ./anapic_release_diff.sh goog/tm-dev goog/master android.hardware.boot"
+ exit 1
+fi
+
+# for pathmod
+source ${ANDROID_BUILD_TOP}/build/make/envsetup.sh
+
+set -ex
+
+INTERFACE_NAME_NO_VER=${3%@*}
+pushd $(pathmod $INTERFACE_NAME_NO_VER)
+git diff "$1".."$2" android | git apply
+git add -A
+git commit -am "Android $1 to $2: $3" --no-edit
+git diff HEAD~1 --stat
+repo upload . --no-verify --wip --hashtag=anapic_release_review
+popd
diff --git a/secure_element/1.0/vts/OWNERS b/secure_element/1.0/vts/OWNERS
deleted file mode 100644
index c7963e7..0000000
--- a/secure_element/1.0/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-alisher@google.com
-jackcwyu@google.com
-georgekgchang@google.com
-zachoverflow@google.com
diff --git a/secure_element/1.0/vts/functional/OWNERS b/secure_element/1.0/vts/functional/OWNERS
deleted file mode 100644
index a7ee7e9..0000000
--- a/secure_element/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 456592
-jackcwyu@google.com
diff --git a/secure_element/1.1/vts/OWNERS b/secure_element/1.1/vts/OWNERS
deleted file mode 100644
index c7963e7..0000000
--- a/secure_element/1.1/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-alisher@google.com
-jackcwyu@google.com
-georgekgchang@google.com
-zachoverflow@google.com
diff --git a/secure_element/1.1/vts/functional/OWNERS b/secure_element/1.1/vts/functional/OWNERS
deleted file mode 100644
index a7ee7e9..0000000
--- a/secure_element/1.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 456592
-jackcwyu@google.com
diff --git a/secure_element/1.2/vts/OWNERS b/secure_element/1.2/vts/OWNERS
deleted file mode 100644
index c7963e7..0000000
--- a/secure_element/1.2/vts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-alisher@google.com
-jackcwyu@google.com
-georgekgchang@google.com
-zachoverflow@google.com
diff --git a/secure_element/1.2/vts/functional/OWNERS b/secure_element/1.2/vts/functional/OWNERS
deleted file mode 100644
index a7ee7e9..0000000
--- a/secure_element/1.2/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 456592
-jackcwyu@google.com
diff --git a/secure_element/OWNERS b/secure_element/OWNERS
new file mode 100644
index 0000000..492696b
--- /dev/null
+++ b/secure_element/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 456592
+alisher@google.com
+jackcwyu@google.com
+georgekgchang@google.com
+henrichataing@google.com
diff --git a/secure_element/aidl/default/main.cpp b/secure_element/aidl/default/main.cpp
index 6149eae..0822402 100644
--- a/secure_element/aidl/default/main.cpp
+++ b/secure_element/aidl/default/main.cpp
@@ -586,7 +586,7 @@
// The selected basic or logical channel is not opened.
if (channel_number >= channels_.size() || !channels_[channel_number].opened) {
- return ScopedAStatus::ok();
+ return ScopedAStatus::fromServiceSpecificError(FAILED);
}
// TODO(b/123254068) - this is not an implementation of the OMAPI protocol
diff --git a/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
index c265579..2e96f7d 100644
--- a/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
+++ b/secure_element/aidl/vts/VtsHalSecureElementTargetTest.cpp
@@ -106,9 +106,19 @@
EXPECT_OK(secure_element_->init(secure_element_callback_));
secure_element_callback_->expectCallbackHistory({true});
+
+ // Check if the basic channel is supported by the bound SE.
+ std::vector<uint8_t> basic_channel_response;
+ auto status =
+ secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response);
+ if (status.isOk()) {
+ basic_channel_supported_ = true;
+ secure_element_->closeChannel(0);
+ }
}
void TearDown() override {
+ EXPECT_OK(secure_element_->reset());
secure_element_ = nullptr;
secure_element_callback_ = nullptr;
}
@@ -142,6 +152,7 @@
std::shared_ptr<ISecureElement> secure_element_;
std::shared_ptr<MySecureElementCallback> secure_element_callback_;
+ bool basic_channel_supported_{false};
};
TEST_P(SecureElementAidl, init) {
@@ -158,14 +169,18 @@
LogicalChannelResponse logical_channel_response;
// reset called after init shall succeed.
- EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+ if (basic_channel_supported_) {
+ EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+ }
EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
EXPECT_OK(secure_element_->reset());
secure_element_callback_->expectCallbackHistory({true, false, true});
// All opened channels must be closed.
- EXPECT_NE(transmit(0), 0x9000);
+ if (basic_channel_supported_) {
+ EXPECT_NE(transmit(0), 0x9000);
+ }
EXPECT_NE(transmit(logical_channel_response.channelNumber), 0x9000);
}
@@ -189,6 +204,10 @@
TEST_P(SecureElementAidl, openBasicChannel) {
std::vector<uint8_t> response;
+ if (!basic_channel_supported_) {
+ return;
+ }
+
// openBasicChannel called with an invalid AID shall fail.
EXPECT_ERR(secure_element_->openBasicChannel(kNonSelectableAid, 0x00, &response));
@@ -198,7 +217,7 @@
EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &response));
EXPECT_GE(response.size(), 2u);
- // tramsmit called on the basic channel should succeed.
+ // transmit called on the basic channel should succeed.
EXPECT_EQ(transmit(0), 0x9000);
// openBasicChannel called a second time shall fail.
@@ -224,7 +243,7 @@
EXPECT_GE(response.channelNumber, 1u);
EXPECT_LE(response.channelNumber, 19u);
- // tramsmit called on the logical channel should succeed.
+ // transmit called on the logical channel should succeed.
EXPECT_EQ(transmit(response.channelNumber), 0x9000);
}
@@ -232,23 +251,25 @@
std::vector<uint8_t> basic_channel_response;
LogicalChannelResponse logical_channel_response;
- // closeChannel called on non-existing basic or logical channel is a no-op
- // and shall succeed.
- EXPECT_OK(secure_element_->closeChannel(0));
- EXPECT_OK(secure_element_->closeChannel(1));
+ // closeChannel called on non-existing basic or logical channel
+ // shall fail.
+ EXPECT_ERR(secure_element_->closeChannel(0));
+ EXPECT_ERR(secure_element_->closeChannel(1));
// closeChannel called on basic channel closes the basic channel.
- EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
- EXPECT_OK(secure_element_->closeChannel(0));
+ if (basic_channel_supported_) {
+ EXPECT_OK(secure_element_->openBasicChannel(kSelectableAid, 0x00, &basic_channel_response));
+ EXPECT_OK(secure_element_->closeChannel(0));
- // tramsmit called on the basic channel should fail.
- EXPECT_NE(transmit(0), 0x9000);
+ // transmit called on the basic channel should fail.
+ EXPECT_NE(transmit(0), 0x9000);
+ }
// closeChannel called on logical channel closes the logical channel.
EXPECT_OK(secure_element_->openLogicalChannel(kSelectableAid, 0x00, &logical_channel_response));
EXPECT_OK(secure_element_->closeChannel(logical_channel_response.channelNumber));
- // tramsmit called on the basic channel should fail.
+ // transmit called on the logical channel should fail.
EXPECT_NE(transmit(logical_channel_response.channelNumber), 0x9000);
}
diff --git a/security/dice/aidl/default/Android.bp b/security/dice/aidl/default/Android.bp
index b67a44a..5ff4847 100644
--- a/security/dice/aidl/default/Android.bp
+++ b/security/dice/aidl/default/Android.bp
@@ -14,7 +14,6 @@
vendor: true,
rustlibs: [
"android.hardware.security.dice-V1-rust",
- "libdiced_open_dice_cbor",
"libdiced_sample_inputs",
"libdiced_vendor",
"libandroid_logger",
diff --git a/security/dice/aidl/default/service.rs b/security/dice/aidl/default/service.rs
index eebf333..4363e91 100644
--- a/security/dice/aidl/default/service.rs
+++ b/security/dice/aidl/default/service.rs
@@ -14,14 +14,13 @@
//! Main entry point for the android.hardware.security.dice service.
-use anyhow::Result;
+use anyhow::{anyhow, Result};
use diced::{
dice,
hal_node::{DiceArtifacts, DiceDevice, ResidentHal, UpdatableDiceArtifacts},
};
use diced_sample_inputs::make_sample_bcc_and_cdis;
use serde::{Deserialize, Serialize};
-use std::convert::TryInto;
use std::panic;
use std::sync::Arc;
@@ -41,8 +40,8 @@
fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
&self.cdi_seal
}
- fn bcc(&self) -> Vec<u8> {
- self.bcc.clone()
+ fn bcc(&self) -> Option<&[u8]> {
+ Some(&self.bcc)
}
}
@@ -57,7 +56,10 @@
Ok(Self {
cdi_attest: *new_artifacts.cdi_attest(),
cdi_seal: *new_artifacts.cdi_seal(),
- bcc: new_artifacts.bcc(),
+ bcc: new_artifacts
+ .bcc()
+ .ok_or_else(|| anyhow!("bcc is none"))?
+ .to_vec(),
})
}
}
@@ -76,22 +78,21 @@
// Saying hi.
log::info!("android.hardware.security.dice is starting.");
- let (cdi_attest, cdi_seal, bcc) =
+ let dice_artifacts =
make_sample_bcc_and_cdis().expect("Failed to construct sample dice chain.");
-
+ let mut cdi_attest = [0u8; dice::CDI_SIZE];
+ cdi_attest.copy_from_slice(dice_artifacts.cdi_attest());
+ let mut cdi_seal = [0u8; dice::CDI_SIZE];
+ cdi_seal.copy_from_slice(dice_artifacts.cdi_seal());
let hal_impl = Arc::new(
unsafe {
// Safety: ResidentHal cannot be used in multi threaded processes.
// This service does not start a thread pool. The main thread is the only thread
// joining the thread pool, thereby keeping the process single threaded.
ResidentHal::new(InsecureSerializableArtifacts {
- cdi_attest: cdi_attest[..]
- .try_into()
- .expect("Failed to convert cdi_attest to array reference."),
- cdi_seal: cdi_seal[..]
- .try_into()
- .expect("Failed to convert cdi_seal to array reference."),
- bcc,
+ cdi_attest,
+ cdi_seal,
+ bcc: dice_artifacts.bcc().expect("bcc is none").to_vec(),
})
}
.expect("Failed to create ResidentHal implementation."),
diff --git a/security/dice/aidl/vts/functional/Android.bp b/security/dice/aidl/vts/functional/Android.bp
index f5bc949..2a85a19 100644
--- a/security/dice/aidl/vts/functional/Android.bp
+++ b/security/dice/aidl/vts/functional/Android.bp
@@ -23,7 +23,7 @@
"android.hardware.security.dice-V1-rust",
"libanyhow",
"libbinder_rs",
- "libdiced_open_dice_cbor",
+ "libdiced_open_dice",
"libdiced_sample_inputs",
"libdiced_utils",
"libkeystore2_vintf_rust",
@@ -46,7 +46,7 @@
"android.hardware.security.dice-V1-rust",
"libanyhow",
"libbinder_rs",
- "libdiced_open_dice_cbor",
+ "libdiced_open_dice",
"libdiced_sample_inputs",
"libdiced_utils",
"libkeystore2_vintf_rust",
diff --git a/security/dice/aidl/vts/functional/dice_demote_test.rs b/security/dice/aidl/vts/functional/dice_demote_test.rs
index 1a17ec7..49aea67 100644
--- a/security/dice/aidl/vts/functional/dice_demote_test.rs
+++ b/security/dice/aidl/vts/functional/dice_demote_test.rs
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+use diced_open_dice::DiceArtifacts;
use diced_sample_inputs;
use diced_utils;
use std::convert::TryInto;
@@ -44,11 +45,10 @@
.unwrap();
let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
- let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
let from_former = diced_utils::make_bcc_handover(
- cdi_attest[..].try_into().unwrap(),
- cdi_seal[..].try_into().unwrap(),
- &bcc,
+ artifacts.cdi_attest(),
+ artifacts.cdi_seal(),
+ artifacts.bcc().expect("bcc is none"),
)
.unwrap();
// TODO b/204938506 when we have a parser/verifier, check equivalence rather
diff --git a/security/dice/aidl/vts/functional/dice_test.rs b/security/dice/aidl/vts/functional/dice_test.rs
index 190f187..fbbdd81 100644
--- a/security/dice/aidl/vts/functional/dice_test.rs
+++ b/security/dice/aidl/vts/functional/dice_test.rs
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+use diced_open_dice::DiceArtifacts;
use diced_sample_inputs;
use diced_utils;
-use std::convert::TryInto;
mod utils;
use utils::with_connection;
@@ -44,11 +44,10 @@
.unwrap();
let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
- let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
let from_former = diced_utils::make_bcc_handover(
- cdi_attest[..].try_into().unwrap(),
- cdi_seal[..].try_into().unwrap(),
- &bcc,
+ artifacts.cdi_attest(),
+ artifacts.cdi_seal(),
+ artifacts.bcc().expect("bcc is none"),
)
.unwrap();
// TODO b/204938506 when we have a parser/verifier, check equivalence rather
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 26e91bd..ed3ca74 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -35,9 +35,12 @@
"libbinder_ndk",
"libcrypto",
"libbase",
+ "libgatekeeper",
"packagemanager_aidl-cpp",
],
static_libs: [
+ "android.hardware.gatekeeper@1.0",
+ "android.hardware.gatekeeper-V1-ndk",
"android.hardware.security.rkp-V3-ndk",
"android.hardware.security.secureclock-V1-ndk",
"libcppbor_external",
@@ -59,6 +62,7 @@
],
srcs: [
"AttestKeyTest.cpp",
+ "AuthTest.cpp",
"DeviceUniqueAttestationTest.cpp",
"KeyBlobUpgradeTest.cpp",
"KeyMintTest.cpp",
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 99d2510..8027dce 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -86,7 +86,17 @@
} // namespace
class AttestKeyTest : public KeyMintAidlTestBase {
+ public:
+ void SetUp() override {
+ check_skip_test();
+ KeyMintAidlTestBase::SetUp();
+ }
+
protected:
+ const string FEATURE_KEYSTORE_APP_ATTEST_KEY = "android.hardware.keystore.app_attest_key";
+
+ const string FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
+
ErrorCode GenerateAttestKey(const AuthorizationSet& key_desc,
const optional<AttestationKey>& attest_key,
vector<uint8_t>* key_blob,
@@ -111,6 +121,62 @@
}
return GenerateKey(key_desc, attest_key, key_blob, key_characteristics, cert_chain);
}
+
+ // Check if ATTEST_KEY feature is disabled
+ bool is_attest_key_feature_disabled(void) const {
+ if (!check_feature(FEATURE_KEYSTORE_APP_ATTEST_KEY)) {
+ GTEST_LOG_(INFO) << "Feature " + FEATURE_KEYSTORE_APP_ATTEST_KEY + " is disabled";
+ return true;
+ }
+
+ return false;
+ }
+
+ // Check if StrongBox KeyStore is enabled
+ bool is_strongbox_enabled(void) const {
+ if (check_feature(FEATURE_STRONGBOX_KEYSTORE)) {
+ GTEST_LOG_(INFO) << "Feature " + FEATURE_STRONGBOX_KEYSTORE + " is enabled";
+ return true;
+ }
+
+ return false;
+ }
+
+ // Check if chipset has received a waiver allowing it to be launched with Android S or T with
+ // Keymaster 4.0 in StrongBox.
+ bool is_chipset_allowed_km4_strongbox(void) const {
+ std::array<char, PROPERTY_VALUE_MAX> buffer;
+
+ const int32_t first_api_level = property_get_int32("ro.board.first_api_level", 0);
+ if (first_api_level <= 0 || first_api_level > __ANDROID_API_T__) return false;
+
+ auto res = property_get("ro.vendor.qti.soc_model", buffer.data(), nullptr);
+ if (res <= 0) return false;
+
+ const string allowed_soc_models[] = {"SM8450", "SM8475", "SM8550", "SXR2230P"};
+
+ for (const string model : allowed_soc_models) {
+ if (model.compare(buffer.data()) == 0) {
+ GTEST_LOG_(INFO) << "QTI SOC Model " + model + " is allowed SB KM 4.0";
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // Skip the test if all the following conditions hold:
+ // 1. ATTEST_KEY feature is disabled
+ // 2. STRONGBOX is enabled
+ // 3. The device is running one of the chipsets that have received a waiver
+ // allowing it to be launched with Android S (or later) with Keymaster 4.0
+ // in StrongBox
+ void check_skip_test(void) const {
+ if (is_attest_key_feature_disabled() && is_strongbox_enabled() &&
+ is_chipset_allowed_km4_strongbox()) {
+ GTEST_SKIP() << "Test is not applicable";
+ }
+ }
};
/*
@@ -951,6 +1017,14 @@
.Authorization(TAG_ATTESTATION_ID_MEID, "mismatching-meid")
.Authorization(TAG_ATTESTATION_ID_MANUFACTURER, "malformed-manufacturer")
.Authorization(TAG_ATTESTATION_ID_MODEL, "malicious-model");
+
+ // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
+ if (SecLevel() != SecurityLevel::STRONGBOX) {
+ if (isSecondImeiIdAttestationRequired()) {
+ attestation_id_tags.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI,
+ "invalid-second-imei");
+ }
+ }
vector<uint8_t> key_blob;
vector<KeyCharacteristics> key_characteristics;
@@ -979,6 +1053,178 @@
CheckedDeleteKey(&attest_key.keyBlob);
}
+TEST_P(AttestKeyTest, SecondIMEIAttestationIDSuccess) {
+ if (is_gsi_image()) {
+ // GSI sets up a standard set of device identifiers that may not match
+ // the device identifiers held by the device.
+ GTEST_SKIP() << "Test not applicable under GSI";
+ }
+
+ // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ GTEST_SKIP() << "Test not applicable for SecurityLevel::STRONGBOX";
+ }
+
+ // Skip the test if there is no second IMEI exists.
+ string second_imei = get_imei(1);
+ if (second_imei.empty() || second_imei.compare("null") == 0) {
+ GTEST_SKIP() << "Test not applicable as there is no second IMEI";
+ }
+
+ if (!isSecondImeiIdAttestationRequired()) {
+ GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
+ }
+
+ // Create attestation key.
+ AttestationKey attest_key;
+ vector<KeyCharacteristics> attest_key_characteristics;
+ vector<Certificate> attest_key_cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateAttestKey(AuthorizationSetBuilder()
+ .EcdsaKey(EcCurve::P_256)
+ .AttestKey()
+ .SetDefaultValidity(),
+ {} /* attestation signing key */, &attest_key.keyBlob,
+ &attest_key_characteristics, &attest_key_cert_chain));
+ attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+ EXPECT_EQ(attest_key_cert_chain.size(), 1);
+ EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
+
+ // Use attestation key to sign an ECDSA key, but include an attestation ID field.
+ AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AttestationChallenge("challenge")
+ .AttestationApplicationId("foo")
+ .SetDefaultValidity();
+ // b/264979486 - second imei doesn't depend on first imei.
+ // Add second IMEI as attestation id without adding first IMEI as
+ // attestation id.
+ builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());
+
+ vector<uint8_t> attested_key_blob;
+ vector<KeyCharacteristics> attested_key_characteristics;
+ vector<Certificate> attested_key_cert_chain;
+ auto result = GenerateKey(builder, attest_key, &attested_key_blob,
+ &attested_key_characteristics, &attested_key_cert_chain);
+
+ if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+ GTEST_SKIP()
+ << "Test not applicable as device does not support SECOND-IMEI ID attestation.";
+ }
+
+ ASSERT_EQ(result, ErrorCode::OK);
+
+ device_id_attestation_vsr_check(result);
+
+ CheckedDeleteKey(&attested_key_blob);
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
+ // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+ // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+ // attestation extension should contain them, so make sure the extra tag is added.
+ vector<uint8_t> imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
+ KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, imei_blob);
+ hw_enforced.push_back(imei_tag);
+
+ EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
+ hw_enforced, SecLevel(),
+ attested_key_cert_chain[0].encodedCertificate));
+
+ CheckedDeleteKey(&attest_key.keyBlob);
+}
+
+TEST_P(AttestKeyTest, MultipleIMEIAttestationIDSuccess) {
+ if (is_gsi_image()) {
+ // GSI sets up a standard set of device identifiers that may not match
+ // the device identifiers held by the device.
+ GTEST_SKIP() << "Test not applicable under GSI";
+ }
+
+ // TODO(b/262255219): Remove this condition when StrongBox supports 2nd IMEI attestation.
+ if (SecLevel() == SecurityLevel::STRONGBOX) {
+ GTEST_SKIP() << "Test not applicable for SecurityLevel::STRONGBOX";
+ }
+
+ // Skip the test if there is no first IMEI exists.
+ string imei = get_imei(0);
+ if (imei.empty() || imei.compare("null") == 0) {
+ GTEST_SKIP() << "Test not applicable as there is no first IMEI";
+ }
+
+ // Skip the test if there is no second IMEI exists.
+ string second_imei = get_imei(1);
+ if (second_imei.empty() || second_imei.compare("null") == 0) {
+ GTEST_SKIP() << "Test not applicable as there is no second IMEI";
+ }
+
+ if (!isSecondImeiIdAttestationRequired()) {
+ GTEST_SKIP() << "Test not applicable for KeyMint-Version < 3 or first-api-level < 34";
+ }
+
+ // Create attestation key.
+ AttestationKey attest_key;
+ vector<KeyCharacteristics> attest_key_characteristics;
+ vector<Certificate> attest_key_cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateAttestKey(AuthorizationSetBuilder()
+ .EcdsaKey(EcCurve::P_256)
+ .AttestKey()
+ .SetDefaultValidity(),
+ {} /* attestation signing key */, &attest_key.keyBlob,
+ &attest_key_characteristics, &attest_key_cert_chain));
+ attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+ EXPECT_EQ(attest_key_cert_chain.size(), 1);
+ EXPECT_TRUE(IsSelfSigned(attest_key_cert_chain));
+
+ // Use attestation key to sign an ECDSA key, but include both IMEI attestation ID fields.
+ AuthorizationSetBuilder builder = AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AttestationChallenge("challenge")
+ .AttestationApplicationId("foo")
+ .SetDefaultValidity();
+ builder.Authorization(TAG_ATTESTATION_ID_IMEI, imei.data(), imei.size());
+ builder.Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, second_imei.data(), second_imei.size());
+
+ vector<uint8_t> attested_key_blob;
+ vector<KeyCharacteristics> attested_key_characteristics;
+ vector<Certificate> attested_key_cert_chain;
+ auto result = GenerateKey(builder, attest_key, &attested_key_blob,
+ &attested_key_characteristics, &attested_key_cert_chain);
+
+ if (result == ErrorCode::CANNOT_ATTEST_IDS && !isDeviceIdAttestationRequired()) {
+ GTEST_SKIP() << "Test not applicable as device does not support IMEI ID attestation.";
+ }
+
+ ASSERT_EQ(result, ErrorCode::OK);
+
+ device_id_attestation_vsr_check(result);
+
+ CheckedDeleteKey(&attested_key_blob);
+
+ AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
+ AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
+
+ // The attested key characteristics will not contain APPLICATION_ID_* fields (their
+ // spec definitions all have "Must never appear in KeyCharacteristics"), but the
+ // attestation extension should contain them, so make sure the extra tag is added.
+ vector<uint8_t> imei_blob(imei.data(), imei.data() + imei.size());
+ KeyParameter imei_tag = Authorization(TAG_ATTESTATION_ID_IMEI, imei_blob);
+ hw_enforced.push_back(imei_tag);
+ vector<uint8_t> sec_imei_blob(second_imei.data(), second_imei.data() + second_imei.size());
+ KeyParameter sec_imei_tag = Authorization(TAG_ATTESTATION_ID_SECOND_IMEI, sec_imei_blob);
+ hw_enforced.push_back(sec_imei_tag);
+
+ EXPECT_TRUE(verify_attestation_record(AidlVersion(), "challenge", "foo", sw_enforced,
+ hw_enforced, SecLevel(),
+ attested_key_cert_chain[0].encodedCertificate));
+
+ CheckedDeleteKey(&attest_key.keyBlob);
+}
+
INSTANTIATE_KEYMINT_AIDL_TEST(AttestKeyTest);
} // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/AuthTest.cpp b/security/keymint/aidl/vts/functional/AuthTest.cpp
new file mode 100644
index 0000000..a31ac01
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/AuthTest.cpp
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2023 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 "keymint_1_test"
+#include <cutils/log.h>
+
+#include <iostream>
+#include <optional>
+
+#include "KeyMintAidlTestBase.h"
+
+#include <aidl/android/hardware/gatekeeper/GatekeeperEnrollResponse.h>
+#include <aidl/android/hardware/gatekeeper/GatekeeperVerifyResponse.h>
+#include <aidl/android/hardware/gatekeeper/IGatekeeper.h>
+#include <aidl/android/hardware/security/secureclock/ISecureClock.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+
+using aidl::android::hardware::gatekeeper::GatekeeperEnrollResponse;
+using aidl::android::hardware::gatekeeper::GatekeeperVerifyResponse;
+using aidl::android::hardware::gatekeeper::IGatekeeper;
+using aidl::android::hardware::security::keymint::HardwareAuthToken;
+using aidl::android::hardware::security::secureclock::ISecureClock;
+
+#include <android/hardware/gatekeeper/1.0/IGatekeeper.h>
+#include <android/hardware/gatekeeper/1.0/types.h>
+#include <gatekeeper/password_handle.h> // for password_handle_t
+#include <hardware/hw_auth_token.h>
+
+using ::android::sp;
+using IHidlGatekeeper = ::android::hardware::gatekeeper::V1_0::IGatekeeper;
+using HidlGatekeeperResponse = ::android::hardware::gatekeeper::V1_0::GatekeeperResponse;
+using HidlGatekeeperStatusCode = ::android::hardware::gatekeeper::V1_0::GatekeeperStatusCode;
+
+namespace aidl::android::hardware::security::keymint::test {
+
+class AuthTest : public KeyMintAidlTestBase {
+ public:
+ void SetUp() {
+ KeyMintAidlTestBase::SetUp();
+
+ // Find the default Gatekeeper instance.
+ string gk_name = string(IGatekeeper::descriptor) + "/default";
+ if (AServiceManager_isDeclared(gk_name.c_str())) {
+ // Enroll a user with AIDL Gatekeeper.
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(gk_name.c_str()));
+ gk_ = IGatekeeper::fromBinder(binder);
+ } else {
+ // Prior to Android U, Gatekeeper was HIDL not AIDL and so may not be present.
+ // Try to enroll user with HIDL Gatekeeper instead.
+ string gk_name = "default";
+ hidl_gk_ = IHidlGatekeeper::getService(gk_name.c_str());
+ if (hidl_gk_ == nullptr) {
+ std::cerr << "No HIDL Gatekeeper instance for '" << gk_name << "' found.\n";
+ return;
+ }
+ std::cerr << "No AIDL Gatekeeper instance for '" << gk_name << "' found, using HIDL.\n";
+ }
+
+ // If the device needs timestamps, find the default ISecureClock instance.
+ if (timestamp_token_required_) {
+ string clock_name = string(ISecureClock::descriptor) + "/default";
+ if (AServiceManager_isDeclared(clock_name.c_str())) {
+ ::ndk::SpAIBinder binder(AServiceManager_waitForService(clock_name.c_str()));
+ clock_ = ISecureClock::fromBinder(binder);
+ } else {
+ std::cerr << "No ISecureClock instance for '" << clock_name << "' found.\n";
+ }
+ }
+
+ // Enroll a password for a user.
+ uid_ = 10001;
+ password_ = "correcthorsebatterystaple";
+ std::optional<GatekeeperEnrollResponse> rsp = doEnroll(password_);
+ ASSERT_TRUE(rsp.has_value());
+ sid_ = rsp->secureUserId;
+ handle_ = rsp->data;
+ }
+
+ void TearDown() {
+ if (gk_ == nullptr) return;
+ gk_->deleteUser(uid_);
+ }
+
+ bool GatekeeperAvailable() { return (gk_ != nullptr) || (hidl_gk_ != nullptr); }
+
+ std::optional<GatekeeperEnrollResponse> doEnroll(const std::vector<uint8_t>& newPwd,
+ const std::vector<uint8_t>& curHandle = {},
+ const std::vector<uint8_t>& curPwd = {}) {
+ if (gk_ != nullptr) {
+ while (true) {
+ GatekeeperEnrollResponse rsp;
+ Status status = gk_->enroll(uid_, curHandle, curPwd, newPwd, &rsp);
+ if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+ status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
+ sleep(1);
+ continue;
+ }
+ if (status.isOk()) {
+ return std::move(rsp);
+ } else {
+ GTEST_LOG_(ERROR) << "doEnroll(AIDL) failed: " << status;
+ return std::nullopt;
+ }
+ }
+ } else if (hidl_gk_ != nullptr) {
+ while (true) {
+ HidlGatekeeperResponse rsp;
+ auto status = hidl_gk_->enroll(
+ uid_, curHandle, curPwd, newPwd,
+ [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
+ if (!status.isOk()) {
+ GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed";
+ return std::nullopt;
+ }
+ if (rsp.code == HidlGatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
+ sleep(1);
+ continue;
+ }
+ if (rsp.code != HidlGatekeeperStatusCode::STATUS_OK) {
+ GTEST_LOG_(ERROR) << "doEnroll(HIDL) failed with " << int(rsp.code);
+ return std::nullopt;
+ }
+ // "Parse" the returned data to get at the secure user ID.
+ if (rsp.data.size() != sizeof(::gatekeeper::password_handle_t)) {
+ GTEST_LOG_(ERROR)
+ << "HAL returned password handle of invalid length " << rsp.data.size();
+ return std::nullopt;
+ }
+ const ::gatekeeper::password_handle_t* handle =
+ reinterpret_cast<const ::gatekeeper::password_handle_t*>(rsp.data.data());
+
+ // Translate HIDL response to look like an AIDL response.
+ GatekeeperEnrollResponse aidl_rsp;
+ aidl_rsp.statusCode = IGatekeeper::STATUS_OK;
+ aidl_rsp.data = rsp.data;
+ aidl_rsp.secureUserId = handle->user_id;
+ return aidl_rsp;
+ }
+ } else {
+ return std::nullopt;
+ }
+ }
+
+ std::optional<GatekeeperEnrollResponse> doEnroll(const string& newPwd,
+ const std::vector<uint8_t>& curHandle = {},
+ const string& curPwd = {}) {
+ return doEnroll(std::vector<uint8_t>(newPwd.begin(), newPwd.end()), curHandle,
+ std::vector<uint8_t>(curPwd.begin(), curPwd.end()));
+ }
+
+ std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
+ const std::vector<uint8_t>& handle,
+ const std::vector<uint8_t>& pwd) {
+ if (gk_ != nullptr) {
+ while (true) {
+ GatekeeperVerifyResponse rsp;
+ Status status = gk_->verify(uid_, challenge, handle, pwd, &rsp);
+ if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+ status.getServiceSpecificError() == IGatekeeper::ERROR_RETRY_TIMEOUT) {
+ sleep(1);
+ continue;
+ }
+ if (status.isOk()) {
+ return rsp.hardwareAuthToken;
+ } else {
+ GTEST_LOG_(ERROR) << "doVerify(AIDL) failed: " << status;
+ return std::nullopt;
+ }
+ }
+ } else if (hidl_gk_ != nullptr) {
+ while (true) {
+ HidlGatekeeperResponse rsp;
+ auto status = hidl_gk_->verify(
+ uid_, challenge, handle, pwd,
+ [&rsp](const HidlGatekeeperResponse& cbRsp) { rsp = cbRsp; });
+ if (!status.isOk()) {
+ GTEST_LOG_(ERROR) << "doVerify(HIDL) failed";
+ return std::nullopt;
+ }
+ if (rsp.code == HidlGatekeeperStatusCode::ERROR_RETRY_TIMEOUT) {
+ sleep(1);
+ continue;
+ }
+ if (rsp.code != HidlGatekeeperStatusCode::STATUS_OK) {
+ GTEST_LOG_(ERROR) << "doVerify(HIDL) failed with " << int(rsp.code);
+ return std::nullopt;
+ }
+ // "Parse" the returned data to get auth token contents.
+ if (rsp.data.size() != sizeof(hw_auth_token_t)) {
+ GTEST_LOG_(ERROR) << "Incorrect size of AuthToken payload.";
+ return std::nullopt;
+ }
+ const hw_auth_token_t* hwAuthToken =
+ reinterpret_cast<const hw_auth_token_t*>(rsp.data.data());
+ HardwareAuthToken authToken;
+ authToken.timestamp.milliSeconds = betoh64(hwAuthToken->timestamp);
+ authToken.challenge = hwAuthToken->challenge;
+ authToken.userId = hwAuthToken->user_id;
+ authToken.authenticatorId = hwAuthToken->authenticator_id;
+ authToken.authenticatorType = static_cast<HardwareAuthenticatorType>(
+ betoh32(hwAuthToken->authenticator_type));
+ authToken.mac.assign(&hwAuthToken->hmac[0], &hwAuthToken->hmac[32]);
+ return authToken;
+ }
+ } else {
+ return std::nullopt;
+ }
+ }
+ std::optional<HardwareAuthToken> doVerify(uint64_t challenge,
+ const std::vector<uint8_t>& handle,
+ const string& pwd) {
+ return doVerify(challenge, handle, std::vector<uint8_t>(pwd.begin(), pwd.end()));
+ }
+
+ // Variants of the base class methods but with authentication information included.
+ string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
+ const string& message, const AuthorizationSet& in_params,
+ AuthorizationSet* out_params, const HardwareAuthToken& hat) {
+ AuthorizationSet begin_out_params;
+ ErrorCode result = Begin(operation, key_blob, in_params, out_params, hat);
+ EXPECT_EQ(ErrorCode::OK, result);
+ if (result != ErrorCode::OK) {
+ return "";
+ }
+
+ std::optional<secureclock::TimeStampToken> time_token = std::nullopt;
+ if (timestamp_token_required_ && clock_ != nullptr) {
+ // Ask a secure clock instance for a timestamp, including the per-op challenge.
+ secureclock::TimeStampToken token;
+ EXPECT_EQ(ErrorCode::OK,
+ GetReturnErrorCode(clock_->generateTimeStamp(challenge_, &token)));
+ time_token = token;
+ }
+
+ string output;
+ EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &output, hat, time_token));
+ return output;
+ }
+
+ string EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
+ const AuthorizationSet& in_params, AuthorizationSet* out_params,
+ const HardwareAuthToken& hat) {
+ SCOPED_TRACE("EncryptMessage");
+ return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params, hat);
+ }
+
+ string DecryptMessage(const vector<uint8_t>& key_blob, const string& ciphertext,
+ const AuthorizationSet& params, const HardwareAuthToken& hat) {
+ SCOPED_TRACE("DecryptMessage");
+ AuthorizationSet out_params;
+ string plaintext =
+ ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params, hat);
+ EXPECT_TRUE(out_params.empty());
+ return plaintext;
+ }
+
+ protected:
+ std::shared_ptr<IGatekeeper> gk_;
+ sp<IHidlGatekeeper> hidl_gk_;
+ std::shared_ptr<ISecureClock> clock_;
+ string password_;
+ uint32_t uid_;
+ long sid_;
+ std::vector<uint8_t> handle_;
+};
+
+// Test use of a key that requires user-authentication within recent history.
+TEST_P(AuthTest, TimeoutAuthentication) {
+ if (!GatekeeperAvailable()) {
+ GTEST_SKIP() << "No Gatekeeper available";
+ }
+ if (timestamp_token_required_ && clock_ == nullptr) {
+ GTEST_SKIP() << "Device requires timestamps and no ISecureClock available";
+ }
+
+ // Create an AES key that requires authentication within the last 3 seconds.
+ const uint32_t timeout_secs = 3;
+ auto builder = AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_USER_SECURE_ID, sid_)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
+ .Authorization(TAG_AUTH_TIMEOUT, timeout_secs);
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+ // Attempt to use the AES key without authentication.
+ const string message = "Hello World!";
+ AuthorizationSet out_params;
+ auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+
+ // Verify to get a HAT, arbitrary challenge.
+ const uint64_t challenge = 42;
+ const std::optional<HardwareAuthToken> hat = doVerify(challenge, handle_, password_);
+ ASSERT_TRUE(hat.has_value());
+ EXPECT_EQ(hat->userId, sid_);
+
+ // Adding the auth token makes it possible to use the AES key.
+ const string ciphertext = EncryptMessage(keyblob, message, params, &out_params, hat.value());
+ const string plaintext = DecryptMessage(keyblob, ciphertext, params, hat.value());
+ EXPECT_EQ(message, plaintext);
+
+ // Altering a single bit in the MAC means no auth.
+ HardwareAuthToken dodgy_hat = hat.value();
+ ASSERT_GT(dodgy_hat.mac.size(), 0);
+ dodgy_hat.mac[0] ^= 0x01;
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, dodgy_hat));
+
+ // Wait for long enough that the hardware auth token expires.
+ sleep(timeout_secs + 1);
+ if (!timestamp_token_required_) {
+ // KeyMint implementation has its own clock, and can immediately detect timeout.
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat));
+ } else {
+ // KeyMint implementation has no clock, so only detects timeout via timestamp token provided
+ // on update()/finish().
+ ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, hat));
+ secureclock::TimeStampToken time_token;
+ EXPECT_EQ(ErrorCode::OK,
+ GetReturnErrorCode(clock_->generateTimeStamp(challenge_, &time_token)));
+
+ string output;
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Finish(message, {} /* signature */, &output, hat, time_token));
+ }
+}
+
+// Test use of a key that requires an auth token for each action on the operation, with
+// a per-operation challenge value included.
+TEST_P(AuthTest, AuthPerOperation) {
+ if (!GatekeeperAvailable()) {
+ GTEST_SKIP() << "No Gatekeeper available";
+ }
+
+ // Create an AES key that requires authentication per-action.
+ auto builder = AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_USER_SECURE_ID, sid_)
+ .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD);
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ ASSERT_EQ(ErrorCode::OK,
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain));
+
+ // Attempt to use the AES key without authentication fails after begin.
+ const string message = "Hello World!";
+ AuthorizationSet out_params;
+ auto params = AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+ string output;
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED, Finish(message, {} /* signature */, &output));
+
+ // Verify to get a HAT, but with an arbitrary challenge.
+ const uint64_t unrelated_challenge = 42;
+ const std::optional<HardwareAuthToken> unrelated_hat =
+ doVerify(unrelated_challenge, handle_, password_);
+ ASSERT_TRUE(unrelated_hat.has_value());
+ EXPECT_EQ(unrelated_hat->userId, sid_);
+
+ // Attempt to use the AES key with an unrelated authentication fails after begin.
+ EXPECT_EQ(ErrorCode::OK,
+ Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params, unrelated_hat.value()));
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Finish(message, {} /* signature */, &output, unrelated_hat.value()));
+
+ // Now get a HAT with the challenge from an in-progress operation.
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+ const std::optional<HardwareAuthToken> hat = doVerify(challenge_, handle_, password_);
+ ASSERT_TRUE(hat.has_value());
+ EXPECT_EQ(hat->userId, sid_);
+ string ciphertext;
+ EXPECT_EQ(ErrorCode::OK, Finish(message, {} /* signature */, &ciphertext, hat.value()));
+
+ // Altering a single bit in the MAC means no auth.
+ EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, keyblob, params, &out_params));
+ std::optional<HardwareAuthToken> dodgy_hat = doVerify(challenge_, handle_, password_);
+ ASSERT_TRUE(dodgy_hat.has_value());
+ EXPECT_EQ(dodgy_hat->userId, sid_);
+ ASSERT_GT(dodgy_hat->mac.size(), 0);
+ dodgy_hat->mac[0] ^= 0x01;
+ EXPECT_EQ(ErrorCode::KEY_USER_NOT_AUTHENTICATED,
+ Finish(message, {} /* signature */, &ciphertext, hat.value()));
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(AuthTest);
+
+} // namespace aidl::android::hardware::security::keymint::test
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index e9cbe10..4b4f953 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -108,27 +108,6 @@
return true;
}
-// Extract attestation record from cert. Returned object is still part of cert; don't free it
-// separately.
-ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
- ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
- EXPECT_TRUE(!!oid.get());
- if (!oid.get()) return nullptr;
-
- int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
- EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
- if (location == -1) return nullptr;
-
- X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
- EXPECT_TRUE(!!attest_rec_ext)
- << "Found attestation extension but couldn't retrieve it? Probably a BoringSSL bug.";
- if (!attest_rec_ext) return nullptr;
-
- ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
- EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
- return attest_rec;
-}
-
void check_attestation_version(uint32_t attestation_version, int32_t aidl_version) {
// Version numbers in attestation extensions should be a multiple of 100.
EXPECT_EQ(attestation_version % 100, 0);
@@ -217,6 +196,14 @@
return AidlVersion() >= 2 || property_get_int32("ro.vendor.api_level", 0) >= 33;
}
+/**
+ * An API to determine second IMEI ID attestation is required or not,
+ * which is supported for KeyMint version 3 or first_api_level greater than 33.
+ */
+bool KeyMintAidlTestBase::isSecondImeiIdAttestationRequired() {
+ return AidlVersion() >= 3 && property_get_int32("ro.vendor.api_level", 0) > 33;
+}
+
bool KeyMintAidlTestBase::Curve25519Supported() {
// Strongbox never supports curve 25519.
if (SecLevel() == SecurityLevel::STRONGBOX) {
@@ -544,12 +531,13 @@
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
const AuthorizationSet& in_params,
- AuthorizationSet* out_params) {
+ AuthorizationSet* out_params,
+ std::optional<HardwareAuthToken> hat) {
SCOPED_TRACE("Begin");
Status result;
BeginResult out;
- result = keymint_->begin(purpose, key_blob, in_params.vector_data(), std::nullopt, &out);
+ result = keymint_->begin(purpose, key_blob, in_params.vector_data(), hat, &out);
if (result.isOk()) {
*out_params = out.params;
@@ -603,8 +591,9 @@
return GetReturnErrorCode(result);
}
-ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature,
- string* output) {
+ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature, string* output,
+ std::optional<HardwareAuthToken> hat,
+ std::optional<secureclock::TimeStampToken> time_token) {
SCOPED_TRACE("Finish");
Status result;
@@ -613,8 +602,8 @@
vector<uint8_t> oPut;
result = op_->finish(vector<uint8_t>(input.begin(), input.end()),
- vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
- {} /* timestampToken */, {} /* confirmationToken */, &oPut);
+ vector<uint8_t>(signature.begin(), signature.end()), hat, time_token,
+ {} /* confirmationToken */, &oPut);
if (result.isOk()) output->append(oPut.begin(), oPut.end());
@@ -1743,38 +1732,33 @@
EXPECT_EQ(security_level, att_keymint_security_level);
EXPECT_EQ(security_level, att_attestation_security_level);
- // TODO(b/136282179): When running under VTS-on-GSI the TEE-backed
- // keymint implementation will report YYYYMM dates instead of YYYYMMDD
- // for the BOOT_PATCH_LEVEL.
- if (avb_verification_enabled()) {
- for (int i = 0; i < att_hw_enforced.size(); i++) {
- if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
- att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
- std::string date =
- std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::integer>());
+ for (int i = 0; i < att_hw_enforced.size(); i++) {
+ if (att_hw_enforced[i].tag == TAG_BOOT_PATCHLEVEL ||
+ att_hw_enforced[i].tag == TAG_VENDOR_PATCHLEVEL) {
+ std::string date =
+ std::to_string(att_hw_enforced[i].value.get<KeyParameterValue::integer>());
- // strptime seems to require delimiters, but the tag value will
- // be YYYYMMDD
- if (date.size() != 8) {
- ADD_FAILURE() << "Tag " << att_hw_enforced[i].tag
- << " with invalid format (not YYYYMMDD): " << date;
- return false;
- }
- date.insert(6, "-");
- date.insert(4, "-");
- struct tm time;
- strptime(date.c_str(), "%Y-%m-%d", &time);
-
- // Day of the month (0-31)
- EXPECT_GE(time.tm_mday, 0);
- EXPECT_LT(time.tm_mday, 32);
- // Months since Jan (0-11)
- EXPECT_GE(time.tm_mon, 0);
- EXPECT_LT(time.tm_mon, 12);
- // Years since 1900
- EXPECT_GT(time.tm_year, 110);
- EXPECT_LT(time.tm_year, 200);
+ // strptime seems to require delimiters, but the tag value will
+ // be YYYYMMDD
+ if (date.size() != 8) {
+ ADD_FAILURE() << "Tag " << att_hw_enforced[i].tag
+ << " with invalid format (not YYYYMMDD): " << date;
+ return false;
}
+ date.insert(6, "-");
+ date.insert(4, "-");
+ struct tm time;
+ strptime(date.c_str(), "%Y-%m-%d", &time);
+
+ // Day of the month (0-31)
+ EXPECT_GE(time.tm_mday, 0);
+ EXPECT_LT(time.tm_mday, 32);
+ // Months since Jan (0-11)
+ EXPECT_GE(time.tm_mon, 0);
+ EXPECT_LT(time.tm_mon, 12);
+ // Years since 1900
+ EXPECT_GT(time.tm_year, 110);
+ EXPECT_LT(time.tm_year, 200);
}
}
@@ -1896,6 +1880,27 @@
return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
}
+// Extract attestation record from cert. Returned object is still part of cert; don't free it
+// separately.
+ASN1_OCTET_STRING* get_attestation_record(X509* certificate) {
+ ASN1_OBJECT_Ptr oid(OBJ_txt2obj(kAttestionRecordOid, 1 /* dotted string format */));
+ EXPECT_TRUE(!!oid.get());
+ if (!oid.get()) return nullptr;
+
+ int location = X509_get_ext_by_OBJ(certificate, oid.get(), -1 /* search from beginning */);
+ EXPECT_NE(-1, location) << "Attestation extension not found in certificate";
+ if (location == -1) return nullptr;
+
+ X509_EXTENSION* attest_rec_ext = X509_get_ext(certificate, location);
+ EXPECT_TRUE(!!attest_rec_ext)
+ << "Found attestation extension but couldn't retrieve it? Probably a BoringSSL bug.";
+ if (!attest_rec_ext) return nullptr;
+
+ ASN1_OCTET_STRING* attest_rec = X509_EXTENSION_get_data(attest_rec_ext);
+ EXPECT_TRUE(!!attest_rec) << "Attestation extension contained no data";
+ return attest_rec;
+}
+
vector<uint8_t> make_name_from_str(const string& name) {
X509_NAME_Ptr x509_name(X509_NAME_new());
EXPECT_TRUE(x509_name.get() != nullptr);
@@ -2052,9 +2057,10 @@
// Check whether the given named feature is available.
bool check_feature(const std::string& name) {
::android::sp<::android::IServiceManager> sm(::android::defaultServiceManager());
- ::android::sp<::android::IBinder> binder(sm->getService(::android::String16("package_native")));
+ ::android::sp<::android::IBinder> binder(
+ sm->waitForService(::android::String16("package_native")));
if (binder == nullptr) {
- GTEST_LOG_(ERROR) << "getService package_native failed";
+ GTEST_LOG_(ERROR) << "waitForService package_native failed";
return false;
}
::android::sp<::android::content::pm::IPackageManagerNative> packageMgr =
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index fae9459..a6a9df6 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -85,6 +85,7 @@
uint32_t boot_patch_level(const vector<KeyCharacteristics>& key_characteristics);
uint32_t boot_patch_level();
bool isDeviceIdAttestationRequired();
+ bool isSecondImeiIdAttestationRequired();
bool Curve25519Supported();
@@ -160,7 +161,8 @@
const AuthorizationSet& in_params, AuthorizationSet* out_params,
std::shared_ptr<IKeyMintOperation>& op);
ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
- const AuthorizationSet& in_params, AuthorizationSet* out_params);
+ const AuthorizationSet& in_params, AuthorizationSet* out_params,
+ std::optional<HardwareAuthToken> hat = std::nullopt);
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
AuthorizationSet* out_params);
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
@@ -168,7 +170,9 @@
ErrorCode UpdateAad(const string& input);
ErrorCode Update(const string& input, string* output);
- ErrorCode Finish(const string& message, const string& signature, string* output);
+ ErrorCode Finish(const string& message, const string& signature, string* output,
+ std::optional<HardwareAuthToken> hat = std::nullopt,
+ std::optional<secureclock::TimeStampToken> time_token = std::nullopt);
ErrorCode Finish(const string& message, string* output) {
return Finish(message, {} /* signature */, output);
}
@@ -397,6 +401,7 @@
string bin2hex(const vector<uint8_t>& data);
X509_Ptr parse_cert_blob(const vector<uint8_t>& blob);
+ASN1_OCTET_STRING* get_attestation_record(X509* certificate);
vector<uint8_t> make_name_from_str(const string& name);
void check_maced_pubkey(const MacedPublicKey& macedPubKey, bool testMode,
vector<uint8_t>* payload_value);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 1b9e758..357405f 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -1214,7 +1214,7 @@
* that has been generated using an associate IRemotelyProvisionedComponent.
*/
TEST_P(NewKeyGenerationTest, EcdsaWithRkpAttestation) {
- if (get_vsr_api_level() < 32 || AidlVersion() < 2) {
+ if (get_vsr_api_level() <= 32 || AidlVersion() < 2) {
GTEST_SKIP() << "Only required for VSR 12+ and KeyMint 2+";
}
diff --git a/security/keymint/support/attestation_record.cpp b/security/keymint/support/attestation_record.cpp
index 2462228..5a26611 100644
--- a/security/keymint/support/attestation_record.cpp
+++ b/security/keymint/support/attestation_record.cpp
@@ -105,6 +105,7 @@
ASN1_INTEGER* boot_patchlevel;
ASN1_NULL* device_unique_attestation;
ASN1_NULL* identity_credential;
+ ASN1_OCTET_STRING* attestation_id_second_imei;
} KM_AUTH_LIST;
ASN1_SEQUENCE(KM_AUTH_LIST) = {
@@ -170,6 +171,8 @@
TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()),
ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL,
TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()),
+ ASN1_EXP_OPT(KM_AUTH_LIST, attestation_id_second_imei, ASN1_OCTET_STRING,
+ TAG_ATTESTATION_ID_SECOND_IMEI.maskedTag()),
} ASN1_SEQUENCE_END(KM_AUTH_LIST);
IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
@@ -323,6 +326,7 @@
copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list);
copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list);
+ copyAuthTag(record->attestation_id_second_imei, TAG_ATTESTATION_ID_SECOND_IMEI, auth_list);
return ErrorCode::OK;
}
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 5b2a6f3..823899a 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -77,6 +77,7 @@
DECLARE_TYPED_TAG(ATTESTATION_ID_BRAND);
DECLARE_TYPED_TAG(ATTESTATION_ID_DEVICE);
DECLARE_TYPED_TAG(ATTESTATION_ID_IMEI);
+DECLARE_TYPED_TAG(ATTESTATION_ID_SECOND_IMEI);
DECLARE_TYPED_TAG(ATTESTATION_ID_MANUFACTURER);
DECLARE_TYPED_TAG(ATTESTATION_ID_MEID);
DECLARE_TYPED_TAG(ATTESTATION_ID_PRODUCT);
diff --git a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
index 404553b..1397c05 100644
--- a/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
+++ b/security/rkp/aidl/aidl_api/android.hardware.security.rkp/1/.hash
@@ -1 +1,2 @@
+976674616001f714f4a4df49ee45f548de828524
d285480d2e0002adc0ace80edf34aa725679512e
diff --git a/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl b/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
index 57ee8cf..de94264 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/ProtectedData.aidl
@@ -70,7 +70,7 @@
* ; HKDF. See details on use in ProtectedData comments above. The public key data
* ; included in the other field of PartyUInfo / PartyVInfo is encoded as:
* ; - a raw 32-byte public key for X25519
- * ; - uncompressed SEC-1 coordinate data (0x04 || x || y) for P-256
+ * ; - raw coordinate data (x || y) for P-256
* Context = [
* AlgorithmID : 3 ; AES-GCM 256
* PartyUInfo : [
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 573f10b..bf40976 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -23,6 +23,7 @@
#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
#include <android/binder_manager.h>
#include <binder/IServiceManager.h>
+#include <cppbor.h>
#include <cppbor_parse.h>
#include <gmock/gmock.h>
#include <keymaster/cppcose/cppcose.h>
@@ -797,6 +798,128 @@
BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
}
+void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
+ vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
+ bool* device_locked, vector<uint8_t>* verified_boot_hash) {
+ X509_Ptr cert(parse_cert_blob(attestation_cert));
+ ASSERT_TRUE(cert.get());
+
+ ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
+ ASSERT_TRUE(attest_rec);
+
+ auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, verified_boot_key,
+ verified_boot_state, device_locked, verified_boot_hash);
+ ASSERT_EQ(error, ErrorCode::OK);
+}
+
+/**
+ * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
+ */
+TEST_P(CertificateRequestV2Test, DeviceInfo) {
+ // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
+ std::shared_ptr<IKeyMintDevice> keyMint;
+ if (!matching_keymint_device(GetParam(), &keyMint)) {
+ // No matching IKeyMintDevice.
+ GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
+ return;
+ }
+ KeyMintHardwareInfo info;
+ ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
+
+ // Get IDs attested by KeyMint.
+ MacedPublicKey macedPubKey;
+ bytevec privateKeyBlob;
+ auto irpcStatus =
+ provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
+ ASSERT_TRUE(irpcStatus.isOk());
+
+ AttestationKey attestKey;
+ attestKey.keyBlob = std::move(privateKeyBlob);
+ attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
+
+ // Generate an ECDSA key that is attested by the generated P256 keypair.
+ AuthorizationSet keyDesc = AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(EcCurve::P_256)
+ .AttestationChallenge("foo")
+ .AttestationApplicationId("bar")
+ .Digest(Digest::NONE)
+ .SetDefaultValidity();
+ KeyCreationResult creationResult;
+ auto kmStatus = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
+ ASSERT_TRUE(kmStatus.isOk());
+
+ vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
+ vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
+ // We didn't provision the attestation key.
+ ASSERT_EQ(key_cert_chain.size(), 1);
+
+ // Parse attested patch levels.
+ auto auths = HwEnforcedAuthorizations(key_characteristics);
+
+ auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
+ auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
+ auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
+
+ ASSERT_TRUE(attestedSystemPatchLevel.has_value());
+ ASSERT_TRUE(attestedVendorPatchLevel.has_value());
+ ASSERT_TRUE(attestedBootPatchLevel.has_value());
+
+ // Parse attested AVB values.
+ vector<uint8_t> key;
+ VerifiedBoot attestedVbState;
+ bool attestedBootloaderState;
+ vector<uint8_t> attestedVbmetaDigest;
+ parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
+ &attestedBootloaderState, &attestedVbmetaDigest);
+
+ // Get IDs from DeviceInfo.
+ bytevec csr;
+ irpcStatus =
+ provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
+ ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();
+
+ auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
+ ASSERT_TRUE(result) << result.message();
+
+ std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
+ ASSERT_TRUE(csrPayload);
+
+ auto deviceInfo = csrPayload->get(2)->asMap();
+ ASSERT_TRUE(deviceInfo);
+
+ auto vbState = deviceInfo->get("vb_state")->asTstr();
+ auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
+ auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
+ auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
+ auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
+ auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
+ auto securityLevel = deviceInfo->get("security_level")->asTstr();
+
+ ASSERT_TRUE(vbState);
+ ASSERT_TRUE(bootloaderState);
+ ASSERT_TRUE(vbmetaDigest);
+ ASSERT_TRUE(systemPatchLevel);
+ ASSERT_TRUE(vendorPatchLevel);
+ ASSERT_TRUE(bootPatchLevel);
+ ASSERT_TRUE(securityLevel);
+
+ auto kmDeviceName = device_suffix(GetParam());
+
+ // Compare DeviceInfo against IDs attested by KeyMint.
+ ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
+ (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
+ ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
+ (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
+ (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
+ ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
+ (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
+ ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
+ ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
+ ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
+ ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
+}
+
INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
diff --git a/staging/threadnetwork/OWNERS b/staging/threadnetwork/OWNERS
new file mode 100644
index 0000000..037215d
--- /dev/null
+++ b/staging/threadnetwork/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 1203089
+
+wgtdkp@google.com
+xyk@google.com
+zhanglongxia@google.com
diff --git a/staging/threadnetwork/README.md b/staging/threadnetwork/README.md
new file mode 100644
index 0000000..12104e5
--- /dev/null
+++ b/staging/threadnetwork/README.md
@@ -0,0 +1,12 @@
+# Staging threadnetwork HAL interface
+
+The directory includes the unstable/unreleased version of `hardware/interfaces/threadnetwork`
+code which should **NOT** be used in production. But vendors may start verifying their hardware
+with the HAL interface.
+
+This directory will be cleaned up when the stable Thread HAL interface is added in
+`hardware/interfaces/threadnetwork` by version `V` or later.
+
+More information about _Thread_:
+- https://www.threadgroup.org
+- https://openthread.io
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl
index 30b2c8d..984f2a5 100644
--- a/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/IOffload.aidl
@@ -32,8 +32,7 @@
/**
* Indicates intent to start offload for tethering in immediate future.
*
- * This API must be called exactly once the first time that Tethering is requested by
- * the user.
+ * This API must be called exactly once when Tethering is requested by the user.
*
* If this API is called multiple times without first calling stopOffload, then the subsequent
* calls must fail without changing the state of the server.
@@ -168,7 +167,6 @@
* or negative number of bytes).
* - EX_ILLEGAL_STATE if this method is called before initOffload(), or if this method
* is called after stopOffload().
- * - EX_UNSUPPORTED_OPERATION if it is not supported.
* - EX_SERVICE_SPECIFIC with the error message set to a human-readable reason for the
* error.
*/
@@ -269,7 +267,7 @@
* This API may only be called after initOffload and before stopOffload.
*
* @param iface Downstream interface
- * @param prefix Downstream prefix depicting address that must no longer be offloaded
+ * @param prefix Downstream prefix depicting prefix that must no longer be offloaded
* For e.g. 192.168.1.0/24 or 2001:4860:684::/64)
*
* @throws:
diff --git a/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl b/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
index a95f674..15a1f93 100644
--- a/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
+++ b/tetheroffload/aidl/android/hardware/tetheroffload/OffloadCallbackEvent.aidl
@@ -55,7 +55,7 @@
*/
OFFLOAD_STOPPED_LIMIT_REACHED = 5,
/**
- * This event is fired when the quota, applied in setDataWarning, has expired. It is
+ * This event is fired when the quota, applied in setDataWarningAndLimit, has expired. It is
* recommended that the client query for statistics immediately after receiving this event.
* Any offloaded traffic will continue to be offloaded until offload is stopped or
* OFFLOAD_STOPPED_LIMIT_REACHED is sent.
diff --git a/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp b/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
index fc8abbd..f46c9ab 100644
--- a/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
+++ b/tetheroffload/aidl/vts/functional/VtsHalTetheroffloadTargetTest.cpp
@@ -152,15 +152,13 @@
void initOffload(const bool expectedResult) {
unique_fd ufd1(netlinkSocket(kFd1Groups));
if (ufd1.get() < 0) {
- ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
- FAIL();
+ FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
}
ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
unique_fd ufd2(netlinkSocket(kFd2Groups));
if (ufd2.get() < 0) {
- ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
- FAIL();
+ FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
}
ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
@@ -214,8 +212,7 @@
ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(-1);
unique_fd ufd2(netlinkSocket(kFd2Groups));
if (ufd2.get() < 0) {
- ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
- FAIL();
+ FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
}
ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(ufd2.release());
mTetheringOffloadCallback = ndk::SharedRefBase::make<TetheringOffloadCallback>();
@@ -229,8 +226,7 @@
TEST_P(TetheroffloadAidlPreInitTest, TestInitOffloadInvalidFd2ReturnsError) {
unique_fd ufd1(netlinkSocket(kFd1Groups));
if (ufd1.get() < 0) {
- ALOGE("Unable to create conntrack sockets: %d/%s", errno, strerror(errno));
- FAIL();
+ FAIL() << "Unable to create conntrack sockets: " << strerror(errno);
}
ndk::ScopedFileDescriptor fd1 = ndk::ScopedFileDescriptor(ufd1.release());
ndk::ScopedFileDescriptor fd2 = ndk::ScopedFileDescriptor(-1);
@@ -264,7 +260,8 @@
const std::string v4Addr("192.0.0.2");
const std::string v4Gw("192.0.0.1");
const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
- EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
+ auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+ EXPECT_TRUE(ret.isOk()) << ret;
if (!interfaceIsUp(TEST_IFACE)) {
return;
}
@@ -279,7 +276,7 @@
// Check that calling setLocalPrefixes() without first having called initOffload() returns error.
TEST_P(TetheroffloadAidlPreInitTest, SetLocalPrefixesWithoutInitReturnsError) {
const std::vector<std::string> prefixes{std::string("2001:db8::/64")};
- EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
}
// Check that calling getForwardedStats() without first having called initOffload()
@@ -287,9 +284,10 @@
TEST_P(TetheroffloadAidlPreInitTest, GetForwardedStatsWithoutInitReturnsZeroValues) {
const std::string upstream(TEST_IFACE);
ForwardedStats stats;
- EXPECT_TRUE(mOffload->getForwardedStats(upstream, &stats).isOk());
- EXPECT_EQ(stats.rxBytes, 0ULL);
- EXPECT_EQ(stats.txBytes, 0ULL);
+ auto ret = mOffload->getForwardedStats(upstream, &stats);
+ EXPECT_TRUE(ret.isOk()) << ret;
+ EXPECT_EQ(0ULL, stats.rxBytes);
+ EXPECT_EQ(0ULL, stats.txBytes);
}
// Check that calling setDataWarningAndLimit() without first having called initOffload() returns
@@ -298,8 +296,8 @@
const std::string upstream(TEST_IFACE);
const int64_t warning = 5000LL;
const int64_t limit = 5000LL;
- EXPECT_EQ(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
- EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE,
+ mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
}
// Check that calling setUpstreamParameters() without first having called initOffload()
@@ -309,8 +307,8 @@
const std::string v4Addr("192.0.2.0/24");
const std::string v4Gw("192.0.2.1");
const std::vector<std::string> v6Gws{std::string("fe80::db8:1")};
- EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
- EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE,
+ mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
}
// Check that calling addDownstream() with an IPv4 prefix without first having called
@@ -318,7 +316,7 @@
TEST_P(TetheroffloadAidlPreInitTest, AddIPv4DownstreamWithoutInitReturnsError) {
const std::string iface(TEST_IFACE);
const std::string prefix("192.0.2.0/24");
- EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->addDownstream(iface, prefix).getExceptionCode());
}
// Check that calling addDownstream() with an IPv6 prefix without first having called
@@ -326,7 +324,7 @@
TEST_P(TetheroffloadAidlPreInitTest, AddIPv6DownstreamWithoutInitReturnsError) {
const std::string iface(TEST_IFACE);
const std::string prefix("2001:db8::/64");
- EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->addDownstream(iface, prefix).getExceptionCode());
}
// Check that calling removeDownstream() with an IPv4 prefix without first having called
@@ -334,7 +332,7 @@
TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv4DownstreamWithoutInitReturnsError) {
const std::string iface(TEST_IFACE);
const std::string prefix("192.0.2.0/24");
- EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->removeDownstream(iface, prefix).getExceptionCode());
}
// Check that calling removeDownstream() with an IPv6 prefix without first having called
@@ -342,7 +340,7 @@
TEST_P(TetheroffloadAidlPreInitTest, RemoveIPv6DownstreamWithoutInitReturnsError) {
const std::string iface(TEST_IFACE);
const std::string prefix("2001:db8::/64");
- EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_STATE);
+ EXPECT_EQ(EX_ILLEGAL_STATE, mOffload->removeDownstream(iface, prefix).getExceptionCode());
}
/*
@@ -352,19 +350,20 @@
// Test setLocalPrefixes() rejects an IPv4 address.
TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4AddressFails) {
const std::vector<std::string> prefixes{std::string("192.0.2.1")};
- EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
}
// Test setLocalPrefixes() rejects an IPv6 address.
TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv6AddressFails) {
const std::vector<std::string> prefixes{std::string("fe80::1")};
- EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
}
// Test setLocalPrefixes() accepts both IPv4 and IPv6 prefixes.
TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesIPv4v6PrefixesOk) {
const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("fe80::/64")};
- EXPECT_TRUE(mOffload->setLocalPrefixes(prefixes).isOk());
+ auto ret = mOffload->setLocalPrefixes(prefixes);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test that setLocalPrefixes() fails given empty input. There is always
@@ -372,13 +371,13 @@
// we still apply {127.0.0.0/8, ::1/128, fe80::/64} here.
TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesEmptyFails) {
const std::vector<std::string> prefixes{};
- EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
}
// Test setLocalPrefixes() fails on incorrectly formed input strings.
TEST_P(TetheroffloadAidlGeneralTest, SetLocalPrefixesInvalidFails) {
const std::vector<std::string> prefixes{std::string("192.0.2.0/24"), std::string("invalid")};
- EXPECT_EQ(mOffload->setLocalPrefixes(prefixes).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->setLocalPrefixes(prefixes).getExceptionCode());
}
/*
@@ -389,9 +388,10 @@
TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsInvalidUpstreamIface) {
const std::string upstream("invalid");
ForwardedStats stats;
- EXPECT_TRUE(mOffload->getForwardedStats(upstream, &stats).isOk());
- EXPECT_EQ(stats.rxBytes, 0ULL);
- EXPECT_EQ(stats.txBytes, 0ULL);
+ auto ret = mOffload->getForwardedStats(upstream, &stats);
+ EXPECT_TRUE(ret.isOk()) << ret;
+ EXPECT_EQ(0ULL, stats.rxBytes);
+ EXPECT_EQ(0ULL, stats.txBytes);
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -399,9 +399,10 @@
TEST_P(TetheroffloadAidlGeneralTest, GetForwardedStatsDummyIface) {
const std::string upstream(TEST_IFACE);
ForwardedStats stats;
- EXPECT_TRUE(mOffload->getForwardedStats(upstream, &stats).isOk());
- EXPECT_EQ(stats.rxBytes, 0ULL);
- EXPECT_EQ(stats.txBytes, 0ULL);
+ auto ret = mOffload->getForwardedStats(upstream, &stats);
+ EXPECT_TRUE(ret.isOk()) << ret;
+ EXPECT_EQ(0ULL, stats.rxBytes);
+ EXPECT_EQ(0ULL, stats.txBytes);
}
/*
@@ -413,8 +414,8 @@
const std::string upstream("");
const int64_t warning = 12345LL;
const int64_t limit = 67890LL;
- EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
- AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_UNSUPPORTED_OPERATION)));
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -423,8 +424,8 @@
const std::string upstream(TEST_IFACE);
const int64_t warning = 4000LL;
const int64_t limit = 5000LL;
- EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
- AnyOf(Eq(EX_NONE), Eq(EX_UNSUPPORTED_OPERATION)));
+ auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -433,8 +434,8 @@
const std::string upstream(TEST_IFACE);
const int64_t warning = 0LL;
const int64_t limit = 0LL;
- EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
- AnyOf(Eq(EX_NONE), Eq(EX_UNSUPPORTED_OPERATION)));
+ auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -443,7 +444,8 @@
const std::string upstream(TEST_IFACE);
const int64_t warning = LLONG_MAX;
const int64_t limit = 5000LL;
- EXPECT_TRUE(mOffload->setDataWarningAndLimit(upstream, warning, limit).isOk());
+ auto ret = mOffload->setDataWarningAndLimit(upstream, warning, limit);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test that setDataWarningAndLimit() with negative thresholds fails.
@@ -451,8 +453,8 @@
const std::string upstream(TEST_IFACE);
const int64_t warning = -1LL;
const int64_t limit = -1LL;
- EXPECT_THAT(mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode(),
- AnyOf(Eq(EX_ILLEGAL_ARGUMENT), Eq(EX_UNSUPPORTED_OPERATION)));
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setDataWarningAndLimit(upstream, warning, limit).getExceptionCode());
}
/*
@@ -466,7 +468,8 @@
const std::string v4Addr("");
const std::string v4Gw("");
const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
- EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
+ auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -476,7 +479,8 @@
const std::string v4Addr("");
const std::string v4Gw("");
const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:3")};
- EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
+ auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -486,7 +490,8 @@
const std::string v4Addr("192.0.2.2");
const std::string v4Gw("192.0.2.1");
const std::vector<std::string> v6Gws{};
- EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
+ auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// TEST_IFACE is presumed to exist on the device and be up. No packets
@@ -496,7 +501,8 @@
const std::string v4Addr("192.0.2.2");
const std::string v4Gw("192.0.2.1");
const std::vector<std::string> v6Gws{std::string("fe80::db8:1"), std::string("fe80::db8:2")};
- EXPECT_TRUE(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).isOk());
+ auto ret = mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test that setUpstreamParameters() fails when all parameters are empty.
@@ -505,8 +511,8 @@
const std::string v4Addr("");
const std::string v4Gw("");
const std::vector<std::string> v6Gws{};
- EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
}
// Test that setUpstreamParameters() fails when given empty or non-existent interface names.
@@ -517,8 +523,8 @@
for (const auto& bogus : {"", "invalid"}) {
SCOPED_TRACE(testing::Message() << "upstream: " << bogus);
const std::string iface(bogus);
- EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
}
}
@@ -530,8 +536,8 @@
for (const auto& bogus : {"invalid", "192.0.2"}) {
SCOPED_TRACE(testing::Message() << "v4addr: " << bogus);
const std::string v4Addr(bogus);
- EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
}
}
@@ -543,8 +549,8 @@
for (const auto& bogus : {"invalid", "192.0.2"}) {
SCOPED_TRACE(testing::Message() << "v4gateway: " << bogus);
const std::string v4Gw(bogus);
- EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
}
}
@@ -556,8 +562,8 @@
for (const auto& bogus : {"", "invalid", "fe80::bogus", "192.0.2.66"}) {
SCOPED_TRACE(testing::Message() << "v6gateway: " << bogus);
const std::vector<std::string> v6Gws{std::string("fe80::1"), std::string(bogus)};
- EXPECT_EQ(mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->setUpstreamParameters(iface, v4Addr, v4Gw, v6Gws).getExceptionCode());
}
}
@@ -569,21 +575,23 @@
TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv4) {
const std::string iface("dummy0");
const std::string prefix("192.0.2.0/24");
- EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
+ auto ret = mOffload->addDownstream(iface, prefix);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test addDownstream() works given an IPv6 prefix.
TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamIPv6) {
const std::string iface("dummy0");
const std::string prefix("2001:db8::/64");
- EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
+ auto ret = mOffload->addDownstream(iface, prefix);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test addDownstream() fails given all empty parameters.
TEST_P(TetheroffloadAidlGeneralTest, AddDownstreamEmptyFails) {
const std::string iface("");
const std::string prefix("");
- EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
}
// Test addDownstream() fails given empty or non-existent interface names.
@@ -592,7 +600,7 @@
for (const auto& bogus : {"", "invalid"}) {
SCOPED_TRACE(testing::Message() << "iface: " << bogus);
const std::string iface(bogus);
- EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
}
}
@@ -602,7 +610,7 @@
for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
const std::string prefix(bogus);
- EXPECT_EQ(mOffload->addDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->addDownstream(iface, prefix).getExceptionCode());
}
}
@@ -616,8 +624,10 @@
const std::string prefix("192.0.2.0/24");
// First add the downstream, otherwise removeDownstream logic can reasonably
// return error for downstreams not previously added.
- EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
- EXPECT_TRUE(mOffload->removeDownstream(iface, prefix).isOk());
+ auto ret = mOffload->addDownstream(iface, prefix);
+ EXPECT_TRUE(ret.isOk()) << ret;
+ ret = mOffload->removeDownstream(iface, prefix);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test removeDownstream() works given an IPv6 prefix.
@@ -626,15 +636,17 @@
const std::string prefix("2001:db8::/64");
// First add the downstream, otherwise removeDownstream logic can reasonably
// return error for downstreams not previously added.
- EXPECT_TRUE(mOffload->addDownstream(iface, prefix).isOk());
- EXPECT_TRUE(mOffload->removeDownstream(iface, prefix).isOk());
+ auto ret = mOffload->addDownstream(iface, prefix);
+ EXPECT_TRUE(ret.isOk()) << ret;
+ ret = mOffload->removeDownstream(iface, prefix);
+ EXPECT_TRUE(ret.isOk()) << ret;
}
// Test removeDownstream() fails given all empty parameters.
TEST_P(TetheroffloadAidlGeneralTest, RemoveDownstreamEmptyFails) {
const std::string iface("");
const std::string prefix("");
- EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT, mOffload->removeDownstream(iface, prefix).getExceptionCode());
}
// Test removeDownstream() fails given empty or non-existent interface names.
@@ -643,8 +655,8 @@
for (const auto& bogus : {"", "invalid"}) {
SCOPED_TRACE(testing::Message() << "iface: " << bogus);
const std::string iface(bogus);
- EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->removeDownstream(iface, prefix).getExceptionCode());
}
}
@@ -654,8 +666,8 @@
for (const auto& bogus : {"", "192.0.2/24", "2001:db8/64"}) {
SCOPED_TRACE(testing::Message() << "prefix: " << bogus);
const std::string prefix(bogus);
- EXPECT_EQ(mOffload->removeDownstream(iface, prefix).getExceptionCode(),
- EX_ILLEGAL_ARGUMENT);
+ EXPECT_EQ(EX_ILLEGAL_ARGUMENT,
+ mOffload->removeDownstream(iface, prefix).getExceptionCode());
}
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
index dfd8686..dff3c4c 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
@@ -33,7 +33,7 @@
package android.hardware.thermal;
/* @hide */
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
parcelable CoolingDevice {
android.hardware.thermal.CoolingType type;
String name;
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
index 3bf08bf..ce70ab8 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/Temperature.aidl
@@ -33,7 +33,7 @@
package android.hardware.thermal;
/* @hide */
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
parcelable Temperature {
android.hardware.thermal.TemperatureType type;
String name;
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
index c5ca4b9..a384d19 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureThreshold.aidl
@@ -33,7 +33,7 @@
package android.hardware.thermal;
/* @hide */
-@VintfStability
+@JavaDerive(toString=true) @VintfStability
parcelable TemperatureThreshold {
android.hardware.thermal.TemperatureType type;
String name;
diff --git a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
index 1f2360d..0c5c17d 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
@@ -20,6 +20,7 @@
/* @hide */
@VintfStability
+@JavaDerive(toString=true)
parcelable CoolingDevice {
/**
* This cooling device type, CPU, GPU, BATTERY, and etc.
diff --git a/thermal/aidl/android/hardware/thermal/IThermal.aidl b/thermal/aidl/android/hardware/thermal/IThermal.aidl
index 7c23c17..c94edcd 100644
--- a/thermal/aidl/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/android/hardware/thermal/IThermal.aidl
@@ -36,9 +36,8 @@
* exist on boot. The method always returns and never removes from
* the list such cooling devices.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, getMessage() must be populated with the human-readable
- * error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
CoolingDevice[] getCoolingDevices();
@@ -54,9 +53,8 @@
* exist on boot. The method always returns and never removes from
* the list such cooling devices.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
CoolingDevice[] getCoolingDevicesWithType(in CoolingType type);
@@ -70,9 +68,8 @@
* they go offline, if these devices exist on boot. The method
* always returns and never removes such temperatures.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
Temperature[] getTemperatures();
@@ -88,9 +85,8 @@
* they go offline, if these devices exist on boot. The method
* always returns and never removes such temperatures.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
Temperature[] getTemperaturesWithType(in TemperatureType type);
@@ -110,9 +106,8 @@
* throttling status, use getTemperatures or registerThermalChangedCallback
* and listen to the callback.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
TemperatureThreshold[] getTemperatureThresholds();
@@ -135,9 +130,8 @@
* throttling status, use getTemperatures or registerThermalChangedCallback
* and listen to the callback.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
TemperatureThreshold[] getTemperatureThresholdsWithType(in TemperatureType type);
@@ -152,12 +146,10 @@
* thermal events. if nullptr callback is given, the status code will be
* STATUS_BAD_VALUE and the operation will fail.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message. If callback is given nullptr, the returned status code
- * will be STATUS_BAD_VALUE and the exception will be EX_ILLEGAL_ARGUMENT.
- * if callback is already registered, the returned status code will be
- * STATUS_INVALID_OPERATION, the exception will be EX_ILLEGAL_ARGUMENT.
+ * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+ * getMessage() must be populated with human-readable error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
void registerThermalChangedCallback(in IThermalChangedCallback callback);
@@ -174,12 +166,10 @@
* STATUS_BAD_VALUE and the operation will fail.
* @param type the type to be filtered.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message. If callback is given nullptr, the returned status code
- * will be STATUS_BAD_VALUE and the exception will be EX_ILLEGAL_ARGUMENT.
- * if callback is already registered, the returned status code will be
- * STATUS_INVALID_OPERATION, the exception will be EX_ILLEGAL_ARGUMENT.
+ * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+ * getMessage() must be populated with human-readable error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
void registerThermalChangedCallbackWithType(
in IThermalChangedCallback callback, in TemperatureType type);
@@ -192,12 +182,10 @@
* thermal events. if nullptr callback is given, the status code will be
* STATUS_BAD_VALUE and the operation will fail.
*
- * @throws ScopedAStatus Status of the operation. If status code is not
- * STATUS_OK, the getMessage() must be populated with the human-readable
- * error message. If callback is given nullptr, the returned status code
- * will be STATUS_BAD_VALUE and the exception will be EX_ILLEGAL_ARGUMENT.
- * if callback is not registered, the returned status code will be
- * STATUS_INVALID_OPERATION, the exception will be EX_ILLEGAL_ARGUMENT.
+ * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or not previously registered.
+ * And the getMessage() must be populated with human-readable error message.
+ * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+ * getMessage() must be populated with human-readable error message.
*/
void unregisterThermalChangedCallback(in IThermalChangedCallback callback);
}
diff --git a/thermal/aidl/android/hardware/thermal/Temperature.aidl b/thermal/aidl/android/hardware/thermal/Temperature.aidl
index 281d68d..b3f6700 100644
--- a/thermal/aidl/android/hardware/thermal/Temperature.aidl
+++ b/thermal/aidl/android/hardware/thermal/Temperature.aidl
@@ -21,6 +21,7 @@
/* @hide */
@VintfStability
+@JavaDerive(toString=true)
parcelable Temperature {
/**
* This temperature's type.
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl b/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
index 0714c82..94991ae 100644
--- a/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
+++ b/thermal/aidl/android/hardware/thermal/TemperatureThreshold.aidl
@@ -20,6 +20,7 @@
/* @hide */
@VintfStability
+@JavaDerive(toString=true)
parcelable TemperatureThreshold {
/**
* This temperature's type.
diff --git a/thermal/aidl/default/Thermal.cpp b/thermal/aidl/default/Thermal.cpp
index 5771e0e..f643d22 100644
--- a/thermal/aidl/default/Thermal.cpp
+++ b/thermal/aidl/default/Thermal.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "thermal_service_example"
+
#include "Thermal.h"
#include <android-base/logging.h>
@@ -22,6 +24,18 @@
using ndk::ScopedAStatus;
+namespace {
+
+bool interfacesEqual(const std::shared_ptr<::ndk::ICInterface>& left,
+ const std::shared_ptr<::ndk::ICInterface>& right) {
+ if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
+ return left == right;
+ }
+ return left->asBinder() == right->asBinder();
+}
+
+} // namespace
+
ScopedAStatus Thermal::getCoolingDevices(std::vector<CoolingDevice>* /* out_devices */) {
LOG(VERBOSE) << __func__;
return ScopedAStatus::ok();
@@ -61,12 +75,20 @@
const std::shared_ptr<IThermalChangedCallback>& in_callback) {
LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
if (in_callback == nullptr) {
- return ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid nullptr callback");
}
- if (mCallbacks.find(in_callback) != mCallbacks.end()) {
- return ScopedAStatus::fromStatus(STATUS_INVALID_OPERATION);
+ {
+ std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+ if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+ [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+ return interfacesEqual(c, in_callback);
+ })) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Callback already registered");
+ }
+ thermal_callbacks_.push_back(in_callback);
}
- mCallbacks.insert(in_callback);
return ScopedAStatus::ok();
}
@@ -75,26 +97,48 @@
LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback
<< ", TemperatureType: " << static_cast<int32_t>(in_type);
if (in_callback == nullptr) {
- return ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid nullptr callback");
}
- if (mCallbacks.find(in_callback) != mCallbacks.end()) {
- return ScopedAStatus::fromStatus(STATUS_INVALID_OPERATION);
+ {
+ std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+ if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+ [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+ return interfacesEqual(c, in_callback);
+ })) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Callback already registered");
+ }
+ thermal_callbacks_.push_back(in_callback);
}
- mCallbacks.insert(in_callback);
return ScopedAStatus::ok();
}
ScopedAStatus Thermal::unregisterThermalChangedCallback(
const std::shared_ptr<IThermalChangedCallback>& in_callback) {
LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
- bool found = false;
if (in_callback == nullptr) {
- return ScopedAStatus::fromStatus(STATUS_BAD_VALUE);
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Invalid nullptr callback");
}
- if (mCallbacks.find(in_callback) == mCallbacks.end()) {
- return ScopedAStatus::fromStatus(STATUS_INVALID_OPERATION);
+ {
+ std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
+ bool removed = false;
+ thermal_callbacks_.erase(
+ std::remove_if(thermal_callbacks_.begin(), thermal_callbacks_.end(),
+ [&](const std::shared_ptr<IThermalChangedCallback>& c) {
+ if (interfacesEqual(c, in_callback)) {
+ removed = true;
+ return true;
+ }
+ return false;
+ }),
+ thermal_callbacks_.end());
+ if (!removed) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "Callback wasn't registered");
+ }
}
- mCallbacks.erase(in_callback);
return ScopedAStatus::ok();
}
diff --git a/thermal/aidl/default/Thermal.h b/thermal/aidl/default/Thermal.h
index 788af4a..8885e63 100644
--- a/thermal/aidl/default/Thermal.h
+++ b/thermal/aidl/default/Thermal.h
@@ -54,7 +54,8 @@
const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
private:
- std::set<std::shared_ptr<IThermalChangedCallback>> mCallbacks;
+ std::mutex thermal_callback_mutex_;
+ std::vector<std::shared_ptr<IThermalChangedCallback>> thermal_callbacks_;
};
} // namespace example
diff --git a/thermal/aidl/default/main.cpp b/thermal/aidl/default/main.cpp
index 61d8ad0..9f4ddb8 100644
--- a/thermal/aidl/default/main.cpp
+++ b/thermal/aidl/default/main.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "thermal_service_example"
+
#include "Thermal.h"
#include <android-base/logging.h>
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index b93250e..73c5dd2 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -95,21 +95,21 @@
mThermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
ASSERT_NE(mThermalCallback, nullptr);
- auto ret = mThermal->registerThermalChangedCallback(mThermalCallback);
- ASSERT_TRUE(ret.isOk());
+ auto status = mThermal->registerThermalChangedCallback(mThermalCallback);
+ ASSERT_TRUE(status.isOk());
// Expect to fail if register again
- ret = mThermal->registerThermalChangedCallback(mThermalCallback);
- ASSERT_FALSE(ret.isOk());
- ASSERT_TRUE(ret.getStatus() == STATUS_INVALID_OPERATION);
+ status = mThermal->registerThermalChangedCallback(mThermalCallback);
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
}
void TearDown() override {
- auto ret = mThermal->unregisterThermalChangedCallback(mThermalCallback);
- ASSERT_TRUE(ret.isOk());
+ auto status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+ ASSERT_TRUE(status.isOk());
// Expect to fail if unregister again
- ret = mThermal->unregisterThermalChangedCallback(mThermalCallback);
- ASSERT_FALSE(ret.isOk());
- ASSERT_TRUE(ret.getStatus() == STATUS_INVALID_OPERATION);
+ status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
+ ASSERT_FALSE(status.isOk());
+ ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
}
protected:
diff --git a/tv/hdmi/cec/aidl/OWNERS b/tv/hdmi/OWNERS
similarity index 100%
rename from tv/hdmi/cec/aidl/OWNERS
rename to tv/hdmi/OWNERS
diff --git a/tv/hdmi/connection/aidl/OWNERS b/tv/hdmi/connection/aidl/OWNERS
deleted file mode 100644
index d9c6783..0000000
--- a/tv/hdmi/connection/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 826094
-include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/tv/hdmi/earc/aidl/OWNERS b/tv/hdmi/earc/aidl/OWNERS
deleted file mode 100644
index d9c6783..0000000
--- a/tv/hdmi/earc/aidl/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 826094
-include platform/frameworks/base:/core/java/android/hardware/hdmi/OWNERS
\ No newline at end of file
diff --git a/usb/gadget/aidl/default/UsbGadget.cpp b/usb/gadget/aidl/default/UsbGadget.cpp
index 72cf681..51f7f5b 100644
--- a/usb/gadget/aidl/default/UsbGadget.cpp
+++ b/usb/gadget/aidl/default/UsbGadget.cpp
@@ -91,6 +91,9 @@
ScopedAStatus UsbGadget::getCurrentUsbFunctions(const shared_ptr<IUsbGadgetCallback>& callback,
int64_t in_transactionId) {
+ if (callback == nullptr) {
+ return ScopedAStatus::fromExceptionCode(EX_NULL_POINTER);
+ }
ScopedAStatus ret = callback->getCurrentUsbFunctionsCb(
mCurrentUsbFunctions,
mCurrentUsbFunctionsApplied ? Status::FUNCTIONS_APPLIED : Status::FUNCTIONS_NOT_APPLIED,
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index 7dc2b7f..3e71913 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -18,7 +18,11 @@
backend: {
java: {
sdk_version: "module_Tiramisu",
- enabled: false,
+ enabled: true,
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.uwb",
+ ],
},
ndk: {
apex_available: [
@@ -72,6 +76,11 @@
version: "1",
imports: [],
},
+ {
+ version: "2",
+ imports: [],
+ },
+
],
}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash
new file mode 100644
index 0000000..856fa7c
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/.hash
@@ -0,0 +1 @@
+39791e3a4bb9892a340e94e44860048624d2f66e
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
new file mode 100644
index 0000000..e2c06e5
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-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.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorCapabilityTlvTypes {
+ SUPPORTED_POWER_STATS_QUERY = 192,
+ CCC_SUPPORTED_CHAPS_PER_SLOT = 160,
+ CCC_SUPPORTED_SYNC_CODES = 161,
+ CCC_SUPPORTED_HOPPING_CONFIG_MODES_AND_SEQUENCES = 162,
+ CCC_SUPPORTED_CHANNELS = 163,
+ CCC_SUPPORTED_VERSIONS = 164,
+ CCC_SUPPORTED_UWB_CONFIGS = 165,
+ CCC_SUPPORTED_PULSE_SHAPE_COMBOS = 166,
+ CCC_SUPPORTED_RAN_MULTIPLIER = 167,
+ CCC_SUPPORTED_MAX_RANGING_SESSION_NUMBER = 168,
+ SUPPORTED_AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 227,
+ SUPPORTED_MIN_RANGING_INTERVAL_MS = 228,
+ SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
+ SUPPORTED_RSSI_REPORTING = 230,
+ SUPPORTED_DIAGNOSTICS = 231,
+ SUPPORTED_MIN_SLOT_DURATION_MS = 232,
+ SUPPORTED_MAX_RANGING_SESSION_NUMBER = 233,
+ SUPPORTED_CHANNELS_AOA = 234,
+}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
similarity index 64%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
index 50a5528..0e33f70 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvValues.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,26 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="long") @VintfStability
+enum UwbVendorCapabilityTlvValues {
+ UWB_CONFIG_0 = 0,
+ UWB_CONFIG_1 = 1,
+ PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE = 0,
+ PULSE_SHAPE_PRECURSOR_FREE = 1,
+ PULSE_SHAPE_PRECURSOR_FREE_SPECIAL = 2,
+ CHAPS_PER_SLOT_3 = 1,
+ CHAPS_PER_SLOT_4 = 2,
+ CHAPS_PER_SLOT_6 = 4,
+ CHAPS_PER_SLOT_8 = 8,
+ CHAPS_PER_SLOT_9 = 16,
+ CHAPS_PER_SLOT_12 = 32,
+ CHAPS_PER_SLOT_24 = 64,
+ HOPPING_SEQUENCE_DEFAULT = 16,
+ HOPPING_SEQUENCE_AES = 8,
+ HOPPING_CONFIG_MODE_NONE = 128,
+ HOPPING_CONFIG_MODE_CONTINUOUS = 64,
+ HOPPING_CONFIG_MODE_ADAPTIVE = 32,
+ CCC_CHANNEL_5 = 1,
+ CCC_CHANNEL_9 = 2,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
similarity index 73%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
index 50a5528..fbcfbff 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGidAndroidOids.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,10 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGidAndroidOids {
+ ANDROID_GET_POWER_STATS = 0,
+ ANDROID_SET_COUNTRY_CODE = 1,
+ ANDROID_RANGE_DIAGNOSTICS = 2,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
similarity index 73%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
index 50a5528..5515c67 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorGids.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,8 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorGids {
+ ANDROID = 12,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
similarity index 76%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
index 50a5528..dc2252b 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -2,10 +2,10 @@
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,8 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorReasonCodes {
+ REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 128,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
similarity index 70%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
index 50a5528..8413f06 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvTypes.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,18 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorSessionAppConfigTlvTypes {
+ CCC_HOP_MODE_KEY = 160,
+ CCC_UWB_TIME0 = 161,
+ CCC_RANGING_PROTOCOL_VER = 163,
+ CCC_UWB_CONFIG_ID = 164,
+ CCC_PULSESHAPE_COMBO = 165,
+ CCC_URSK_TTL = 166,
+ NB_OF_RANGE_MEASUREMENTS = 227,
+ NB_OF_AZIMUTH_MEASUREMENTS = 228,
+ NB_OF_ELEVATION_MEASUREMENTS = 229,
+ ENABLE_DIAGNOSTICS = 232,
+ DIAGRAMS_FRAME_REPORTS_FIELDS = 233,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
similarity index 73%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
index 50a5528..a7f487b 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionAppConfigTlvValues.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,8 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorSessionAppConfigTlvValues {
+ AOA_RESULT_REQ_ANTENNA_INTERLEAVING = 240,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
similarity index 73%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
index 50a5528..30a0a1b 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorSessionInitSessionType.aidl
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,8 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorSessionInitSessionType {
+ CCC = 160,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
similarity index 76%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
index 50a5528..2f534df 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/2/android/hardware/uwb/fira_android/UwbVendorStatusCodes.aidl
@@ -2,10 +2,10 @@
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,9 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="byte") @VintfStability
+enum UwbVendorStatusCodes {
+ STATUS_ERROR_CCC_SE_BUSY = 80,
+ STATUS_ERROR_CCC_LIFECYCLE = 81,
}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index b9ac7b9..e2c06e5 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -49,6 +49,7 @@
SUPPORTED_RANGE_DATA_NTF_CONFIG = 229,
SUPPORTED_RSSI_REPORTING = 230,
SUPPORTED_DIAGNOSTICS = 231,
- SUPPORTED_MIN_SLOT_DURATION = 232,
+ SUPPORTED_MIN_SLOT_DURATION_MS = 232,
SUPPORTED_MAX_RANGING_SESSION_NUMBER = 233,
+ SUPPORTED_CHANNELS_AOA = 234,
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
similarity index 76%
copy from audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
copy to uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
index 50a5528..dc2252b 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/MicrophoneDynamicInfo.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -2,10 +2,10 @@
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
+ * 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
+ * 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,
@@ -31,15 +31,8 @@
// 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.audio.core;
-@JavaDerive(equals=true, toString=true) @VintfStability
-parcelable MicrophoneDynamicInfo {
- @utf8InCpp String id;
- android.hardware.audio.core.MicrophoneDynamicInfo.ChannelMapping[] channelMapping;
- @Backing(type="int") @VintfStability
- enum ChannelMapping {
- UNUSED = 0,
- DIRECT = 1,
- PROCESSED = 2,
- }
+package android.hardware.uwb.fira_android;
+@Backing(type="int") @VintfStability
+enum UwbVendorReasonCodes {
+ REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 128,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
index a3bb7a6..bf59318 100644
--- a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorCapabilityTlvTypes.aidl
@@ -188,10 +188,24 @@
/**
* 4 byte value to indicate supported min slot duration in ms.
*/
- SUPPORTED_MIN_SLOT_DURATION = 0xE8,
+ SUPPORTED_MIN_SLOT_DURATION_MS = 0xE8,
/**
* Int value to indicate supported max number of fira ranging sessions
*/
SUPPORTED_MAX_RANGING_SESSION_NUMBER = 0xE9,
+
+ /**
+ * 2 byte bitmask to indicate the channels that support AoA.
+ * Each "1" in this bitmap corresponds to a specific UWB channel where:
+ * 0x01 = "Channel 5",
+ * 0x02 = "Channel 6",
+ * 0x04 = "Channel 8",
+ * 0x08 = "Channel 9",
+ * 0x10 = "Channel 10",
+ * 0x20 = "Channel 12",
+ * 0x40 = "Channel 13",
+ * 0x80 = "Channel 14"
+ */
+ SUPPORTED_CHANNELS_AOA = 0xEA,
}
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
new file mode 100644
index 0000000..ae203a3
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbVendorReasonCodes.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * You may not use this file except in compliance with the License.
+ * 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.uwb.fira_android;
+
+/**
+ * Android specific vendor reason codes should be defined here.
+ *
+ */
+@VintfStability
+@Backing(type="int")
+enum UwbVendorReasonCodes {
+ /**
+ * Use values from the vendor specific reason code range: 0x80 – 0xFF defined in Table 16 of
+ * UCI specification.
+ */
+
+ /** Fira specific */
+ /** The channel requested is not available for AoA */
+ REASON_ERROR_INVALID_CHANNEL_WITH_AOA = 0x80,
+}