Merge "vibrator: clean OWNERS"
diff --git a/audio/OWNERS b/audio/OWNERS
index ede448c..3671685 100644
--- a/audio/OWNERS
+++ b/audio/OWNERS
@@ -1 +1,4 @@
-per-file README.md = elaurent@google.com,mnaganov@google.com
+# Bug component: 48436
+
+elaurent@google.com
+mnaganov@google.com
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index 340cdb5..e69306e 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -112,9 +112,9 @@
"android/hardware/audio/core/AudioMode.aidl",
"android/hardware/audio/core/AudioPatch.aidl",
"android/hardware/audio/core/AudioRoute.aidl",
+ "android/hardware/audio/core/IBluetooth.aidl",
"android/hardware/audio/core/IConfig.aidl",
"android/hardware/audio/core/IModule.aidl",
- "android/hardware/audio/core/ISoundDose.aidl",
"android/hardware/audio/core/IStreamCallback.aidl",
"android/hardware/audio/core/IStreamCommon.aidl",
"android/hardware/audio/core/IStreamIn.aidl",
@@ -133,6 +133,7 @@
"android.hardware.common-V2",
"android.hardware.common.fmq-V1",
"android.hardware.audio.common-V1",
+ "android.hardware.audio.core.sounddose-V1",
"android.hardware.audio.effect-V1",
"android.media.audio.common.types-V2",
],
@@ -178,7 +179,7 @@
"android.hardware.audio_defaults",
],
srcs: [
- "android/hardware/audio/core/ISoundDose.aidl",
+ "android/hardware/audio/core/sounddose/ISoundDose.aidl",
],
imports: [
"android.media.audio.common.types-V2",
diff --git a/audio/aidl/OWNERS b/audio/aidl/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/aidl/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
similarity index 88%
rename from audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
rename to audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
index bc010ca..3b5d2d0 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -31,18 +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;
+package android.hardware.audio.core.sounddose;
@VintfStability
interface ISoundDose {
void setOutputRs2(float rs2ValueDbA);
float getOutputRs2();
- void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
+ void registerSoundDoseCallback(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback callback);
const int DEFAULT_MAX_RS2 = 100;
const int MIN_RS2 = 80;
@VintfStability
interface IHalSoundDoseCallback {
oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
- oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+ oneway void onNewMelValues(in android.hardware.audio.core.sounddose.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
@VintfStability
parcelable MelRecord {
float[] melValues;
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
similarity index 62%
copy from audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
copy to audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
index bc010ca..289c0c2 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IBluetooth.aidl
@@ -33,20 +33,29 @@
package android.hardware.audio.core;
@VintfStability
-interface ISoundDose {
- void setOutputRs2(float rs2ValueDbA);
- float getOutputRs2();
- void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
- const int DEFAULT_MAX_RS2 = 100;
- const int MIN_RS2 = 80;
- @VintfStability
- interface IHalSoundDoseCallback {
- oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
- oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
+interface IBluetooth {
+ android.hardware.audio.core.IBluetooth.ScoConfig setScoConfig(in android.hardware.audio.core.IBluetooth.ScoConfig config);
+ android.hardware.audio.core.IBluetooth.HfpConfig setHfpConfig(in android.hardware.audio.core.IBluetooth.HfpConfig config);
+ @JavaDerive(equals=true, toString=true) @VintfStability
+ parcelable ScoConfig {
+ @nullable android.media.audio.common.Boolean isEnabled;
+ @nullable android.media.audio.common.Boolean isNrecEnabled;
+ android.hardware.audio.core.IBluetooth.ScoConfig.Mode mode = android.hardware.audio.core.IBluetooth.ScoConfig.Mode.UNSPECIFIED;
+ @nullable @utf8InCpp String debugName;
@VintfStability
- parcelable MelRecord {
- float[] melValues;
- long timestamp;
+ enum Mode {
+ UNSPECIFIED = 0,
+ SCO = 1,
+ SCO_WB = 2,
+ SCO_SWB = 3,
}
}
+ @JavaDerive(equals=true, toString=true) @VintfStability
+ parcelable HfpConfig {
+ @nullable android.media.audio.common.Boolean isEnabled;
+ @nullable android.media.audio.common.Int sampleRate;
+ @nullable android.media.audio.common.Float volume;
+ const int VOLUME_MIN = 0;
+ const int VOLUME_MAX = 1;
+ }
}
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 6a10295..4486b66 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
@@ -36,6 +36,7 @@
interface IModule {
void setModuleDebug(in android.hardware.audio.core.ModuleDebug debug);
@nullable android.hardware.audio.core.ITelephony getTelephony();
+ @nullable android.hardware.audio.core.IBluetooth getBluetooth();
android.media.audio.common.AudioPort connectExternalDevice(in android.media.audio.common.AudioPort templateIdAndAdditionalData);
void disconnectExternalDevice(int portId);
android.hardware.audio.core.AudioPatch[] getAudioPatches();
@@ -61,7 +62,7 @@
void updateAudioMode(android.hardware.audio.core.AudioMode mode);
void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation);
void updateScreenState(boolean isTurnedOn);
- @nullable android.hardware.audio.core.ISoundDose getSoundDose();
+ @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose();
int generateHwAvSyncId();
android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids);
void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async);
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl
deleted file mode 100644
index bc010ca..0000000
--- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/ISoundDose.aidl
+++ /dev/null
@@ -1,52 +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;
-@VintfStability
-interface ISoundDose {
- void setOutputRs2(float rs2ValueDbA);
- float getOutputRs2();
- void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
- const int DEFAULT_MAX_RS2 = 100;
- const int MIN_RS2 = 80;
- @VintfStability
- interface IHalSoundDoseCallback {
- oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
- oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
- @VintfStability
- parcelable MelRecord {
- float[] melValues;
- long timestamp;
- }
- }
-}
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 68f1ff3..1041943 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
@@ -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);
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 a8c58c1..77063df 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
@@ -36,4 +36,21 @@
interface ITelephony {
android.hardware.audio.core.AudioMode[] getSupportedAudioModes();
void switchAudioMode(android.hardware.audio.core.AudioMode mode);
+ android.hardware.audio.core.ITelephony.TelecomConfig setTelecomConfig(in android.hardware.audio.core.ITelephony.TelecomConfig config);
+ @JavaDerive(equals=true, toString=true) @VintfStability
+ parcelable TelecomConfig {
+ @nullable android.media.audio.common.Float voiceVolume;
+ android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode ttyMode = android.hardware.audio.core.ITelephony.TelecomConfig.TtyMode.UNSPECIFIED;
+ @nullable android.media.audio.common.Boolean isHacEnabled;
+ const int VOICE_VOLUME_MIN = 0;
+ const int VOICE_VOLUME_MAX = 1;
+ @Backing(type="int") @VintfStability
+ enum TtyMode {
+ UNSPECIFIED = (-1),
+ OFF = 0,
+ FULL = 1,
+ HCO = 2,
+ VCO = 3,
+ }
+ }
}
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
index 68c7f88..b77afe3 100644
--- 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
@@ -37,15 +37,15 @@
@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 = -1;
- int indexInTheGroup = -1;
+ 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;
+ const int GROUP_UNKNOWN = (-1);
+ const int INDEX_IN_THE_GROUP_UNKNOWN = (-1);
@Backing(type="int") @VintfStability
enum Location {
UNKNOWN = 0,
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 3a4271b..a65d7b7 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);
@FixedSize @VintfStability
parcelable Position {
- long frames = -1;
- long timeNs = -1;
- const long UNKNOWN = -1;
+ long frames = UNKNOWN;
+ long timeNs = UNKNOWN;
+ const long UNKNOWN = (-1);
}
@Backing(type="int") @VintfStability
enum State {
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 09ad015..f8baa2a 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
@@ -36,8 +36,6 @@
union BassBoost {
android.hardware.audio.effect.VendorExtension vendor;
int strengthPm;
- const int MIN_PER_MILLE_STRENGTH = 0;
- const int MAX_PER_MILLE_STRENGTH = 1000;
@VintfStability
union Id {
int vendorExtensionTag;
@@ -46,6 +44,7 @@
@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/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
index 40a8d72..959594b 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
@@ -35,7 +35,7 @@
@VintfStability
union HapticGenerator {
android.hardware.audio.effect.VendorExtension vendorExtension;
- android.hardware.audio.effect.HapticGenerator.HapticScale hapticScale;
+ android.hardware.audio.effect.HapticGenerator.HapticScale[] hapticScales;
android.hardware.audio.effect.HapticGenerator.VibratorInformation vibratorInfo;
@VintfStability
union Id {
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 deaff90..9fdd692 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,8 +36,6 @@
union Virtualizer {
android.hardware.audio.effect.VendorExtension vendor;
int strengthPm;
- const int MIN_PER_MILLE_STRENGTH = 0;
- const int MAX_PER_MILLE_STRENGTH = 1000;
@VintfStability
union Id {
int vendorExtensionTag;
@@ -46,6 +44,7 @@
@VintfStability
parcelable Capability {
android.hardware.audio.effect.VendorExtension extension;
+ int maxStrengthPm;
boolean strengthSupported;
}
}
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 ccd32e8..6259cfb 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
@@ -37,9 +37,6 @@
android.hardware.audio.effect.VendorExtension vendor;
int levelDb;
boolean mute;
- // TODO(b/263416041) Move to Capability
- const int MIN_LEVEL_DB = -9600;
- const int MAX_LEVEL_DB = 0;
@VintfStability
union Id {
int vendorExtensionTag;
@@ -48,6 +45,7 @@
@VintfStability
parcelable Capability {
android.hardware.audio.effect.VendorExtension extension;
- int maxLevel;
+ int minLevelDb;
+ int maxLevelDb;
}
}
diff --git a/audio/aidl/android/hardware/audio/core/IBluetooth.aidl b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
new file mode 100644
index 0000000..21ac8e2
--- /dev/null
+++ b/audio/aidl/android/hardware/audio/core/IBluetooth.aidl
@@ -0,0 +1,127 @@
+/*
+ * 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.Boolean;
+import android.media.audio.common.Float;
+import android.media.audio.common.Int;
+
+/**
+ * An instance of IBluetooth manages settings for the Hands-Free Profile (HFP)
+ * and the SCO Link. This interface is optional to implement and provide by the
+ * vendor. It needs to be provided only if the device actually supports BT SCO
+ * or HFP.
+ */
+@VintfStability
+interface IBluetooth {
+ @JavaDerive(equals=true, toString=true)
+ @VintfStability
+ parcelable ScoConfig {
+ /**
+ * Whether BT SCO is enabled. The client might need to disable it
+ * when another profile (for example, A2DP) is activated.
+ */
+ @nullable Boolean isEnabled;
+ /**
+ * Whether BT SCO Noise Reduction and Echo Cancellation are enabled.
+ */
+ @nullable Boolean isNrecEnabled;
+ @VintfStability enum Mode { UNSPECIFIED, SCO, SCO_WB, SCO_SWB }
+ /**
+ * If set, specifies the SCO mode to use:
+ * regular, wide band (WB), or super wide band (SWB).
+ */
+ Mode mode = Mode.UNSPECIFIED;
+ /**
+ * The name of the BT SCO headset used for debugging purposes. Can be empty.
+ */
+ @nullable @utf8InCpp String debugName;
+ }
+
+ /**
+ * Set the configuration of Bluetooth SCO.
+ *
+ * In the provided parcelable, the client sets zero, one or more parameters
+ * which have to be updated on the HAL side. The parameters that are left
+ * unset must retain their current values. It is allowed to change
+ * parameters while the SCO profile is disabled (isEnabled.value == false).
+ *
+ * In the returned parcelable, all parameter fields known to the HAL module
+ * must be populated to their current values. If the SCO profile is
+ * currently disabled (isEnabled.value == false), the parameters must
+ * reflect the last values that were in use.
+ *
+ * The client can pass an uninitialized parcelable in order to retrieve the
+ * current configuration.
+ *
+ * @return The current configuration (after update). All fields known to
+ * the HAL must be populated.
+ * @param config The configuration to set. Any number of fields may be left
+ * uninitialized.
+ * @throws EX_UNSUPPORTED_OPERATION If BT SCO is not supported.
+ * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+ * values is invalid.
+ */
+ ScoConfig setScoConfig(in ScoConfig config);
+
+ @JavaDerive(equals=true, toString=true)
+ @VintfStability
+ parcelable HfpConfig {
+ /**
+ * Whether BT HFP is enabled.
+ */
+ @nullable Boolean isEnabled;
+ /**
+ * The sample rate of BT HFP, in Hertz. Must be a positive number.
+ */
+ @nullable Int sampleRate;
+
+ const int VOLUME_MIN = 0;
+ const int VOLUME_MAX = 1;
+ /**
+ * The output volume of BT HFP. 1.0f means unity gain, 0.0f is muted,
+ * see VOLUME_* constants;
+ */
+ @nullable Float volume;
+ }
+
+ /**
+ * Set the configuration of Bluetooth HFP.
+ *
+ * In the provided parcelable, the client sets zero, one or more parameters
+ * which have to be updated on the HAL side. The parameters that are left
+ * unset must retain their current values. It is allowed to change
+ * parameters while the HFP profile is disabled (isEnabled.value == false).
+ *
+ * In the returned parcelable, all parameter fields known to the HAL module
+ * must be populated to their current values. If the HFP profile is
+ * currently disabled (isEnabled.value == false), the parameters must
+ * reflect the last values that were in use.
+ *
+ * The client can pass an uninitialized parcelable in order to retrieve the
+ * current configuration.
+ *
+ * @return The current configuration (after update). All fields known to
+ * the HAL must be populated.
+ * @param config The configuration to set. Any number of fields may be left
+ * uninitialized.
+ * @throws EX_UNSUPPORTED_OPERATION If BT HFP is not supported.
+ * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+ * values is invalid.
+ */
+ HfpConfig setHfpConfig(in HfpConfig config);
+}
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index f4ee1f3..7bc1b9c 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -21,7 +21,7 @@
import android.hardware.audio.core.AudioMode;
import android.hardware.audio.core.AudioPatch;
import android.hardware.audio.core.AudioRoute;
-import android.hardware.audio.core.ISoundDose;
+import android.hardware.audio.core.IBluetooth;
import android.hardware.audio.core.IStreamCallback;
import android.hardware.audio.core.IStreamIn;
import android.hardware.audio.core.IStreamOut;
@@ -31,6 +31,7 @@
import android.hardware.audio.core.ModuleDebug;
import android.hardware.audio.core.StreamDescriptor;
import android.hardware.audio.core.VendorParameter;
+import android.hardware.audio.core.sounddose.ISoundDose;
import android.hardware.audio.effect.IEffect;
import android.media.audio.common.AudioOffloadInfo;
import android.media.audio.common.AudioPort;
@@ -86,6 +87,20 @@
@nullable ITelephony getTelephony();
/**
+ * Retrieve the interface to control Bluetooth SCO and HFP.
+ *
+ * If the HAL module supports either the SCO Link or Hands-Free Profile
+ * functionality (or both) for Bluetooth, it must return an instance of the
+ * IBluetooth interface. The same instance must be returned during the
+ * lifetime of the HAL module. If the HAL module does not support BT SCO and
+ * HFP, a null must be returned, without throwing any errors.
+ *
+ * @return An instance of the IBluetooth interface implementation.
+ * @throws EX_ILLEGAL_STATE If there was an error creating an instance.
+ */
+ @nullable IBluetooth getBluetooth();
+
+ /**
* Set a device port of an external device into connected state.
*
* This method is used to inform the HAL module that an external device has
diff --git a/audio/aidl/android/hardware/audio/core/ITelephony.aidl b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
index a872c7c..a817032 100644
--- a/audio/aidl/android/hardware/audio/core/ITelephony.aidl
+++ b/audio/aidl/android/hardware/audio/core/ITelephony.aidl
@@ -17,6 +17,8 @@
package android.hardware.audio.core;
import android.hardware.audio.core.AudioMode;
+import android.media.audio.common.Boolean;
+import android.media.audio.common.Float;
/**
* An instance of ITelephony manages settings which are specific to voice calls
@@ -53,4 +55,75 @@
* @throws EX_ILLEGAL_STATE If there was an error during switching.
*/
void switchAudioMode(AudioMode mode);
+
+ @JavaDerive(equals=true, toString=true)
+ @VintfStability
+ parcelable TelecomConfig {
+ const int VOICE_VOLUME_MIN = 0;
+ const int VOICE_VOLUME_MAX = 1;
+ /**
+ * Volume of a voice call. 1.0f means unity gain, 0.0f is muted,
+ * see VOLUME_* constants.
+ */
+ @nullable Float voiceVolume;
+ /**
+ * The current mode of teletypewritter (TTY).
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum TtyMode {
+ /**
+ * The default uninitialized value.
+ */
+ UNSPECIFIED = -1,
+ /**
+ * TTY mode is off.
+ */
+ OFF = 0,
+ /**
+ * TTY mode is on. The speaker is off and the microphone is muted. The
+ * user will communicate with the remote party by sending and receiving
+ * text messages.
+ */
+ FULL = 1,
+ /**
+ * TTY mode is in hearing carryover mode (HCO). The microphone is muted
+ * but the speaker is on. The user will communicate with the remote
+ * party by sending text messages and hearing an audible reply.
+ */
+ HCO = 2,
+ /**
+ * TTY mode is in voice carryover mode (VCO). The speaker is off but the
+ * microphone is still on. User will communicate with the remote party
+ * by speaking and receiving text message replies.
+ */
+ VCO = 3,
+ }
+ TtyMode ttyMode = TtyMode.UNSPECIFIED;
+ /**
+ * Whether Hearing Aid Compatibility - Telecoil (HAC-T) mode is enabled.
+ */
+ @nullable Boolean isHacEnabled;
+ }
+
+ /**
+ * Set the configuration of the telephony audio.
+ *
+ * In the provided parcelable, the client sets zero, one or more parameters
+ * which have to be updated on the HAL side. The parameters that are left
+ * unset must retain their current values.
+ *
+ * In the returned parcelable, all parameter fields known to the HAL module
+ * must be populated to their current values.The client can pass an
+ * uninitialized parcelable in order to retrieve the current configuration.
+ *
+ * @return The current configuration (after update). All fields known to
+ * the HAL must be populated.
+ * @param config The configuration to set. Any number of fields may be left
+ * uninitialized.
+ * @throws EX_UNSUPPORTED_OPERATION If telephony is not supported.
+ * @throws EX_ILLEGAL_ARGUMENT If the requested combination of parameter
+ * values is invalid.
+ */
+ TelecomConfig setTelecomConfig(in TelecomConfig config);
}
diff --git a/audio/aidl/android/hardware/audio/core/ISoundDose.aidl b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
similarity index 98%
rename from audio/aidl/android/hardware/audio/core/ISoundDose.aidl
rename to audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
index 89fd69b..953ab62 100644
--- a/audio/aidl/android/hardware/audio/core/ISoundDose.aidl
+++ b/audio/aidl/android/hardware/audio/core/sounddose/ISoundDose.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.hardware.audio.core;
+package android.hardware.audio.core.sounddose;
import android.media.audio.common.AudioDevice;
diff --git a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
index 9e5d8aa..6a94242 100644
--- a/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
+++ b/audio/aidl/android/hardware/audio/effect/BassBoost.aidl
@@ -52,6 +52,10 @@
*/
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.
*/
@@ -59,23 +63,14 @@
}
/**
- * Minimal possible per mille strength.
- */
- const int MIN_PER_MILLE_STRENGTH = 0;
-
- /**
- * Maximum possible per mille strength.
- */
- const int MAX_PER_MILLE_STRENGTH = 1000;
-
- /**
* 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 valid range for strength is [0, 1000].
+ * 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/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
index 944155f..3063ee3 100644
--- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -90,6 +90,6 @@
float maxAmplitude;
}
- HapticScale hapticScale;
+ HapticScale[] hapticScales;
VibratorInformation vibratorInfo;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
index 90ec6f8..5f385a6 100644
--- a/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Virtualizer.aidl
@@ -53,6 +53,10 @@
*/
VendorExtension 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 always return EX_ILLEGAL_ARGUMENT.
*/
@@ -60,23 +64,14 @@
}
/**
- * Minimal possible per mille strength.
- */
- const int MIN_PER_MILLE_STRENGTH = 0;
-
- /**
- * Maximum possible per mille strength.
- */
- const int MAX_PER_MILLE_STRENGTH = 1000;
-
- /**
* The per mille strength of the virtualizer 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 valid range for strength is [0, 1000].
+ * 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/Volume.aidl b/audio/aidl/android/hardware/audio/effect/Volume.aidl
index a9f8371..5033881 100644
--- a/audio/aidl/android/hardware/audio/effect/Volume.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Volume.aidl
@@ -52,25 +52,18 @@
VendorExtension extension;
/**
- * Volume strength supported in dB.
+ * Minimum Volume level supported in dB.
*/
- int maxLevel;
+ int minLevelDb;
+
+ /**
+ * Maximum Volume level supported in dB.
+ */
+ int maxLevelDb;
}
- // TODO(b/263416041) Move to Capability
/**
- * Minimal level in dB.
- */
- const int MIN_LEVEL_DB = -9600;
-
- /**
- * Maximum level in dB.
- */
- const int MAX_LEVEL_DB = 0;
-
- /**
- /**
- * Current level in dB.
+ * Current level in dB with supported minimum and maximum level specified in capability.
*/
int levelDb;
/**
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 7a1f7cd..6f23636 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -62,6 +62,7 @@
export_include_dirs: ["include"],
srcs: [
"AudioPolicyConfigXmlConverter.cpp",
+ "Bluetooth.cpp",
"Config.cpp",
"Configuration.cpp",
"EngineConfigXmlConverter.cpp",
@@ -95,6 +96,7 @@
defaults: [
"aidlaudioservice_defaults",
"latest_android_media_audio_common_types_ndk_shared",
+ "latest_android_hardware_audio_core_sounddose_ndk_shared",
"latest_android_hardware_audio_core_ndk_shared",
],
static_libs: [
diff --git a/audio/aidl/default/Bluetooth.cpp b/audio/aidl/default/Bluetooth.cpp
new file mode 100644
index 0000000..38e0c21
--- /dev/null
+++ b/audio/aidl/default/Bluetooth.cpp
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AHAL_Bluetooth"
+#include <android-base/logging.h>
+
+#include "core-impl/Bluetooth.h"
+
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+using aidl::android::media::audio::common::Int;
+
+namespace aidl::android::hardware::audio::core {
+
+Bluetooth::Bluetooth() {
+ mScoConfig.isEnabled = Boolean{false};
+ mScoConfig.isNrecEnabled = Boolean{false};
+ mScoConfig.mode = ScoConfig::Mode::SCO;
+ mHfpConfig.isEnabled = Boolean{false};
+ mHfpConfig.sampleRate = Int{8000};
+ mHfpConfig.volume = Float{HfpConfig::VOLUME_MAX};
+}
+
+ndk::ScopedAStatus Bluetooth::setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) {
+ if (in_config.isEnabled.has_value()) {
+ mScoConfig.isEnabled = in_config.isEnabled;
+ }
+ if (in_config.isNrecEnabled.has_value()) {
+ mScoConfig.isNrecEnabled = in_config.isNrecEnabled;
+ }
+ if (in_config.mode != ScoConfig::Mode::UNSPECIFIED) {
+ mScoConfig.mode = in_config.mode;
+ }
+ if (in_config.debugName.has_value()) {
+ mScoConfig.debugName = in_config.debugName;
+ }
+ *_aidl_return = mScoConfig;
+ LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+ << _aidl_return->toString();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Bluetooth::setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) {
+ if (in_config.sampleRate.has_value() && in_config.sampleRate.value().value <= 0) {
+ LOG(ERROR) << __func__ << ": invalid sample rate: " << in_config.sampleRate.value().value;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (in_config.volume.has_value() && (in_config.volume.value().value < HfpConfig::VOLUME_MIN ||
+ in_config.volume.value().value > HfpConfig::VOLUME_MAX)) {
+ LOG(ERROR) << __func__ << ": invalid volume: " << in_config.volume.value().value;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ if (in_config.isEnabled.has_value()) {
+ mHfpConfig.isEnabled = in_config.isEnabled;
+ }
+ if (in_config.sampleRate.has_value()) {
+ mHfpConfig.sampleRate = in_config.sampleRate;
+ }
+ if (in_config.volume.has_value()) {
+ mHfpConfig.volume = in_config.volume;
+ }
+ *_aidl_return = mHfpConfig;
+ LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+ << _aidl_return->toString();
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 6a833c4..e8b5bfc 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -25,6 +25,7 @@
#include <aidl/android/media/audio/common/AudioInputFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
+#include "core-impl/Bluetooth.h"
#include "core-impl/Module.h"
#include "core-impl/SoundDose.h"
#include "core-impl/Telephony.h"
@@ -32,6 +33,7 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
using aidl::android::media::audio::common::AudioChannelLayout;
using aidl::android::media::audio::common::AudioDevice;
using aidl::android::media::audio::common::AudioFormatDescription;
@@ -325,6 +327,18 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) {
+ if (mBluetooth == nullptr) {
+ mBluetooth = ndk::SharedRefBase::make<Bluetooth>();
+ mBluetoothBinder = mBluetooth->asBinder();
+ AIBinder_setMinSchedulerPolicy(mBluetoothBinder.get(), SCHED_NORMAL,
+ ANDROID_PRIORITY_AUDIO);
+ }
+ *_aidl_return = mBluetooth;
+ LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _aidl_return->get();
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdAndAdditionalData,
AudioPort* _aidl_return) {
const int32_t templateId = in_templateIdAndAdditionalData.id;
@@ -946,7 +960,7 @@
ndk::ScopedAStatus Module::getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) {
if (mSoundDose == nullptr) {
- mSoundDose = ndk::SharedRefBase::make<SoundDose>();
+ mSoundDose = ndk::SharedRefBase::make<sounddose::SoundDose>();
mSoundDoseBinder = mSoundDose->asBinder();
AIBinder_setMinSchedulerPolicy(mSoundDoseBinder.get(), SCHED_NORMAL,
ANDROID_PRIORITY_AUDIO);
diff --git a/audio/aidl/default/SoundDose.cpp b/audio/aidl/default/SoundDose.cpp
index 3d222a8..be9f93a 100644
--- a/audio/aidl/default/SoundDose.cpp
+++ b/audio/aidl/default/SoundDose.cpp
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::sounddose {
ndk::ScopedAStatus SoundDose::setOutputRs2(float in_rs2ValueDbA) {
if (in_rs2ValueDbA < MIN_RS2 || in_rs2ValueDbA > DEFAULT_MAX_RS2) {
@@ -54,4 +54,4 @@
return ndk::ScopedAStatus::ok();
}
-} // namespace aidl::android::hardware::audio::core
+} // namespace aidl::android::hardware::audio::core::sounddose
diff --git a/audio/aidl/default/Telephony.cpp b/audio/aidl/default/Telephony.cpp
index 1854b35..d873178 100644
--- a/audio/aidl/default/Telephony.cpp
+++ b/audio/aidl/default/Telephony.cpp
@@ -20,8 +20,17 @@
#include "core-impl/Telephony.h"
+using aidl::android::media::audio::common::Boolean;
+using aidl::android::media::audio::common::Float;
+
namespace aidl::android::hardware::audio::core {
+Telephony::Telephony() {
+ mTelecomConfig.voiceVolume = Float{TelecomConfig::VOICE_VOLUME_MAX};
+ mTelecomConfig.ttyMode = TelecomConfig::TtyMode::OFF;
+ mTelecomConfig.isHacEnabled = Boolean{false};
+}
+
ndk::ScopedAStatus Telephony::getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) {
*_aidl_return = mSupportedAudioModes;
LOG(DEBUG) << __func__ << ": returning " << ::android::internal::ToString(*_aidl_return);
@@ -38,4 +47,28 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
+ndk::ScopedAStatus Telephony::setTelecomConfig(const TelecomConfig& in_config,
+ TelecomConfig* _aidl_return) {
+ if (in_config.voiceVolume.has_value() &&
+ (in_config.voiceVolume.value().value < TelecomConfig::VOICE_VOLUME_MIN ||
+ in_config.voiceVolume.value().value > TelecomConfig::VOICE_VOLUME_MAX)) {
+ LOG(ERROR) << __func__
+ << ": voice volume value is invalid: " << in_config.voiceVolume.value().value;
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (in_config.voiceVolume.has_value()) {
+ mTelecomConfig.voiceVolume = in_config.voiceVolume;
+ }
+ if (in_config.ttyMode != TelecomConfig::TtyMode::UNSPECIFIED) {
+ mTelecomConfig.ttyMode = in_config.ttyMode;
+ }
+ if (in_config.isHacEnabled.has_value()) {
+ mTelecomConfig.isHacEnabled = in_config.isHacEnabled;
+ }
+ *_aidl_return = mTelecomConfig;
+ LOG(DEBUG) << __func__ << ": received " << in_config.toString() << ", returning "
+ << _aidl_return->toString();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/bassboost/BassBoostSw.cpp b/audio/aidl/default/bassboost/BassBoostSw.cpp
index 8e4779d..0c7ebe1 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.cpp
+++ b/audio/aidl/default/bassboost/BassBoostSw.cpp
@@ -62,7 +62,8 @@
const std::string BassBoostSw::kEffectName = "BassBoostSw";
const bool BassBoostSw::kStrengthSupported = true;
-const BassBoost::Capability BassBoostSw::kCapability = {.strengthSupported = kStrengthSupported};
+const BassBoost::Capability BassBoostSw::kCapability = {.maxStrengthPm = 1000,
+ .strengthSupported = kStrengthSupported};
const Descriptor BassBoostSw::kDescriptor = {
.common = {.id = {.type = kBassBoostTypeUUID,
.uuid = kBassBoostSwImplUUID,
@@ -171,4 +172,14 @@
return {STATUS_OK, samples, samples};
}
+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;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/bassboost/BassBoostSw.h b/audio/aidl/default/bassboost/BassBoostSw.h
index 91086e9..65c01c8 100644
--- a/audio/aidl/default/bassboost/BassBoostSw.h
+++ b/audio/aidl/default/bassboost/BassBoostSw.h
@@ -33,16 +33,7 @@
LOG(DEBUG) << __func__;
}
- RetCode setBbStrengthPm(int strength) {
- if (strength < BassBoost::MIN_PER_MILLE_STRENGTH ||
- strength > BassBoost::MAX_PER_MILLE_STRENGTH) {
- LOG(ERROR) << __func__ << " invalid strength: " << strength;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new strength
- mStrength = strength;
- return RetCode::SUCCESS;
- }
+ RetCode setBbStrengthPm(int strength);
int getBbStrengthPm() const { return mStrength; }
private:
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
index f6211c4..3c3b66f 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.cpp
@@ -90,8 +90,8 @@
auto tag = hgParam.getTag();
switch (tag) {
- case HapticGenerator::hapticScale: {
- RETURN_IF(mContext->setHgHapticScale(hgParam.get<HapticGenerator::hapticScale>()) !=
+ case HapticGenerator::hapticScales: {
+ RETURN_IF(mContext->setHgHapticScales(hgParam.get<HapticGenerator::hapticScales>()) !=
RetCode::SUCCESS,
EX_ILLEGAL_ARGUMENT, "HapticScaleNotSupported");
return ndk::ScopedAStatus::ok();
@@ -133,8 +133,8 @@
HapticGenerator hgParam;
switch (tag) {
- case HapticGenerator::hapticScale: {
- hgParam.set<HapticGenerator::hapticScale>(mContext->getHgHapticScale());
+ case HapticGenerator::hapticScales: {
+ hgParam.set<HapticGenerator::hapticScales>(mContext->getHgHapticScales());
break;
}
case HapticGenerator::vibratorInfo: {
@@ -183,4 +183,20 @@
return {STATUS_OK, samples, samples};
}
+RetCode HapticGeneratorSwContext::setHgHapticScales(
+ const std::vector<HapticGenerator::HapticScale>& hapticScales) {
+ // Assume any audio track ID is valid
+ for (auto& it : hapticScales) {
+ mHapticScales[it.id] = it;
+ }
+ return RetCode::SUCCESS;
+}
+
+std::vector<HapticGenerator::HapticScale> HapticGeneratorSwContext::getHgHapticScales() const {
+ std::vector<HapticGenerator::HapticScale> result;
+ std::transform(mHapticScales.begin(), mHapticScales.end(), std::back_inserter(result),
+ [](auto& scaleIt) { return scaleIt.second; });
+ return result;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
index d9ec744..7159501 100644
--- a/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
+++ b/audio/aidl/default/hapticGenerator/HapticGeneratorSw.h
@@ -33,12 +33,8 @@
LOG(DEBUG) << __func__;
}
- RetCode setHgHapticScale(const HapticGenerator::HapticScale& hapticScale) {
- // All int values are valid for ID
- mHapticScale = hapticScale;
- return RetCode::SUCCESS;
- }
- HapticGenerator::HapticScale getHgHapticScale() const { return mHapticScale; }
+ RetCode setHgHapticScales(const std::vector<HapticGenerator::HapticScale>& hapticScales);
+ std::vector<HapticGenerator::HapticScale> getHgHapticScales() const;
RetCode setHgVibratorInformation(const HapticGenerator::VibratorInformation& vibratorInfo) {
// All float values are valid for resonantFrequencyHz, qFactor, maxAmplitude
@@ -54,7 +50,7 @@
static constexpr float DEFAULT_RESONANT_FREQUENCY = 150.0f;
static constexpr float DEFAULT_Q_FACTOR = 1.0f;
static constexpr float DEFAULT_MAX_AMPLITUDE = 0.0f;
- HapticGenerator::HapticScale mHapticScale = {0, HapticGenerator::VibratorScale::MUTE};
+ std::map<int /* trackID */, HapticGenerator::HapticScale> mHapticScales;
HapticGenerator::VibratorInformation mVibratorInformation = {
DEFAULT_RESONANT_FREQUENCY, DEFAULT_Q_FACTOR, DEFAULT_MAX_AMPLITUDE};
};
diff --git a/audio/aidl/default/include/core-impl/Bluetooth.h b/audio/aidl/default/include/core-impl/Bluetooth.h
new file mode 100644
index 0000000..f2e762d
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/Bluetooth.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/audio/core/BnBluetooth.h>
+
+namespace aidl::android::hardware::audio::core {
+
+class Bluetooth : public BnBluetooth {
+ public:
+ Bluetooth();
+
+ private:
+ ndk::ScopedAStatus setScoConfig(const ScoConfig& in_config, ScoConfig* _aidl_return) override;
+ ndk::ScopedAStatus setHfpConfig(const HfpConfig& in_config, HfpConfig* _aidl_return) override;
+
+ ScoConfig mScoConfig;
+ HfpConfig mHfpConfig;
+};
+
+} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index ff45f81..e9f43d8 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -39,6 +39,7 @@
ndk::ScopedAStatus setModuleDebug(
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
+ ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
ndk::ScopedAStatus connectExternalDevice(
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
@@ -88,7 +89,7 @@
ndk::ScopedAStatus updateScreenRotation(
::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
- ndk::ScopedAStatus getSoundDose(std::shared_ptr<ISoundDose>* _aidl_return) override;
+ ndk::ScopedAStatus getSoundDose(std::shared_ptr<sounddose::ISoundDose>* _aidl_return) override;
ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override;
ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
std::vector<VendorParameter>* _aidl_return) override;
@@ -127,10 +128,12 @@
const Type mType;
std::unique_ptr<internal::Configuration> mConfig;
ModuleDebug mDebug;
- // Since it is required to return the same instance of the ITelephony, even
- // if the client has released it on its side, we need to hold it via a strong pointer.
+ // For the interfaces requiring to return the same instance, we need to hold them
+ // via a strong pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'.
std::shared_ptr<ITelephony> mTelephony;
ndk::SpAIBinder mTelephonyBinder;
+ std::shared_ptr<IBluetooth> mBluetooth;
+ ndk::SpAIBinder mBluetoothBinder;
// ids of ports created at runtime via 'connectExternalDevice'.
std::set<int32_t> mConnectedDevicePorts;
Streams mStreams;
@@ -140,7 +143,7 @@
bool mMasterMute = false;
float mMasterVolume = 1.0f;
bool mMicMute = false;
- std::shared_ptr<ISoundDose> mSoundDose;
+ std::shared_ptr<sounddose::ISoundDose> mSoundDose;
ndk::SpAIBinder mSoundDoseBinder;
};
diff --git a/audio/aidl/default/include/core-impl/SoundDose.h b/audio/aidl/default/include/core-impl/SoundDose.h
index 54a6cbf..306aa04 100644
--- a/audio/aidl/default/include/core-impl/SoundDose.h
+++ b/audio/aidl/default/include/core-impl/SoundDose.h
@@ -18,12 +18,12 @@
#include <mutex>
-#include <aidl/android/hardware/audio/core/BnSoundDose.h>
+#include <aidl/android/hardware/audio/core/sounddose/BnSoundDose.h>
#include <aidl/android/media/audio/common/AudioDevice.h>
using aidl::android::media::audio::common::AudioDevice;
-namespace aidl::android::hardware::audio::core {
+namespace aidl::android::hardware::audio::core::sounddose {
class SoundDose : public BnSoundDose {
public:
@@ -39,4 +39,4 @@
float mRs2Value;
};
-} // namespace aidl::android::hardware::audio::core
+} // namespace aidl::android::hardware::audio::core::sounddose
diff --git a/audio/aidl/default/include/core-impl/Telephony.h b/audio/aidl/default/include/core-impl/Telephony.h
index 597f3d6..0936172 100644
--- a/audio/aidl/default/include/core-impl/Telephony.h
+++ b/audio/aidl/default/include/core-impl/Telephony.h
@@ -23,12 +23,18 @@
namespace aidl::android::hardware::audio::core {
class Telephony : public BnTelephony {
+ public:
+ Telephony();
+
private:
ndk::ScopedAStatus getSupportedAudioModes(std::vector<AudioMode>* _aidl_return) override;
ndk::ScopedAStatus switchAudioMode(AudioMode in_mode) override;
+ ndk::ScopedAStatus setTelecomConfig(const TelecomConfig& in_config,
+ TelecomConfig* _aidl_return) override;
const std::vector<AudioMode> mSupportedAudioModes = {::ndk::enum_range<AudioMode>().begin(),
::ndk::enum_range<AudioMode>().end()};
+ TelecomConfig mTelecomConfig;
};
} // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.cpp b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
index f4aa67c..cc51937 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.cpp
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.cpp
@@ -61,8 +61,8 @@
const std::string VirtualizerSw::kEffectName = "VirtualizerSw";
const bool VirtualizerSw::kStrengthSupported = true;
-const Virtualizer::Capability VirtualizerSw::kCapability = {.strengthSupported =
- kStrengthSupported};
+const Virtualizer::Capability VirtualizerSw::kCapability = {
+ .maxStrengthPm = 1000, .strengthSupported = kStrengthSupported};
const Descriptor VirtualizerSw::kDescriptor = {
.common = {.id = {.type = kVirtualizerTypeUUID,
.uuid = kVirtualizerSwImplUUID,
@@ -172,4 +172,14 @@
return {STATUS_OK, samples, samples};
}
+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;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/virtualizer/VirtualizerSw.h b/audio/aidl/default/virtualizer/VirtualizerSw.h
index b4482da..0f294cd 100644
--- a/audio/aidl/default/virtualizer/VirtualizerSw.h
+++ b/audio/aidl/default/virtualizer/VirtualizerSw.h
@@ -32,16 +32,7 @@
: EffectContext(statusDepth, common) {
LOG(DEBUG) << __func__;
}
- RetCode setVrStrength(int strength) {
- if (strength < Virtualizer::MIN_PER_MILLE_STRENGTH ||
- strength > Virtualizer::MAX_PER_MILLE_STRENGTH) {
- LOG(ERROR) << __func__ << " invalid strength " << strength;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new strength
- mStrength = strength;
- return RetCode::SUCCESS;
- }
+ RetCode setVrStrength(int strength);
int getVrStrength() const { return mStrength; }
private:
diff --git a/audio/aidl/default/visualizer/VisualizerSw.cpp b/audio/aidl/default/visualizer/VisualizerSw.cpp
index 735180e..614988c 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.cpp
+++ b/audio/aidl/default/visualizer/VisualizerSw.cpp
@@ -241,4 +241,37 @@
return {STATUS_OK, samples, samples};
}
+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;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/visualizer/VisualizerSw.h b/audio/aidl/default/visualizer/VisualizerSw.h
index 3c9e6d2..e9d46d7 100644
--- a/audio/aidl/default/visualizer/VisualizerSw.h
+++ b/audio/aidl/default/visualizer/VisualizerSw.h
@@ -38,40 +38,16 @@
fill(mCaptureSampleBuffer.begin(), mCaptureSampleBuffer.end(), 0x80);
}
- RetCode setVsCaptureSize(int captureSize) {
- if (captureSize < kMinCaptureSize || captureSize > kMaxCaptureSize) {
- LOG(ERROR) << __func__ << " invalid captureSize " << captureSize;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new captureSize
- mCaptureSize = captureSize;
- return RetCode::SUCCESS;
- }
+ RetCode setVsCaptureSize(int captureSize);
int getVsCaptureSize() const { return mCaptureSize; }
- RetCode setVsScalingMode(Visualizer::ScalingMode scalingMode) {
- // TODO : Add implementation to apply new scalingMode
- mScalingMode = scalingMode;
- return RetCode::SUCCESS;
- }
+ RetCode setVsScalingMode(Visualizer::ScalingMode scalingMode);
Visualizer::ScalingMode getVsScalingMode() const { return mScalingMode; }
- RetCode setVsMeasurementMode(Visualizer::MeasurementMode measurementMode) {
- // TODO : Add implementation to apply new measurementMode
- mMeasurementMode = measurementMode;
- return RetCode::SUCCESS;
- }
+ RetCode setVsMeasurementMode(Visualizer::MeasurementMode measurementMode);
Visualizer::MeasurementMode getVsMeasurementMode() const { return mMeasurementMode; }
- RetCode setVsLatency(int latency) {
- if (latency < 0 || latency > kMaxLatencyMs) {
- LOG(ERROR) << __func__ << " invalid latency " << latency;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to modify latency
- mLatency = latency;
- return RetCode::SUCCESS;
- }
+ RetCode setVsLatency(int latency);
Visualizer::GetOnlyParameters::Measurement getVsMeasurement() const { return mMeasurement; }
std::vector<uint8_t> getVsCaptureSampleBuffer() const { return mCaptureSampleBuffer; }
diff --git a/audio/aidl/default/volume/VolumeSw.cpp b/audio/aidl/default/volume/VolumeSw.cpp
index 24e1e1d..64301dc 100644
--- a/audio/aidl/default/volume/VolumeSw.cpp
+++ b/audio/aidl/default/volume/VolumeSw.cpp
@@ -60,7 +60,7 @@
namespace aidl::android::hardware::audio::effect {
const std::string VolumeSw::kEffectName = "VolumeSw";
-const Volume::Capability VolumeSw::kCapability = {.maxLevel = Volume::MAX_LEVEL_DB};
+const Volume::Capability VolumeSw::kCapability = {.minLevelDb = -9600, .maxLevelDb = 0};
const Descriptor VolumeSw::kDescriptor = {
.common = {.id = {.type = kVolumeTypeUUID,
.uuid = kVolumeSwImplUUID,
@@ -176,4 +176,20 @@
return {STATUS_OK, samples, samples};
}
+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;
+}
+
+RetCode VolumeSwContext::setVolMute(bool mute) {
+ // TODO : Add implementation to modify mute
+ mMute = mute;
+ return RetCode::SUCCESS;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/volume/VolumeSw.h b/audio/aidl/default/volume/VolumeSw.h
index a101c59..b6f6077 100644
--- a/audio/aidl/default/volume/VolumeSw.h
+++ b/audio/aidl/default/volume/VolumeSw.h
@@ -33,23 +33,11 @@
LOG(DEBUG) << __func__;
}
- RetCode setVolLevel(int level) {
- if (level < Volume::MIN_LEVEL_DB || level > Volume::MAX_LEVEL_DB) {
- LOG(ERROR) << __func__ << " invalid level " << level;
- return RetCode::ERROR_ILLEGAL_PARAMETER;
- }
- // TODO : Add implementation to apply new level
- mLevel = level;
- return RetCode::SUCCESS;
- }
+ RetCode setVolLevel(int level);
int getVolLevel() const { return mLevel; }
- RetCode setVolMute(bool mute) {
- // TODO : Add implementation to modify mute
- mMute = mute;
- return RetCode::SUCCESS;
- }
+ RetCode setVolMute(bool mute);
bool getVolMute() const { return mMute; }
diff --git a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
index 7dda011..148720c 100644
--- a/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
+++ b/audio/aidl/sounddose/aidl_api/android.hardware.audio.sounddose/current/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -34,5 +34,5 @@
package android.hardware.audio.sounddose;
@VintfStability
interface ISoundDoseFactory {
- @nullable android.hardware.audio.core.ISoundDose getSoundDose(in @utf8InCpp String module);
+ @nullable android.hardware.audio.core.sounddose.ISoundDose getSoundDose(in @utf8InCpp String module);
}
diff --git a/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl b/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
index 3487237..4079fe8 100644
--- a/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
+++ b/audio/aidl/sounddose/android/hardware/audio/sounddose/ISoundDoseFactory.aidl
@@ -16,7 +16,7 @@
package android.hardware.audio.sounddose;
-import android.hardware.audio.core.ISoundDose;
+import android.hardware.audio.core.sounddose.ISoundDose;
/**
* This interface is used to provide an easy way to implement the ISoundDose interface
diff --git a/audio/aidl/sounddose/default/SoundDoseFactory.cpp b/audio/aidl/sounddose/default/SoundDoseFactory.cpp
index 50796d0..83a592b 100644
--- a/audio/aidl/sounddose/default/SoundDoseFactory.cpp
+++ b/audio/aidl/sounddose/default/SoundDoseFactory.cpp
@@ -23,7 +23,7 @@
namespace aidl::android::hardware::audio::sounddose {
-using ::aidl::android::hardware::audio::core::SoundDose;
+using ::aidl::android::hardware::audio::core::sounddose::SoundDose;
ndk::ScopedAStatus SoundDoseFactory::getSoundDose(const std::string& in_module,
std::shared_ptr<ISoundDose>* _aidl_return) {
diff --git a/audio/aidl/sounddose/default/include/SoundDoseFactory.h b/audio/aidl/sounddose/default/include/SoundDoseFactory.h
index 4cf3277..ced4291 100644
--- a/audio/aidl/sounddose/default/include/SoundDoseFactory.h
+++ b/audio/aidl/sounddose/default/include/SoundDoseFactory.h
@@ -16,7 +16,7 @@
#pragma once
-#include <aidl/android/hardware/audio/core/ISoundDose.h>
+#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
#include <aidl/android/hardware/audio/sounddose/BnSoundDoseFactory.h>
#include <android/binder_interface_utils.h>
@@ -24,7 +24,7 @@
namespace aidl::android::hardware::audio::sounddose {
-using ::aidl::android::hardware::audio::core::ISoundDose;
+using ::aidl::android::hardware::audio::core::sounddose::ISoundDose;
class SoundDoseFactory : public BnSoundDoseFactory {
public:
diff --git a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
index 7448c1f..df35bae 100644
--- a/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
+++ b/audio/aidl/sounddose/vts/VtsHalSoundDoseFactoryTargetTest.cpp
@@ -47,7 +47,7 @@
using namespace android;
-using aidl::android::hardware::audio::core::ISoundDose;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
class SoundDoseFactory : public testing::TestWithParam<std::string> {
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 5e6f53d..becdf1b 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -44,6 +44,7 @@
defaults: [
"VtsHalAudioTargetTestDefaults",
"latest_android_hardware_audio_core_ndk_static",
+ "latest_android_hardware_audio_core_sounddose_ndk_static",
],
shared_libs: [
"libcutils",
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 1b46498..8da475e 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -36,8 +36,8 @@
#include <aidl/Vintf.h>
#include <aidl/android/hardware/audio/core/BnStreamCallback.h>
#include <aidl/android/hardware/audio/core/IModule.h>
-#include <aidl/android/hardware/audio/core/ISoundDose.h>
#include <aidl/android/hardware/audio/core/ITelephony.h>
+#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
#include <aidl/android/media/audio/common/AudioIoFlags.h>
#include <aidl/android/media/audio/common/AudioOutputFlags.h>
#include <android-base/chrono_utils.h>
@@ -56,8 +56,8 @@
using aidl::android::hardware::audio::core::AudioMode;
using aidl::android::hardware::audio::core::AudioPatch;
using aidl::android::hardware::audio::core::AudioRoute;
+using aidl::android::hardware::audio::core::IBluetooth;
using aidl::android::hardware::audio::core::IModule;
-using aidl::android::hardware::audio::core::ISoundDose;
using aidl::android::hardware::audio::core::IStreamCommon;
using aidl::android::hardware::audio::core::IStreamIn;
using aidl::android::hardware::audio::core::IStreamOut;
@@ -67,6 +67,7 @@
using aidl::android::hardware::audio::core::ModuleDebug;
using aidl::android::hardware::audio::core::StreamDescriptor;
using aidl::android::hardware::audio::core::VendorParameter;
+using aidl::android::hardware::audio::core::sounddose::ISoundDose;
using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using aidl::android::media::audio::common::AudioContentType;
using aidl::android::media::audio::common::AudioDevice;
@@ -84,6 +85,8 @@
using aidl::android::media::audio::common::AudioPortExt;
using aidl::android::media::audio::common::AudioSource;
using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::Float;
+using aidl::android::media::audio::common::Int;
using aidl::android::media::audio::common::Void;
using android::hardware::audio::common::getChannelCount;
using android::hardware::audio::common::isBitPositionFlagSet;
@@ -1755,13 +1758,12 @@
TEST_P(AudioCoreModule, AddRemoveEffectInvalidArguments) {
ndk::ScopedAStatus addEffectStatus = module->addDeviceEffect(-1, nullptr);
ndk::ScopedAStatus removeEffectStatus = module->removeDeviceEffect(-1, nullptr);
- const bool isSupported = addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION;
- if (isSupported) {
+ if (addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
EXPECT_EQ(EX_ILLEGAL_ARGUMENT, addEffectStatus.getExceptionCode());
EXPECT_EQ(EX_ILLEGAL_ARGUMENT, removeEffectStatus.getExceptionCode());
- } else if (EX_UNSUPPORTED_OPERATION != removeEffectStatus.getExceptionCode()) {
- GTEST_FAIL() << "addEffect and removeEffect must be either supported or not supported "
- << "together";
+ } else if (removeEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+ GTEST_FAIL() << "addDeviceEffect and removeDeviceEffect must be either supported or "
+ << "not supported together";
} else {
GTEST_SKIP() << "Offloaded effects not supported";
}
@@ -1776,6 +1778,89 @@
}
}
+class AudioCoreBluetooth : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(SetUpImpl(GetParam()));
+ ASSERT_IS_OK(module->getBluetooth(&bluetooth));
+ }
+
+ void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownImpl()); }
+
+ std::shared_ptr<IBluetooth> bluetooth;
+};
+
+TEST_P(AudioCoreBluetooth, SameInstance) {
+ if (bluetooth == nullptr) {
+ GTEST_SKIP() << "Bluetooth is not supported";
+ }
+ std::shared_ptr<IBluetooth> bluetooth2;
+ EXPECT_IS_OK(module->getBluetooth(&bluetooth2));
+ ASSERT_NE(nullptr, bluetooth2.get());
+ EXPECT_EQ(bluetooth->asBinder(), bluetooth2->asBinder())
+ << "getBluetooth must return the same interface instance across invocations";
+}
+
+TEST_P(AudioCoreBluetooth, ScoConfig) {
+ static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+ if (bluetooth == nullptr) {
+ GTEST_SKIP() << "Bluetooth is not supported";
+ }
+ ndk::ScopedAStatus status;
+ IBluetooth::ScoConfig scoConfig;
+ ASSERT_STATUS(kStatuses, status = bluetooth->setScoConfig({}, &scoConfig));
+ if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "BT SCO is not supported";
+ }
+ EXPECT_TRUE(scoConfig.isEnabled.has_value());
+ EXPECT_TRUE(scoConfig.isNrecEnabled.has_value());
+ EXPECT_NE(IBluetooth::ScoConfig::Mode::UNSPECIFIED, scoConfig.mode);
+ IBluetooth::ScoConfig scoConfig2;
+ ASSERT_IS_OK(bluetooth->setScoConfig(scoConfig, &scoConfig2));
+ EXPECT_EQ(scoConfig, scoConfig2);
+}
+
+TEST_P(AudioCoreBluetooth, HfpConfig) {
+ static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+ if (bluetooth == nullptr) {
+ GTEST_SKIP() << "Bluetooth is not supported";
+ }
+ ndk::ScopedAStatus status;
+ IBluetooth::HfpConfig hfpConfig;
+ ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
+ if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "BT HFP is not supported";
+ }
+ EXPECT_TRUE(hfpConfig.isEnabled.has_value());
+ EXPECT_TRUE(hfpConfig.sampleRate.has_value());
+ EXPECT_TRUE(hfpConfig.volume.has_value());
+ IBluetooth::HfpConfig hfpConfig2;
+ ASSERT_IS_OK(bluetooth->setHfpConfig(hfpConfig, &hfpConfig2));
+ EXPECT_EQ(hfpConfig, hfpConfig2);
+}
+
+TEST_P(AudioCoreBluetooth, HfpConfigInvalid) {
+ static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+ if (bluetooth == nullptr) {
+ GTEST_SKIP() << "Bluetooth is not supported";
+ }
+ ndk::ScopedAStatus status;
+ IBluetooth::HfpConfig hfpConfig;
+ ASSERT_STATUS(kStatuses, status = bluetooth->setHfpConfig({}, &hfpConfig));
+ if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "BT HFP is not supported";
+ }
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ bluetooth->setHfpConfig({.sampleRate = Int{-1}}, &hfpConfig));
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, bluetooth->setHfpConfig({.sampleRate = Int{0}}, &hfpConfig));
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MIN - 1}},
+ &hfpConfig));
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ bluetooth->setHfpConfig({.volume = Float{IBluetooth::HfpConfig::VOLUME_MAX + 1}},
+ &hfpConfig));
+}
+
class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam<std::string> {
public:
void SetUp() override {
@@ -1788,6 +1873,17 @@
std::shared_ptr<ITelephony> telephony;
};
+TEST_P(AudioCoreTelephony, SameInstance) {
+ if (telephony == nullptr) {
+ GTEST_SKIP() << "Telephony is not supported";
+ }
+ std::shared_ptr<ITelephony> telephony2;
+ EXPECT_IS_OK(module->getTelephony(&telephony2));
+ ASSERT_NE(nullptr, telephony2.get());
+ EXPECT_EQ(telephony->asBinder(), telephony2->asBinder())
+ << "getTelephony must return the same interface instance across invocations";
+}
+
TEST_P(AudioCoreTelephony, GetSupportedAudioModes) {
if (telephony == nullptr) {
GTEST_SKIP() << "Telephony is not supported";
@@ -1829,6 +1925,46 @@
}
}
+TEST_P(AudioCoreTelephony, TelecomConfig) {
+ static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+ if (telephony == nullptr) {
+ GTEST_SKIP() << "Telephony is not supported";
+ }
+ ndk::ScopedAStatus status;
+ ITelephony::TelecomConfig telecomConfig;
+ ASSERT_STATUS(kStatuses, status = telephony->setTelecomConfig({}, &telecomConfig));
+ if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "Telecom is not supported";
+ }
+ EXPECT_TRUE(telecomConfig.voiceVolume.has_value());
+ EXPECT_NE(ITelephony::TelecomConfig::TtyMode::UNSPECIFIED, telecomConfig.ttyMode);
+ EXPECT_TRUE(telecomConfig.isHacEnabled.has_value());
+ ITelephony::TelecomConfig telecomConfig2;
+ ASSERT_IS_OK(telephony->setTelecomConfig(telecomConfig, &telecomConfig2));
+ EXPECT_EQ(telecomConfig, telecomConfig2);
+}
+
+TEST_P(AudioCoreTelephony, TelecomConfigInvalid) {
+ static const auto kStatuses = {EX_NONE, EX_UNSUPPORTED_OPERATION};
+ if (telephony == nullptr) {
+ GTEST_SKIP() << "Telephony is not supported";
+ }
+ ndk::ScopedAStatus status;
+ ITelephony::TelecomConfig telecomConfig;
+ ASSERT_STATUS(kStatuses, status = telephony->setTelecomConfig({}, &telecomConfig));
+ if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ GTEST_SKIP() << "Telecom is not supported";
+ }
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ telephony->setTelecomConfig(
+ {.voiceVolume = Float{ITelephony::TelecomConfig::VOICE_VOLUME_MIN - 1}},
+ &telecomConfig));
+ EXPECT_STATUS(EX_ILLEGAL_ARGUMENT,
+ telephony->setTelecomConfig(
+ {.voiceVolume = Float{ITelephony::TelecomConfig::VOICE_VOLUME_MAX + 1}},
+ &telecomConfig));
+}
+
using CommandSequence = std::vector<StreamDescriptor::Command>;
class StreamLogicDriverInvalidCommand : public StreamLogicDriver {
public:
@@ -2128,15 +2264,13 @@
ASSERT_NE(nullptr, streamCommon);
ndk::ScopedAStatus addEffectStatus = streamCommon->addEffect(nullptr);
ndk::ScopedAStatus removeEffectStatus = streamCommon->removeEffect(nullptr);
- const bool isSupported = addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION;
- if (isSupported) {
+ if (addEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
EXPECT_EQ(EX_ILLEGAL_ARGUMENT, addEffectStatus.getExceptionCode());
EXPECT_EQ(EX_ILLEGAL_ARGUMENT, removeEffectStatus.getExceptionCode());
atLeastOneSupports = true;
- } else if (EX_UNSUPPORTED_OPERATION != removeEffectStatus.getExceptionCode()) {
- ADD_FAILURE()
- << "addEffect and removeEffect must be either supported or not supported "
- << "together";
+ } else if (removeEffectStatus.getExceptionCode() != EX_UNSUPPORTED_OPERATION) {
+ ADD_FAILURE() << "addEffect and removeEffect must be either supported or "
+ << "not supported together";
atLeastOneSupports = true;
}
}
@@ -2458,10 +2592,10 @@
ASSERT_TRUE(portConfig.has_value()) << "No profiles specified for output mix port";
WithStream<IStreamOut> stream(portConfig.value());
ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames));
- bool isSupported = false;
std::vector<AudioLatencyMode> supportedModes;
ndk::ScopedAStatus status = stream.get()->getRecommendedLatencyModes(&supportedModes);
if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) continue;
+ atLeastOneSupports = true;
if (!status.isOk()) {
ADD_FAILURE() << "When latency modes are supported, getRecommendedLatencyModes "
<< "must succeed on a non-closed stream, but it failed with " << status;
@@ -2481,7 +2615,6 @@
for (const auto mode : unsupportedModes) {
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, stream.get()->setLatencyMode(mode));
}
- if (isSupported) atLeastOneSupports = true;
}
if (!atLeastOneSupports) {
GTEST_SKIP() << "Audio latency modes are not supported";
@@ -3002,6 +3135,17 @@
return ndk::ScopedAStatus::ok();
}
+TEST_P(AudioCoreSoundDose, SameInstance) {
+ if (soundDose == nullptr) {
+ GTEST_SKIP() << "SoundDose is not supported";
+ }
+ std::shared_ptr<ISoundDose> soundDose2;
+ EXPECT_IS_OK(module->getSoundDose(&soundDose2));
+ ASSERT_NE(nullptr, soundDose2.get());
+ EXPECT_EQ(soundDose->asBinder(), soundDose2->asBinder())
+ << "getSoundDose must return the same interface instance across invocations";
+}
+
TEST_P(AudioCoreSoundDose, GetSetOutputRs2) {
if (soundDose == nullptr) {
GTEST_SKIP() << "SoundDose is not supported";
@@ -3048,6 +3192,10 @@
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreModule);
+INSTANTIATE_TEST_SUITE_P(AudioCoreBluetoothTest, AudioCoreBluetooth,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
+ android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioCoreBluetooth);
INSTANTIATE_TEST_SUITE_P(AudioCoreTelephonyTest, AudioCoreTelephony,
testing::ValuesIn(android::getAidlHalInstanceNames(IModule::descriptor)),
android::PrintInstanceNameToString);
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 724a9c3..d49a865 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -46,15 +46,6 @@
* otherwise expect EX_ILLEGAL_ARGUMENT.
*/
-const std::vector<int> kStrengthValues = {
- std::numeric_limits<int>::min(),
- BassBoost::MIN_PER_MILLE_STRENGTH - 1,
- BassBoost::MIN_PER_MILLE_STRENGTH,
- (BassBoost::MIN_PER_MILLE_STRENGTH + BassBoost::MAX_PER_MILLE_STRENGTH) >> 1,
- BassBoost::MAX_PER_MILLE_STRENGTH,
- BassBoost::MAX_PER_MILLE_STRENGTH + 2,
- std::numeric_limits<int>::max()};
-
class BassBoostParamTest : public ::testing::TestWithParam<BassBoostParamTestParam>,
public EffectHelper {
public:
@@ -81,7 +72,7 @@
}
Parameter::Specific getDefaultParamSpecific() {
- BassBoost bb = BassBoost::make<BassBoost::strengthPm>(BassBoost::MIN_PER_MILLE_STRENGTH);
+ BassBoost bb = BassBoost::make<BassBoost::strengthPm>(0);
Parameter::Specific specific =
Parameter::Specific::make<Parameter::Specific::bassBoost>(bb);
return specific;
@@ -91,7 +82,7 @@
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
- int mParamStrength = BassBoost::MIN_PER_MILLE_STRENGTH;
+ int mParamStrength = 0;
void SetAndGetBassBoostParameters() {
for (auto& it : mTags) {
@@ -146,8 +137,29 @@
}
bool isStrengthInRange(const BassBoost::Capability& cap, int strength) const {
- return cap.strengthSupported && strength >= BassBoost::MIN_PER_MILLE_STRENGTH &&
- strength <= BassBoost::MAX_PER_MILLE_STRENGTH;
+ 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:
@@ -162,9 +174,12 @@
INSTANTIATE_TEST_SUITE_P(
BassBoostTest, BassBoostParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kBassBoostTypeUUID)),
- testing::ValuesIn(kStrengthValues)),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kBassBoostTypeUUID)),
+ testing::ValuesIn(BassBoostParamTest::getStrengthTestValues(
+ EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kBassBoostTypeUUID)))),
[](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/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index d1f3b97..b8ea9c1 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -19,7 +19,9 @@
#include <Utils.h>
#include <aidl/Vintf.h>
#include <android/binder_enums.h>
-#include <unordered_set>
+#include <map>
+#include <utility>
+#include <vector>
#include "EffectHelper.h"
@@ -87,12 +89,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);
}
@@ -101,15 +102,6 @@
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
}
- Parameter::Specific getDefaultParamSpecific() {
- HapticGenerator::HapticScale hapticScale = {.id = 0,
- .scale = HapticGenerator::VibratorScale::MUTE};
- HapticGenerator hg = HapticGenerator::make<HapticGenerator::hapticScale>(hapticScale);
- Parameter::Specific specific =
- Parameter::Specific::make<Parameter::Specific::hapticGenerator>(hg);
- return specific;
- }
-
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
@@ -122,13 +114,13 @@
void SetAndGetHapticGeneratorParameters() {
for (auto& it : mTags) {
- auto& tag = it.first;
- auto& hg = it.second;
+ auto& tag = std::get<ParamTestEnum::PARAM_TEST_TAG>(it);
+ auto& setHg = std::get<ParamTestEnum::PARAM_TEST_TARGET>(it);
// set parameter
Parameter expectParam;
Parameter::Specific specific;
- specific.set<Parameter::Specific::hapticGenerator>(hg);
+ specific.set<Parameter::Specific::hapticGenerator>(setHg);
expectParam.set<Parameter::specific>(specific);
EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
@@ -139,15 +131,16 @@
hgId.set<HapticGenerator::Id::commonTag>(tag);
id.set<Parameter::Id::hapticGeneratorTag>(hgId);
EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
- EXPECT_EQ(expectParam, getParam);
+ EXPECT_EQ(expectParam, getParam) << expectParam.toString() << "\n"
+ << getParam.toString();
}
}
void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale) {
- HapticGenerator hg;
- HapticGenerator::HapticScale hapticScale = {.id = id, .scale = scale};
- hg.set<HapticGenerator::hapticScale>(hapticScale);
- mTags.push_back({HapticGenerator::hapticScale, hg});
+ HapticGenerator setHg;
+ std::vector<HapticGenerator::HapticScale> hapticScales = {{.id = id, .scale = scale}};
+ setHg.set<HapticGenerator::hapticScales>(hapticScales);
+ mTags.push_back({HapticGenerator::hapticScales, setHg});
}
void addVibratorInformationParam(float resonantFrequencyHz, float qFactor, float maxAmplitude) {
@@ -161,7 +154,8 @@
}
private:
- std::vector<std::pair<HapticGenerator::Tag, HapticGenerator>> mTags;
+ enum ParamTestEnum { PARAM_TEST_TAG, PARAM_TEST_TARGET };
+ std::vector<std::tuple<HapticGenerator::Tag, HapticGenerator>> mTags;
void CleanUp() { mTags.clear(); }
};
@@ -171,6 +165,12 @@
SetAndGetHapticGeneratorParameters();
}
+TEST_P(HapticGeneratorParamTest, SetAndGetMultipleHapticScales) {
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+ SetAndGetHapticGeneratorParameters();
+}
+
TEST_P(HapticGeneratorParamTest, SetAndGetVibratorInformation) {
EXPECT_NO_FATAL_FAILURE(addVibratorInformationParam(mParamResonantFrequency, mParamQFactor,
mParamMaxAmplitude));
@@ -212,7 +212,7 @@
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kHapticGeneratorTypeUUID)),
testing::Values(MIN_ID - 1),
- testing::Values(HapticGenerator::VibratorScale::MUTE),
+ testing::Values(HapticGenerator::VibratorScale::NONE),
testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT),
testing::Values(MIN_FLOAT)),
[](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
@@ -236,9 +236,202 @@
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
return name;
});
-
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorParamTest);
+// Test HapticScale[] hapticScales parameter
+using HapticGeneratorScalesTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>>;
+class HapticGeneratorScalesTest : public ::testing::TestWithParam<HapticGeneratorScalesTestParam>,
+ public EffectHelper {
+ public:
+ HapticGeneratorScalesTest() {
+ 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::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, std::nullopt, &ret, EX_NONE));
+ ASSERT_NE(nullptr, mEffect);
+ }
+
+ void TearDown() override {
+ ASSERT_NO_FATAL_FAILURE(close(mEffect));
+ ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ CleanUp();
+ }
+
+ static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+ std::shared_ptr<IFactory> mFactory;
+ std::shared_ptr<IEffect> mEffect;
+ Descriptor mDescriptor;
+
+ void addHapticScaleParam(std::vector<HapticGenerator::HapticScale> scales) {
+ mHapticScales.push_back(HapticGenerator::make<HapticGenerator::hapticScales>(scales));
+ for (const auto& scale : scales) {
+ expectMap.insert_or_assign(scale.id, scale.scale);
+ }
+ }
+
+ void SetHapticScaleParameters() {
+ // std::unordered_set<HapticGenerator::HapticScale> target;
+ for (auto& it : mHapticScales) {
+ Parameter::Specific specific =
+ Parameter::Specific::make<Parameter::Specific::hapticGenerator>(it);
+ Parameter param = Parameter::make<Parameter::specific>(specific);
+ EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
+ }
+ }
+
+ void checkHapticScaleParameter() {
+ // get parameter
+ Parameter targetParam;
+ HapticGenerator::Id hgId = HapticGenerator::Id::make<HapticGenerator::Id::commonTag>(
+ HapticGenerator::hapticScales);
+ Parameter::Id id = Parameter::Id::make<Parameter::Id::hapticGeneratorTag>(hgId);
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &targetParam));
+ ASSERT_EQ(Parameter::specific, targetParam.getTag());
+ Parameter::Specific specific = targetParam.get<Parameter::specific>();
+ ASSERT_EQ(Parameter::Specific::hapticGenerator, specific.getTag());
+ HapticGenerator hg = specific.get<Parameter::Specific::hapticGenerator>();
+ ASSERT_EQ(HapticGenerator::hapticScales, hg.getTag());
+ std::vector<HapticGenerator::HapticScale> scales = hg.get<HapticGenerator::hapticScales>();
+ ASSERT_EQ(scales.size(), expectMap.size());
+ for (const auto& scale : scales) {
+ auto itor = expectMap.find(scale.id);
+ ASSERT_NE(expectMap.end(), itor);
+ ASSERT_EQ(scale.scale, itor->second);
+ expectMap.erase(scale.id);
+ }
+ ASSERT_EQ(0ul, expectMap.size());
+ }
+
+ const static HapticGenerator::HapticScale kHapticScaleWithMinId;
+ const static HapticGenerator::HapticScale kHapticScaleWithMinIdNew;
+ const static HapticGenerator::HapticScale kHapticScale;
+ const static HapticGenerator::HapticScale kHapticScaleNew;
+ const static HapticGenerator::HapticScale kHapticScaleWithMaxId;
+ const static HapticGenerator::HapticScale kHapticScaleWithMaxIdNew;
+
+ std::vector<HapticGenerator> mHapticScales;
+
+ void CleanUp() {
+ mHapticScales.clear();
+ expectMap.clear();
+ }
+
+ private:
+ std::map<int /* trackID */, HapticGenerator::VibratorScale> expectMap;
+};
+
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinId = {
+ .id = MIN_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMinIdNew = {
+ .id = MIN_ID, .scale = HapticGenerator::VibratorScale::VERY_LOW};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScale = {
+ .id = 1, .scale = HapticGenerator::VibratorScale::LOW};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleNew = {
+ .id = 1, .scale = HapticGenerator::VibratorScale::NONE};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxId = {
+ .id = MAX_ID, .scale = HapticGenerator::VibratorScale::VERY_HIGH};
+const HapticGenerator::HapticScale HapticGeneratorScalesTest::kHapticScaleWithMaxIdNew = {
+ .id = MAX_ID, .scale = HapticGenerator::VibratorScale::MUTE};
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateOne) {
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleNew}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMinIdNew}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxIdNew}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateVector) {
+ EXPECT_NO_FATAL_FAILURE(
+ addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
+ {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetAndUpdateMultipleVector) {
+ EXPECT_NO_FATAL_FAILURE(
+ addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(
+ {kHapticScaleNew, kHapticScaleWithMaxIdNew, kHapticScaleWithMinIdNew}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(
+ addHapticScaleParam({kHapticScale, kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetOneAndAddMoreVector) {
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetMultipleAndAddOneVector) {
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScaleWithMaxId, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam({kHapticScale}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+TEST_P(HapticGeneratorScalesTest, SetMultipleVectorRepeat) {
+ EXPECT_NO_FATAL_FAILURE(
+ addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(
+ addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+ EXPECT_NO_FATAL_FAILURE(
+ addHapticScaleParam({kHapticScaleWithMaxId, kHapticScale, kHapticScaleWithMinId}));
+ EXPECT_NO_FATAL_FAILURE(SetHapticScaleParameters());
+
+ EXPECT_NO_FATAL_FAILURE(checkHapticScaleParameter());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ HapticGeneratorScalesTest, HapticGeneratorScalesTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kHapticGeneratorTypeUUID))),
+ [](const testing::TestParamInfo<HapticGeneratorScalesTest::ParamType>& info) {
+ auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+ std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
+ descriptor.common.name + "_UUID_" +
+ descriptor.common.id.uuid.toString();
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HapticGeneratorScalesTest);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 61776b2..090de17 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -44,11 +44,6 @@
* otherwise expect EX_ILLEGAL_ARGUMENT.
*/
-const std::vector<int> kStrengthValues = {
- std::numeric_limits<int>::min(), Virtualizer::MIN_PER_MILLE_STRENGTH - 1,
- Virtualizer::MIN_PER_MILLE_STRENGTH, Virtualizer::MAX_PER_MILLE_STRENGTH,
- Virtualizer::MAX_PER_MILLE_STRENGTH + 1, std::numeric_limits<int>::max()};
-
class VirtualizerParamTest : public ::testing::TestWithParam<VirtualizerParamTestParam>,
public EffectHelper {
public:
@@ -75,8 +70,7 @@
}
Parameter::Specific getDefaultParamSpecific() {
- Virtualizer vr =
- Virtualizer::make<Virtualizer::strengthPm>(Virtualizer::MIN_PER_MILLE_STRENGTH);
+ Virtualizer vr = Virtualizer::make<Virtualizer::strengthPm>(0);
Parameter::Specific specific =
Parameter::Specific::make<Parameter::Specific::virtualizer>(vr);
return specific;
@@ -86,7 +80,7 @@
std::shared_ptr<IFactory> mFactory;
std::shared_ptr<IEffect> mEffect;
Descriptor mDescriptor;
- int mParamStrength = Virtualizer::MIN_PER_MILLE_STRENGTH;
+ int mParamStrength = 0;
void SetAndGetVirtualizerParameters() {
for (auto& it : mTags) {
@@ -141,8 +135,29 @@
}
bool isStrengthInRange(const Virtualizer::Capability& cap, int strength) const {
- return cap.strengthSupported && strength >= Virtualizer::MIN_PER_MILLE_STRENGTH &&
- strength <= Virtualizer::MAX_PER_MILLE_STRENGTH;
+ 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:
@@ -159,7 +174,9 @@
VirtualizerTest, VirtualizerParamTest,
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
IFactory::descriptor, kVirtualizerTypeUUID)),
- testing::ValuesIn(kStrengthValues)),
+ testing::ValuesIn(VirtualizerParamTest::getStrengthTestValues(
+ EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, kVirtualizerTypeUUID)))),
[](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/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 3e82854..34625e7 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -34,17 +34,14 @@
* Here we focus on specific parameter checking, general IEffect interfaces testing performed in
* VtsAudioEffectTargetTest.
*/
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL_DB, PARAM_MUTE };
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL, PARAM_MUTE };
using VolumeParamTestParam =
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int, bool>;
-const std::vector<int> kLevelValues = {Volume::MIN_LEVEL_DB - 1, Volume::MIN_LEVEL_DB, -100,
- Volume::MAX_LEVEL_DB, Volume::MAX_LEVEL_DB + 1};
-
class VolumeParamTest : public ::testing::TestWithParam<VolumeParamTestParam>, public EffectHelper {
public:
VolumeParamTest()
- : mParamLevel(std::get<PARAM_LEVEL_DB>(GetParam())),
+ : mParamLevel(std::get<PARAM_LEVEL>(GetParam())),
mParamMute(std::get<PARAM_MUTE>(GetParam())) {
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
}
@@ -67,7 +64,7 @@
}
Parameter::Specific getDefaultParamSpecific() {
- Volume vol = Volume::make<Volume::levelDb>(Volume::MIN_LEVEL_DB);
+ Volume vol = Volume::make<Volume::levelDb>(-9600);
Parameter::Specific specific = Parameter::Specific::make<Parameter::Specific::volume>(vol);
return specific;
}
@@ -87,6 +84,8 @@
// 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 binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
@@ -97,7 +96,7 @@
expectParam.set<Parameter::specific>(specific);
EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
- // only get if parameter in range and set success
+ // only get if parameter is in range and set success
if (expected == EX_NONE) {
Parameter getParam;
Parameter::Id id;
@@ -124,6 +123,11 @@
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) {
@@ -138,9 +142,21 @@
}
}
- bool isLevelInRange(const Volume::Capability& cap, int level) const {
- return level >= Volume::MIN_LEVEL_DB && level <= Volume::MAX_LEVEL_DB &&
- level <= cap.maxLevel;
+ 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:
@@ -160,12 +176,16 @@
INSTANTIATE_TEST_SUITE_P(
VolumeTest, VolumeParamTest,
- ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
- IFactory::descriptor, kVolumeTypeUUID)),
- testing::ValuesIn(kLevelValues), testing::Bool()),
+ ::testing::Combine(
+ testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kVolumeTypeUUID)),
+ testing::ValuesIn(VolumeParamTest::getLevelTestValues(
+ EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
+ kVolumeTypeUUID))),
+ testing::Bool() /* mute */),
[](const testing::TestParamInfo<VolumeParamTest::ParamType>& info) {
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
- std::string level = std::to_string(std::get<PARAM_LEVEL_DB>(info.param));
+ std::string level = std::to_string(std::get<PARAM_LEVEL>(info.param));
std::string mute = std::to_string(std::get<PARAM_MUTE>(info.param));
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
descriptor.common.name + "_UUID_" +
diff --git a/audio/common/7.0/enums/OWNERS b/audio/common/7.0/enums/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.0/enums/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/7.0/example/OWNERS b/audio/common/7.0/example/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.0/example/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/7.1/enums/OWNERS b/audio/common/7.1/enums/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/7.1/enums/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/OWNERS b/audio/common/all-versions/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/all-versions/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/default/OWNERS b/audio/common/all-versions/default/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/common/all-versions/default/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/common/all-versions/default/service/android.hardware.audio.service.rc b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
index f859f21..0de4eea 100644
--- a/audio/common/all-versions/default/service/android.hardware.audio.service.rc
+++ b/audio/common/all-versions/default/service/android.hardware.audio.service.rc
@@ -3,7 +3,7 @@
user audioserver
# media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct wakelock context_hub
- capabilities BLOCK_SUSPEND
+ capabilities BLOCK_SUSPEND SYS_NICE
# setting RLIMIT_RTPRIO allows binder RT priority inheritance
rlimit rtprio 10 10
ioprio rt 4
diff --git a/audio/core/all-versions/OWNERS b/audio/core/all-versions/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/core/all-versions/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/core/all-versions/vts/functional/OWNERS b/audio/core/all-versions/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/core/all-versions/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/audio/effect/all-versions/OWNERS b/audio/effect/all-versions/OWNERS
deleted file mode 100644
index f9a2d6b..0000000
--- a/audio/effect/all-versions/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 48436
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index b57dc63..87e1ab7 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -25,8 +25,11 @@
#define ATRACE_TAG ATRACE_TAG_AUDIO
#include <HidlUtils.h>
#include <android/log.h>
+#include <cutils/properties.h>
#include <media/EffectsFactoryApi.h>
#include <mediautils/ScopedStatistics.h>
+#include <sys/syscall.h>
+#include <system/audio_effects/effect_spatializer.h>
#include <util/EffectUtils.h>
#include <utils/Trace.h>
@@ -47,6 +50,160 @@
namespace {
+/**
+ * Some basic scheduling tools.
+ */
+namespace scheduler {
+
+int getCpu() {
+ return sched_getcpu();
+}
+
+uint64_t getAffinity(pid_t tid) {
+ cpu_set_t set;
+ CPU_ZERO_S(sizeof(set), &set);
+
+ if (sched_getaffinity(tid, sizeof(set), &set)) {
+ ALOGW("%s: for tid:%d returning 0, failed %s", __func__, tid, strerror(errno));
+ return 0;
+ }
+ const int count = CPU_COUNT_S(sizeof(set), &set);
+ uint64_t mask = 0;
+ for (int i = 0; i < CPU_SETSIZE; ++i) {
+ if (CPU_ISSET_S(i, sizeof(set), &set)) {
+ mask |= 1 << i;
+ }
+ }
+ ALOGV("%s: for tid:%d returning cpu count %d mask %llu", __func__, tid, count,
+ (unsigned long long)mask);
+ return mask;
+}
+
+status_t setAffinity(pid_t tid, uint64_t mask) {
+ cpu_set_t set;
+ CPU_ZERO_S(sizeof(set), &set);
+
+ for (uint64_t m = mask; m != 0;) {
+ uint64_t tz = __builtin_ctz(m);
+ CPU_SET_S(tz, sizeof(set), &set);
+ m &= ~(1 << tz);
+ }
+ if (sched_setaffinity(tid, sizeof(set), &set)) {
+ ALOGW("%s: for tid:%d setting cpu mask %llu failed %s", __func__, tid,
+ (unsigned long long)mask, strerror(errno));
+ return -errno;
+ }
+ ALOGV("%s: for tid:%d setting cpu mask %llu", __func__, tid, (unsigned long long)mask);
+ return OK;
+}
+
+__unused status_t setPriority(pid_t tid, int policy, int priority) {
+ struct sched_param param {
+ .sched_priority = priority,
+ };
+ if (sched_setscheduler(tid, policy, ¶m) != 0) {
+ ALOGW("%s: Cannot set FIFO priority for tid %d to policy %d priority %d %s", __func__, tid,
+ policy, priority, strerror(errno));
+ return -errno;
+ }
+ ALOGV("%s: Successfully set priority for tid %d to policy %d priority %d", __func__, tid,
+ policy, priority);
+ return NO_ERROR;
+}
+
+status_t setUtilMin(pid_t tid, uint32_t utilMin) {
+ // Currently, there is no wrapper in bionic: b/183240349.
+ struct {
+ uint32_t size;
+ uint32_t sched_policy;
+ uint64_t sched_flags;
+ int32_t sched_nice;
+ uint32_t sched_priority;
+ uint64_t sched_runtime;
+ uint64_t sched_deadline;
+ uint64_t sched_period;
+ uint32_t sched_util_min;
+ uint32_t sched_util_max;
+ } attr{
+ .size = sizeof(attr),
+ .sched_flags = SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP_MIN,
+ .sched_util_min = utilMin,
+ };
+
+ if (syscall(__NR_sched_setattr, tid, &attr, 0 /* flags */)) {
+ ALOGW("%s: Cannot set sched_util_min for pid %d to %u %s", __func__, tid, utilMin,
+ strerror(errno));
+ return -errno;
+ }
+ ALOGV("%s: Successfully set sched_util_min for pid %d to %u", __func__, tid, utilMin);
+ return NO_ERROR;
+}
+
+/*
+ Attempts to raise the priority and usage of tid for spatialization.
+ Returns OK if everything works.
+*/
+status_t updateSpatializerPriority(pid_t tid) {
+ status_t status = OK;
+
+ const int cpu = getCpu();
+ ALOGV("%s: current CPU:%d", __func__, cpu);
+
+ const auto currentAffinity = getAffinity(tid);
+ ALOGV("%s: current Affinity:%llx", __func__, (unsigned long long)currentAffinity);
+
+ // Set the desired CPU core affinity.
+ // Typically this would be done to move the Spatializer effect off of the little cores.
+ // The mid cores and large cores typically have more FP/NEON units
+ // and will advantageously reduce power and prevent glitches due CPU limitations.
+ //
+ // Since this is SOC dependent, we do not set the core affinity here but
+ // prefer to set the util_clamp_min below.
+ //
+ constexpr uint64_t kDefaultAffinity = 0;
+ const int32_t desiredAffinity =
+ property_get_int32("audio.spatializer.effect.affinity", kDefaultAffinity);
+ if (desiredAffinity != 0 && (desiredAffinity & ~currentAffinity) == 0) {
+ const status_t localStatus = setAffinity(tid, desiredAffinity);
+ status = status ? status : localStatus;
+ }
+
+ // Set the util_clamp_min.
+ // This is beneficial to reduce glitches when starting up, or due to scheduler
+ // thread statistics reset (e.g. core migration), which cause the CPU frequency to drop
+ // to minimum.
+ //
+ // Experimentation has found that moving to a mid core over a little core reduces
+ // power if the mid core (e.g. A76/78) has more (e.g. 2x) FP/NEON units
+ // than the little core (e.g. A55).
+ // A possible value is 300.
+ //
+ constexpr uint32_t kUtilMin = 0;
+ const int32_t utilMin = property_get_int32("audio.spatializer.effect.util_clamp_min", kUtilMin);
+ if (utilMin > 0 && utilMin <= 1024) {
+ const status_t localStatus = setUtilMin(tid, utilMin);
+ status = status ? status : localStatus;
+ }
+
+#if 0
+ // Provided for local vendor testing but not enabled as audioserver does this for us.
+ //
+ // Set priority if specified.
+ constexpr int32_t kRTPriorityMin = 1;
+ constexpr int32_t kRTPriorityMax = 3;
+ const int32_t priorityBoost =
+ property_get_int32("audio.spatializer.priority", kRTPriorityMin);
+ if (priorityBoost >= kRTPriorityMin && priorityBoost <= kRTPriorityMax) {
+ const status_t localStatus = scheduler::setPriority(threadId, SCHED_FIFO, priorityBoost);
+ status = status ? status : localStatus;
+ }
+#endif
+
+ return status;
+}
+
+} // namespace scheduler
+
#define SCOPED_STATS() \
::android::mediautils::ScopedStatistics scopedStatistics { \
std::string("EffectHal::").append(__func__), mEffectHal->mStatistics \
@@ -83,6 +240,16 @@
};
bool ProcessThread::threadLoop() {
+ // For a spatializer effect, we perform scheduler adjustments to reduce glitches and power.
+ {
+ effect_descriptor_t halDescriptor{};
+ if ((*mEffect)->get_descriptor(mEffect, &halDescriptor) == NO_ERROR &&
+ memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) {
+ const status_t status = scheduler::updateSpatializerPriority(gettid());
+ ALOGW_IF(status != OK, "Failed to update Spatializer priority");
+ }
+ }
+
// This implementation doesn't return control back to the Thread until it decides to stop,
// as the Thread uses mutexes, and this can lead to priority inversion.
while (!std::atomic_load_explicit(mStop, std::memory_order_acquire)) {
@@ -700,8 +867,21 @@
void* dataPtr = halDataSize > 0 ? &halData[0] : NULL;
void* resultPtr = halResultSize > 0 ? &halResult[0] : NULL;
- status_t status =
- (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize, resultPtr);
+ status_t status = BAD_VALUE;
+ switch (commandId) {
+ case 'gtid': // retrieve the tid, used for spatializer priority boost
+ if (halDataSize == 0 && resultMaxSize == sizeof(int32_t)) {
+ auto ptid = (int32_t*)resultPtr;
+ ptid[0] = mProcessThread ? mProcessThread->getTid() : -1;
+ status = OK;
+ break; // we have handled 'gtid' here.
+ }
+ [[fallthrough]]; // allow 'gtid' overload (checked halDataSize and resultMaxSize).
+ default:
+ status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize,
+ resultPtr);
+ break;
+ }
hidl_vec<uint8_t> result;
if (status == OK && resultPtr != NULL) {
result.setToExternal(&halResult[0], halResultSize);
diff --git a/audio/effect/all-versions/vts/functional/OWNERS b/audio/effect/all-versions/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/effect/all-versions/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/audio/policy/1.0/vts/OWNERS b/audio/policy/1.0/vts/OWNERS
deleted file mode 100644
index 24071af..0000000
--- a/audio/policy/1.0/vts/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-elaurent@google.com
-mnaganov@google.com
diff --git a/audio/policy/1.0/vts/functional/OWNERS b/audio/policy/1.0/vts/functional/OWNERS
deleted file mode 100644
index 448d9fe..0000000
--- a/audio/policy/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 48436
-mnaganov@google.com
diff --git a/camera/common/aidl/Android.bp b/camera/common/aidl/Android.bp
index d21ae58..fa74392 100644
--- a/camera/common/aidl/Android.bp
+++ b/camera/common/aidl/Android.bp
@@ -11,6 +11,7 @@
name: "android.hardware.camera.common",
vendor_available: true,
srcs: ["android/hardware/camera/common/*.aidl"],
+ frozen: true,
stability: "vintf",
backend: {
cpp: {
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 6115d53..461e89d 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -11,13 +11,14 @@
name: "android.hardware.camera.device",
vendor_available: true,
srcs: ["android/hardware/camera/device/*.aidl"],
+ frozen: true,
stability: "vintf",
imports: [
"android.hardware.common-V2",
"android.hardware.common.fmq-V1",
- "android.hardware.camera.common",
- "android.hardware.camera.metadata",
- "android.hardware.graphics.common",
+ "android.hardware.camera.common-V1",
+ "android.hardware.camera.metadata-V1",
+ "android.hardware.graphics.common-V4",
],
backend: {
cpp: {
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index 301a943..8c13ce5 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -11,6 +11,7 @@
name: "android.hardware.camera.metadata",
vendor_available: true,
srcs: ["android/hardware/camera/metadata/*.aidl"],
+ frozen: true,
stability: "vintf",
backend: {
cpp: {
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index 87a94b2..e2c2bea 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -14,8 +14,8 @@
"android/hardware/camera/provider/*.aidl",
],
imports: [
- "android.hardware.camera.device",
- "android.hardware.camera.common",
+ "android.hardware.camera.device-V1",
+ "android.hardware.camera.common-V1",
],
stability: "vintf",
backend: {
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5e1589b..267c762 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -829,4 +829,12 @@
<instance>default</instance>
</interface>
</hal>
+ <hal format="native">
+ <name>mapper</name>
+ <version>1.0</version>
+ <interface>
+ <name>I</name>
+ <regex-instance>.*</regex-instance>
+ </interface>
+ </hal>
</compatibility-matrix>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index cf1e138..3c0c5f1 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -52,6 +52,7 @@
"android.hardware.radio.config@1.2",
// AIDL
"android.hardware.audio.common",
+ "android.hardware.audio.core.sounddose",
"android.hardware.biometrics.common",
"android.hardware.camera.metadata",
"android.hardware.camera.device",
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index e7f5a0f..88badc7 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -57,6 +57,7 @@
srcs: [
"AttestKeyTest.cpp",
"DeviceUniqueAttestationTest.cpp",
+ "KeyBlobUpgradeTest.cpp",
"KeyMintTest.cpp",
"SecureElementProvisioningTest.cpp",
],
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
new file mode 100644
index 0000000..c952012
--- /dev/null
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -0,0 +1,609 @@
+/*
+ * 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.
+ */
+
+// The tests in this file are intended to be run manually, to allow testing of whether
+// keyblob upgrade works correctly. The manual procedure is roughly:
+//
+// 1) Run the "*Before*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
+// so that keyblobs are saved to a directory on the device:
+//
+// VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*Before*" \
+// --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// All tests should pass, and the `UpgradeKeyBlobs` test should indicate that no keyblob
+// upgrades were needed.
+//
+// 2) Copy the generated keyblobs off the device into a safe place.
+//
+// adb pull /data/local/tmp/keymint-blobs
+//
+// 3) Upgrade the device to a new version.
+//
+// 4) Push the saved keyblobs back onto the upgraded device.
+//
+// adb push keymint-blobs /data/local/tmp/keymint-blobs
+//
+// 5) Run the "*After*" subset of these tests with the `--keyblob_dir <dir>` command-line argument
+// pointing to the directory with the keyblobs:
+//
+// VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest*After*" \
+// --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// (Note that this skips the `CreateKeyBlobs` test, which would otherwise replace the saved
+// keyblobs with freshly generated ones.).
+//
+// All tests should pass, and the `UpgradeKeyBlobs` test should have output that matches whether
+// upgrade was expected or not.
+
+#define LOG_TAG "keymint_1_test"
+#include <cutils/log.h>
+
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+#include <unistd.h>
+
+#include <openssl/curve25519.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+#include <openssl/x509v3.h>
+
+#include "KeyMintAidlTestBase.h"
+
+using aidl::android::hardware::security::keymint::KeyCharacteristics;
+
+namespace aidl::android::hardware::security::keymint::test {
+
+namespace {
+
+std::vector<std::string> keyblob_names_tee = {
+ "aes-key", "aes-key-rr", "des-key", "hmac-key",
+ "rsa-key", "p256-key", "ed25519-key", "x25519-key",
+ "rsa-attest-key", "p256-attest-key", "ed25519-attest-key"};
+
+std::vector<std::string> keyblob_names_sb = {"aes-key", "aes-key-rr", "des-key",
+ "hmac-key", "rsa-key", "p256-key",
+ "rsa-attest-key", "p256-attest-key"};
+
+const std::vector<std::string>& keyblob_names(SecurityLevel sec_level) {
+ if (sec_level == SecurityLevel::STRONGBOX) {
+ return keyblob_names_sb;
+ } else {
+ return keyblob_names_tee;
+ }
+}
+
+bool requires_rr(const std::string& name) {
+ return name.find("-rr") != std::string::npos;
+}
+
+bool is_asymmetric(const std::string& name) {
+ return (name.find("rsa") != std::string::npos || name.find("25519") != std::string::npos ||
+ name.find("p256") != std::string::npos);
+}
+
+std::string keyblob_subdir(const std::string& keyblob_dir, const std::string& full_name,
+ bool create) {
+ if (keyblob_dir.empty()) {
+ return "";
+ }
+
+ // Use a subdirectory for the specific instance, so two different KeyMint instances won't
+ // clash with each other.
+ size_t found = full_name.find_last_of('/');
+ std::string subdir = keyblob_dir + "/" + full_name.substr(found + 1);
+
+ if (create) {
+ mkdir(keyblob_dir.c_str(), 0777);
+ mkdir(subdir.c_str(), 0777);
+ }
+ return subdir;
+}
+
+void save_keyblob(const std::string& subdir, const std::string& name,
+ const vector<uint8_t>& keyblob,
+ const std::vector<KeyCharacteristics>& key_characteristics) {
+ // Write the keyblob out to a file.
+ std::string blobname(subdir + "/" + name + ".keyblob");
+ std::ofstream blobfile(blobname, std::ios::out | std::ios::trunc | std::ios::binary);
+ blobfile.write(reinterpret_cast<const char*>(keyblob.data()), keyblob.size());
+ blobfile.close();
+
+ // Dump the characteristics too.
+ std::string charsname(subdir + "/" + name + ".chars");
+ std::ofstream charsfile(charsname, std::ios::out | std::ios::trunc);
+ charsfile << "{\n";
+ for (const auto& characteristic : key_characteristics) {
+ charsfile << " " << characteristic.toString() << "\n";
+ }
+ charsfile << "}\n";
+ charsfile.close();
+
+ // Also write out a hexdump of the keyblob for convenience.
+ std::string hexname(subdir + "/" + name + ".hex");
+ std::ofstream hexfile(hexname, std::ios::out | std::ios::trunc);
+ hexfile << bin2hex(keyblob) << "\n";
+ hexfile.close();
+}
+
+void save_keyblob_and_cert(const std::string& subdir, const std::string& name,
+ const vector<uint8_t>& keyblob,
+ const std::vector<KeyCharacteristics>& key_characteristics,
+ const std::vector<Certificate>& cert_chain) {
+ save_keyblob(subdir, name, keyblob, key_characteristics);
+
+ if (is_asymmetric(name)) {
+ // Dump the leaf certificate as DER.
+ if (cert_chain.empty()) {
+ FAIL() << "No cert available for " << name;
+ } else {
+ const vector<uint8_t>& certdata = cert_chain[0].encodedCertificate;
+ std::string certname(subdir + "/" + name + ".cert");
+ std::ofstream certfile(certname, std::ios::out | std::ios::trunc | std::ios::binary);
+ certfile.write(reinterpret_cast<const char*>(certdata.data()), certdata.size());
+ certfile.close();
+ }
+ }
+}
+
+void delete_keyblob(const std::string& subdir, const std::string& name) {
+ std::string blobname(subdir + "/" + name + ".keyblob");
+ unlink(blobname.c_str());
+ std::string charsname(subdir + "/" + name + ".chars");
+ unlink(charsname.c_str());
+ std::string hexname(subdir + "/" + name + ".hex");
+ unlink(hexname.c_str());
+ std::string certname(subdir + "/" + name + ".cert");
+ unlink(certname.c_str());
+}
+
+std::vector<uint8_t> load_file(const std::string& subdir, const std::string& name,
+ const std::string& suffix) {
+ std::string blobname(subdir + "/" + name + suffix);
+ std::ifstream blobfile(blobname, std::ios::in | std::ios::binary);
+
+ std::vector<uint8_t> data((std::istreambuf_iterator<char>(blobfile)),
+ std::istreambuf_iterator<char>());
+ return data;
+}
+
+std::vector<uint8_t> load_keyblob(const std::string& subdir, const std::string& name) {
+ return load_file(subdir, name, ".keyblob");
+}
+
+std::vector<uint8_t> load_cert(const std::string& subdir, const std::string& name) {
+ return load_file(subdir, name, ".cert");
+}
+
+} // namespace
+
+class KeyBlobUpgradeTest : public KeyMintAidlTestBase {
+ protected:
+ void UpgradeKeyBlobs(bool expectUpgrade) {
+ std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+ if (subdir.empty()) {
+ GTEST_SKIP() << "No keyblob directory provided";
+ }
+
+ for (std::string name : keyblob_names(SecLevel())) {
+ for (bool with_hidden : {false, true}) {
+ std::string app_id;
+ std::string app_data;
+ auto builder = AuthorizationSetBuilder();
+ if (with_hidden) {
+ // Build a variant keyblob that requires app_id/app_data
+ app_id = "appid";
+ app_data = "appdata";
+ builder.Authorization(TAG_APPLICATION_ID, "appid")
+ .Authorization(TAG_APPLICATION_DATA, "appdata");
+ name += "-hidden";
+ }
+ SCOPED_TRACE(testing::Message() << name);
+
+ // Load the old format keyblob.
+ std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+ if (keyblob.empty()) {
+ if (requires_rr(name)) {
+ std::cerr << "Skipping missing keyblob file '" << name
+ << "', assuming rollback resistance unavailable\n";
+ } else {
+ FAIL() << "Missing keyblob file '" << name << "'";
+ }
+ continue;
+ }
+
+ // An upgrade will either produce a new keyblob or no data (if upgrade isn't
+ // needed).
+ std::vector<uint8_t> upgraded_keyblob;
+ Status result =
+ keymint_->upgradeKey(keyblob, builder.vector_data(), &upgraded_keyblob);
+ ASSERT_EQ(ErrorCode::OK, GetReturnErrorCode(result));
+
+ if (upgraded_keyblob.empty()) {
+ std::cerr << "Keyblob '" << name << "' did not require upgrade\n";
+ EXPECT_TRUE(!expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
+ } else {
+ // Ensure the old format keyblob is deleted (so any secure deletion data is
+ // cleaned up).
+ EXPECT_EQ(ErrorCode::OK, DeleteKey(&keyblob));
+
+ std::vector<uint8_t> app_id_v(app_id.begin(), app_id.end());
+ std::vector<uint8_t> app_data_v(app_data.begin(), app_data.end());
+ std::vector<KeyCharacteristics> key_characteristics;
+ result = keymint_->getKeyCharacteristics(upgraded_keyblob, app_id_v, app_data_v,
+ &key_characteristics);
+ ASSERT_EQ(ErrorCode::OK, GetReturnErrorCode(result))
+ << "Failed getKeyCharacteristics() after upgrade";
+
+ save_keyblob(subdir, name, upgraded_keyblob, key_characteristics);
+ // Cert file is left unchanged.
+ std::cerr << "Keyblob '" << name << "' upgraded\n";
+ EXPECT_TRUE(expectUpgrade)
+ << "Keyblob '" << name << "' unexpectedly left as-is";
+ }
+ }
+ }
+ }
+};
+
+// To save off keyblobs before upgrade, use:
+//
+// VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.CreateKeyBlobs*" \
+// --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// Then copy the contents of the /data/local/tmp/keymint-blobs/ directory somewhere safe:
+//
+// adb pull /data/local/tmp/keymint-blobs/
+TEST_P(KeyBlobUpgradeTest, CreateKeyBlobsBefore) {
+ std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ true);
+
+ std::map<const std::string, AuthorizationSetBuilder> keys_info = {
+ {"aes-key", AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_NO_AUTH_REQUIRED)},
+ {"aes-key-rr", AuthorizationSetBuilder()
+ .AesEncryptionKey(256)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_ROLLBACK_RESISTANCE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)},
+ {"des-key", AuthorizationSetBuilder()
+ .TripleDesEncryptionKey(168)
+ .BlockMode(BlockMode::ECB)
+ .Padding(PaddingMode::PKCS7)
+ .Authorization(TAG_NO_AUTH_REQUIRED)},
+ {"hmac-key", AuthorizationSetBuilder()
+ .HmacKey(128)
+ .Digest(Digest::SHA1)
+ .Authorization(TAG_MIN_MAC_LENGTH, 128)
+ .Authorization(TAG_NO_AUTH_REQUIRED)},
+ {"rsa-key", AuthorizationSetBuilder()
+ .RsaEncryptionKey(2048, 65537)
+ .Authorization(TAG_PURPOSE, KeyPurpose::SIGN)
+ .Digest(Digest::NONE)
+ .Digest(Digest::SHA1)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity()},
+ {
+ "p256-key",
+ AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+ .Digest(Digest::NONE)
+ .Digest(Digest::SHA1)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ },
+ {
+ "ed25519-key",
+ AuthorizationSetBuilder()
+ .EcdsaSigningKey(EcCurve::CURVE_25519)
+ .Digest(Digest::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ },
+ {"x25519-key", AuthorizationSetBuilder()
+ .Authorization(TAG_EC_CURVE, EcCurve::CURVE_25519)
+ .Authorization(TAG_PURPOSE, KeyPurpose::AGREE_KEY)
+ .Authorization(TAG_ALGORITHM, Algorithm::EC)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity()},
+ {"rsa-attest-key", AuthorizationSetBuilder()
+ .RsaKey(2048, 65537)
+ .AttestKey()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity()},
+ {
+ "p256-attest-key",
+ AuthorizationSetBuilder()
+ .EcdsaKey(EcCurve::P_256)
+ .AttestKey()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ },
+ {
+ "ed25519-attest-key",
+ AuthorizationSetBuilder()
+ .EcdsaKey(EcCurve::CURVE_25519)
+ .AttestKey()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .SetDefaultValidity(),
+ }};
+
+ for (std::string name : keyblob_names(SecLevel())) {
+ auto entry = keys_info.find(name);
+ ASSERT_NE(entry, keys_info.end()) << "no builder for " << name;
+ auto builder = entry->second;
+ for (bool with_hidden : {false, true}) {
+ if (with_hidden) {
+ // Build a variant keyblob that requires app_id/app_data
+ builder.Authorization(TAG_APPLICATION_ID, "appid")
+ .Authorization(TAG_APPLICATION_DATA, "appdata");
+ name += "-hidden";
+ }
+ SCOPED_TRACE(testing::Message() << name);
+
+ vector<uint8_t> keyblob;
+ vector<KeyCharacteristics> key_characteristics;
+ vector<Certificate> cert_chain;
+ auto result =
+ GenerateKey(builder, std::nullopt, &keyblob, &key_characteristics, &cert_chain);
+
+ if (requires_rr(name) && result == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE) {
+ // Rollback resistance support is optional.
+ std::cerr << "Skipping '" << name << "' key as rollback resistance unavailable\n";
+ continue;
+ }
+ ASSERT_EQ(ErrorCode::OK, result) << " failed for " << name;
+
+ if (!subdir.empty()) {
+ save_keyblob_and_cert(subdir, name, keyblob, key_characteristics, cert_chain);
+ }
+ }
+ }
+
+ if (!subdir.empty()) {
+ std::cerr << "Save generated keyblobs with:\n\n adb pull " << keyblob_dir << "\n\n";
+ }
+}
+
+TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsBefore) {
+ // Check that attempting to upgrade valid keyblobs does nothing.
+ UpgradeKeyBlobs(/* expectUpgrade= */ false);
+}
+
+// To run this test:
+//
+// - save off some keyblobs before upgrade as per the CreateKeyBlobs test above.
+// - upgrade the device to a version that should trigger keyblob upgrade (e.g. different patchlevel)
+// - put the saved keyblobs back onto the upgraded device:
+//
+// adb push keymint-blobs /data/local/tmp/keymint-blobs
+//
+// - run the test with:
+//
+// VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UpgradeKeyBlobsAfter*" \
+// --keyblob_dir /data/local/tmp/keymint-blobs
+//
+// - this replaces the keyblob contents in that directory; if needed, save the upgraded keyblobs
+// with:
+// adb pull /data/local/tmp/keymint-blobs/
+TEST_P(KeyBlobUpgradeTest, UpgradeKeyBlobsAfter) {
+ UpgradeKeyBlobs(/* expectUpgrade= */ true);
+}
+
+// To run this test:
+//
+// - save off some keyblobs before upgrade as per the CreateKeyBlobs test above
+// - if needed, upgrade the saved keyblobs as per the UpgradeKeyBlobs test above
+// - run the test with:
+//
+// VtsAidlKeyMintTargetTest --gtest_filter="*KeyBlobUpgradeTest.UseKeyBlobs*" \
+// --keyblob_dir /data/local/tmp/keymint-blobs
+TEST_P(KeyBlobUpgradeTest, UseKeyBlobsBeforeOrAfter) {
+ std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+ if (subdir.empty()) {
+ GTEST_SKIP() << "No keyblob directory provided with (e.g.) --keyblob_dir "
+ "/data/local/tmp/keymint-blobs";
+ }
+
+ for (std::string name : keyblob_names(SecLevel())) {
+ for (bool with_hidden : {false, true}) {
+ auto builder = AuthorizationSetBuilder();
+ if (with_hidden) {
+ // Build a variant keyblob that requires app_id/app_data
+ builder.Authorization(TAG_APPLICATION_ID, "appid")
+ .Authorization(TAG_APPLICATION_DATA, "appdata");
+ name += "-hidden";
+ }
+ SCOPED_TRACE(testing::Message() << name);
+ std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+ if (keyblob.empty()) {
+ if (requires_rr(name)) {
+ std::cerr << "Skipping missing keyblob file '" << name
+ << "', assuming rollback resistance unavailable\n";
+ } else {
+ FAIL() << "Missing keyblob file '" << name << "'";
+ }
+ continue;
+ }
+
+ std::vector<uint8_t> cert;
+ if (is_asymmetric(name)) {
+ cert = load_cert(subdir, name);
+ }
+
+ // Perform an algorithm-specific operation with the keyblob.
+ string message = "Hello World!";
+ AuthorizationSet out_params;
+ if (name.find("aes-key") != std::string::npos) {
+ builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ string ciphertext = EncryptMessage(keyblob, message, builder, &out_params);
+ string plaintext = DecryptMessage(keyblob, ciphertext, builder);
+ EXPECT_EQ(message, plaintext);
+ } else if (name.find("des-key") != std::string::npos) {
+ builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ string ciphertext = EncryptMessage(keyblob, message, builder, &out_params);
+ string plaintext = DecryptMessage(keyblob, ciphertext, builder);
+ EXPECT_EQ(message, plaintext);
+ } else if (name.find("hmac-key") != std::string::npos) {
+ builder.Digest(Digest::SHA1);
+ auto sign_builder = builder;
+ sign_builder.Authorization(TAG_MAC_LENGTH, 128);
+ string tag = SignMessage(keyblob, message, sign_builder);
+ VerifyMessage(keyblob, message, tag, builder);
+ } else if (name.find("rsa-key") != std::string::npos) {
+ builder.Digest(Digest::NONE).Padding(PaddingMode::NONE);
+ string signature = SignMessage(keyblob, message, builder);
+ LocalVerifyMessage(cert, message, signature, builder);
+ } else if (name.find("p256-key") != std::string::npos) {
+ builder.Digest(Digest::SHA1);
+ string signature = SignMessage(keyblob, message, builder);
+ LocalVerifyMessage(cert, message, signature, builder);
+ } else if (name.find("ed25519-key") != std::string::npos) {
+ builder.Digest(Digest::NONE);
+ string signature = SignMessage(keyblob, message, builder);
+ LocalVerifyMessage(cert, message, signature, builder);
+ } else if (name.find("x25519-key") != std::string::npos) {
+ // Generate EC key on same curve locally (with access to private key material).
+ uint8_t localPrivKeyData[32];
+ uint8_t localPubKeyData[32];
+ X25519_keypair(localPubKeyData, localPrivKeyData);
+ EVP_PKEY_Ptr localPrivKey(EVP_PKEY_new_raw_private_key(
+ EVP_PKEY_X25519, nullptr, localPrivKeyData, sizeof(localPrivKeyData)));
+ // Get encoded form of the public part of the locally generated key.
+ unsigned char* p = nullptr;
+ int localPublicKeySize = i2d_PUBKEY(localPrivKey.get(), &p);
+ ASSERT_GT(localPublicKeySize, 0);
+ vector<uint8_t> localPublicKey(
+ reinterpret_cast<const uint8_t*>(p),
+ reinterpret_cast<const uint8_t*>(p + localPublicKeySize));
+ OPENSSL_free(p);
+
+ // Agree on a key between local and KeyMint.
+ string data;
+ ASSERT_EQ(ErrorCode::OK,
+ Begin(KeyPurpose::AGREE_KEY, keyblob, builder, &out_params));
+ ASSERT_EQ(ErrorCode::OK,
+ Finish(string(localPublicKey.begin(), localPublicKey.end()), &data));
+ vector<uint8_t> keymint_data(data.begin(), data.end());
+
+ // Extract the public key for the KeyMint key from the cert.
+ X509_Ptr kmKeyCert(parse_cert_blob(cert));
+ ASSERT_NE(kmKeyCert, nullptr);
+ EVP_PKEY_Ptr kmPubKey = EVP_PKEY_Ptr(X509_get_pubkey(kmKeyCert.get()));
+ ASSERT_NE(kmPubKey.get(), nullptr);
+
+ size_t kmPubKeySize = 32;
+ uint8_t kmPubKeyData[32];
+ ASSERT_EQ(1,
+ EVP_PKEY_get_raw_public_key(kmPubKey.get(), kmPubKeyData, &kmPubKeySize));
+ ASSERT_EQ(kmPubKeySize, 32);
+
+ // Agree on a key between KeyMint and local.
+ uint8_t sharedKey[32];
+ ASSERT_EQ(1, X25519(sharedKey, localPrivKeyData, kmPubKeyData));
+ vector<uint8_t> local_data(sharedKey, sharedKey + 32);
+
+ // Both ways round should agree.
+ EXPECT_EQ(keymint_data, local_data);
+ } else if (name.find("-attest-key") != std::string::npos) {
+ // Covers rsa-attest-key, p256-attest-key, ed25519-attest-key.
+
+ // Use attestation key to sign RSA signing key
+ AttestationKey attest_key;
+ attest_key.keyBlob = keyblob;
+ attest_key.attestKeyParams = builder.vector_data();
+ attest_key.issuerSubjectName = make_name_from_str("Android Keystore Key");
+ vector<uint8_t> attested_key_blob;
+ vector<KeyCharacteristics> attested_key_characteristics;
+ vector<Certificate> attested_key_cert_chain;
+ EXPECT_EQ(ErrorCode::OK,
+ GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .AttestationChallenge("challenge")
+ .AttestationApplicationId("app-id")
+ .SetDefaultValidity(),
+ attest_key, &attested_key_blob, &attested_key_characteristics,
+ &attested_key_cert_chain));
+ CheckedDeleteKey(&attested_key_blob);
+ } else {
+ FAIL() << "Unexpected name: " << name;
+ }
+ }
+ }
+}
+
+// This test target deletes any keys from the keyblob subdirectory that have rollback resistance
+// enabled.
+TEST_P(KeyBlobUpgradeTest, DeleteRRKeyBlobsAfter) {
+ std::string subdir = keyblob_subdir(keyblob_dir, GetParam(), /* create? */ false);
+ if (subdir.empty()) {
+ GTEST_SKIP() << "No keyblob directory provided with (e.g.) --keyblob_dir "
+ "/data/local/tmp/keymint-blobs";
+ }
+
+ for (std::string name : keyblob_names(SecLevel())) {
+ for (bool with_hidden : {false, true}) {
+ auto builder = AuthorizationSetBuilder();
+ if (with_hidden) {
+ // Build a variant keyblob that requires app_id/app_data
+ builder.Authorization(TAG_APPLICATION_ID, "appid")
+ .Authorization(TAG_APPLICATION_DATA, "appdata");
+ name += "-hidden";
+ }
+ if (!requires_rr(name)) {
+ std::cerr << "Skipping keyblob file '" << name
+ << "' which does not use rollback resistance\n";
+ continue;
+ }
+ SCOPED_TRACE(testing::Message() << name);
+ std::vector<uint8_t> keyblob = load_keyblob(subdir, name);
+ if (keyblob.empty()) {
+ std::cerr << "Skipping missing keyblob file '" << name
+ << "', assuming rollback resistance unavailable\n";
+ continue;
+ }
+
+ // Delete the key
+ ASSERT_EQ(ErrorCode::OK, DeleteKey(&keyblob));
+
+ // Remove all files relating to the deleted key.
+ std::cerr << "Deleting files for deleted key '" << name << ";";
+ delete_keyblob(subdir, name);
+
+ // Attempting to use the keyblob after deletion should fail.
+ AuthorizationSet out_params;
+ if (name.find("aes-key") != std::string::npos) {
+ builder.BlockMode(BlockMode::ECB).Padding(PaddingMode::PKCS7);
+ EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
+ Begin(KeyPurpose::ENCRYPT, keyblob, builder, &out_params));
+ } else {
+ FAIL() << "Unexpected name: " << name;
+ }
+ }
+ }
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(KeyBlobUpgradeTest);
+
+} // 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 43ad30a..6c012fa 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -184,6 +184,7 @@
bool KeyMintAidlTestBase::arm_deleteAllKeys = false;
bool KeyMintAidlTestBase::dump_Attestations = false;
+std::string KeyMintAidlTestBase::keyblob_dir;
uint32_t KeyMintAidlTestBase::boot_patch_level(
const vector<KeyCharacteristics>& key_characteristics) {
@@ -946,9 +947,15 @@
const AuthorizationSet& params) {
SCOPED_TRACE("LocalVerifyMessage");
- // Retrieve the public key from the leaf certificate.
ASSERT_GT(cert_chain_.size(), 0);
- X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+ LocalVerifyMessage(cert_chain_[0].encodedCertificate, message, signature, params);
+}
+
+void KeyMintAidlTestBase::LocalVerifyMessage(const vector<uint8_t>& der_cert, const string& message,
+ const string& signature,
+ const AuthorizationSet& params) {
+ // Retrieve the public key from the leaf certificate.
+ X509_Ptr key_cert(parse_cert_blob(der_cert));
ASSERT_TRUE(key_cert.get());
EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
ASSERT_TRUE(pub_key.get());
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 5b09ca5..908eeab 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -64,6 +64,10 @@
static bool arm_deleteAllKeys;
static bool dump_Attestations;
+ // Directory to store/retrieve keyblobs, using subdirectories named for the
+ // KeyMint instance in question (e.g. "./default/", "./strongbox/").
+ static std::string keyblob_dir;
+
void SetUp() override;
void TearDown() override {
if (key_blob_.size()) {
@@ -206,6 +210,8 @@
const string& signature, const AuthorizationSet& params);
void VerifyMessage(const string& message, const string& signature,
const AuthorizationSet& params);
+ void LocalVerifyMessage(const vector<uint8_t>& der_cert, const string& message,
+ const string& signature, const AuthorizationSet& params);
void LocalVerifyMessage(const string& message, const string& signature,
const AuthorizationSet& params);
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index ca18082..342b926 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -8649,6 +8649,15 @@
// interactions.
aidl::android::hardware::security::keymint::test::check_boot_pl = false;
}
+ if (std::string(argv[i]) == "--keyblob_dir") {
+ if (i + 1 >= argc) {
+ std::cerr << "Missing argument for --keyblob_dir\n";
+ return 1;
+ }
+ aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::keyblob_dir =
+ std::string(argv[i + 1]);
+ ++i;
+ }
}
}
return RUN_ALL_TESTS();
diff --git a/sensors/1.0/default/OWNERS b/sensors/1.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/1.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/1.0/vts/functional/OWNERS b/sensors/1.0/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/1.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/2.0/default/OWNERS b/sensors/2.0/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/2.0/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/2.0/multihal/OWNERS b/sensors/2.0/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/2.0/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/2.0/vts/functional/OWNERS b/sensors/2.0/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/2.0/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/2.1/default/OWNERS b/sensors/2.1/default/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/2.1/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/2.1/multihal/OWNERS b/sensors/2.1/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/2.1/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/2.1/vts/functional/OWNERS b/sensors/2.1/vts/functional/OWNERS
deleted file mode 100644
index e20125b..0000000
--- a/sensors/2.1/vts/functional/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-# Bug component: 62965
-include ../../../common/vts/OWNERS
diff --git a/sensors/common/vts/OWNERS b/sensors/OWNERS
similarity index 83%
rename from sensors/common/vts/OWNERS
rename to sensors/OWNERS
index 1b9a2f8..e7ebd3e 100644
--- a/sensors/common/vts/OWNERS
+++ b/sensors/OWNERS
@@ -1,5 +1,5 @@
# Bug component: 62965
-# Sensors team
+
arthuri@google.com
bduddie@google.com
stange@google.com
diff --git a/sensors/aidl/default/OWNERS b/sensors/aidl/default/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/aidl/default/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/multihal/OWNERS b/sensors/aidl/multihal/OWNERS
deleted file mode 100644
index e955670..0000000
--- a/sensors/aidl/multihal/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
\ No newline at end of file
diff --git a/sensors/aidl/vts/OWNERS b/sensors/aidl/vts/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/aidl/vts/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/default/2.X/OWNERS b/sensors/common/default/2.X/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/common/default/2.X/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/utils/OWNERS b/sensors/common/utils/OWNERS
deleted file mode 100644
index 90c2330..0000000
--- a/sensors/common/utils/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-arthuri@google.com
-bduddie@google.com
-stange@google.com
diff --git a/sensors/common/vts/utils/OWNERS b/sensors/common/vts/utils/OWNERS
deleted file mode 100644
index 892da15..0000000
--- a/sensors/common/vts/utils/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
similarity index 68%
copy from audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
copy to tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
index bc010ca..eef4025 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/HpdSignal.aidl
@@ -31,22 +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;
-@VintfStability
-interface ISoundDose {
- void setOutputRs2(float rs2ValueDbA);
- float getOutputRs2();
- void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
- const int DEFAULT_MAX_RS2 = 100;
- const int MIN_RS2 = 80;
- @VintfStability
- interface IHalSoundDoseCallback {
- oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
- oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
- @VintfStability
- parcelable MelRecord {
- float[] melValues;
- long timestamp;
- }
- }
+package android.hardware.tv.hdmi;
+@Backing(type="byte") @VintfStability
+enum HpdSignal {
+ HDMI_HPD_PHYSICAL = 0,
+ HDMI_HPD_STATUS_BIT = 1,
}
diff --git a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
index 3fc7f41..809d392 100644
--- a/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/IHdmi.aidl
@@ -37,4 +37,6 @@
android.hardware.tv.hdmi.HdmiPortInfo[] getPortInfo();
boolean isConnected(in int portId);
void setCallback(in android.hardware.tv.hdmi.IHdmiCallback callback);
+ void setHpdSignal(android.hardware.tv.hdmi.HpdSignal signal);
+ android.hardware.tv.hdmi.HpdSignal getHpdSignal();
}
diff --git a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
similarity index 69%
copy from audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
copy to tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
index bc010ca..b6b0eb3 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.core.sounddose/current/android/hardware/audio/core/ISoundDose.aidl
+++ b/tv/hdmi/aidl/aidl_api/android.hardware.tv.hdmi/current/android/hardware/tv/hdmi/Result.aidl
@@ -31,22 +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;
+package android.hardware.tv.hdmi;
@VintfStability
-interface ISoundDose {
- void setOutputRs2(float rs2ValueDbA);
- float getOutputRs2();
- void registerSoundDoseCallback(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback callback);
- const int DEFAULT_MAX_RS2 = 100;
- const int MIN_RS2 = 80;
- @VintfStability
- interface IHalSoundDoseCallback {
- oneway void onMomentaryExposureWarning(float currentDbA, in android.media.audio.common.AudioDevice audioDevice);
- oneway void onNewMelValues(in android.hardware.audio.core.ISoundDose.IHalSoundDoseCallback.MelRecord melRecord, in android.media.audio.common.AudioDevice audioDevice);
- @VintfStability
- parcelable MelRecord {
- float[] melValues;
- long timestamp;
- }
- }
+enum Result {
+ SUCCESS = 0,
+ FAILURE_UNKNOWN = 1,
+ FAILURE_INVALID_ARGS = 2,
+ FAILURE_INVALID_STATE = 3,
+ FAILURE_NOT_SUPPORTED = 4,
}
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
new file mode 100644
index 0000000..05963f2
--- /dev/null
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/HpdSignal.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.tv.hdmi;
+
+/**
+ * HPD (Hotplug Detection) Signal Types
+ */
+@VintfStability
+@Backing(type="byte")
+enum HpdSignal {
+ HDMI_HPD_PHYSICAL = 0,
+ HDMI_HPD_STATUS_BIT = 1,
+}
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
index 5536846..457234d 100644
--- a/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/IHdmi.aidl
@@ -17,6 +17,7 @@
package android.hardware.tv.hdmi;
import android.hardware.tv.hdmi.HdmiPortInfo;
+import android.hardware.tv.hdmi.HpdSignal;
import android.hardware.tv.hdmi.IHdmiCallback;
/**
@@ -48,4 +49,17 @@
* setCallback(null) should deregister the callback.
*/
void setCallback(in IHdmiCallback callback);
+
+ /**
+ * Method to set the HPD (Hot Plug Detection) signal the HAL should use for HPD signaling (e.g.
+ * signaling EDID updates). By default, the HAL will use {@code HDMI_HPD_PHYSICAL} (the physical
+ * hotplug signal). When set to {@code HDMI_HPD_STATUS_BIT} the HAL should use the HDP status
+ * bit.
+ */
+ void setHpdSignal(HpdSignal signal);
+
+ /**
+ * Get the current signal the HAL is using for HPD
+ */
+ HpdSignal getHpdSignal();
}
diff --git a/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl b/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
new file mode 100644
index 0000000..d2a1fef
--- /dev/null
+++ b/tv/hdmi/aidl/android/hardware/tv/hdmi/Result.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.tv.hdmi;
+
+/**
+ * Result enum for return values. Used by the HDMI related AIDL.
+ */
+@VintfStability
+enum Result {
+ /**
+ * The HPD Signal type was set successfully.
+ */
+ SUCCESS = 0,
+
+ /**
+ * The HPD Signal type could not be set because of an unknown failure.
+ */
+ FAILURE_UNKNOWN = 1,
+
+ /**
+ * The HPD Signal type could not be set because the arguments were invalid.
+ */
+ FAILURE_INVALID_ARGS = 2,
+
+ /**
+ * The HPD Signal type could not be set because the HAL is in an invalid state.
+ */
+ FAILURE_INVALID_STATE = 3,
+
+ /**
+ * The HPD Signal type could not be set as the signal type is not supported.
+ */
+ FAILURE_NOT_SUPPORTED = 4,
+}
diff --git a/tv/hdmi/aidl/default/HdmiMock.cpp b/tv/hdmi/aidl/default/HdmiMock.cpp
index bbc4705..7cd9bb7 100644
--- a/tv/hdmi/aidl/default/HdmiMock.cpp
+++ b/tv/hdmi/aidl/default/HdmiMock.cpp
@@ -67,6 +67,21 @@
return ScopedAStatus::ok();
}
+ScopedAStatus HdmiMock::setHpdSignal(HpdSignal signal) {
+ if (mHdmiThreadRun) {
+ mHpdSignal = signal;
+ return ScopedAStatus::ok();
+ } else {
+ return ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::FAILURE_INVALID_STATE));
+ }
+}
+
+ScopedAStatus HdmiMock::getHpdSignal(HpdSignal* _aidl_return) {
+ *_aidl_return = mHpdSignal;
+ return ScopedAStatus::ok();
+}
+
void* HdmiMock::__threadLoop(void* user) {
HdmiMock* const self = static_cast<HdmiMock*>(user);
self->threadLoop();
diff --git a/tv/hdmi/aidl/default/HdmiMock.h b/tv/hdmi/aidl/default/HdmiMock.h
index 05795dd..51abaff 100644
--- a/tv/hdmi/aidl/default/HdmiMock.h
+++ b/tv/hdmi/aidl/default/HdmiMock.h
@@ -15,6 +15,7 @@
*/
#include <aidl/android/hardware/tv/hdmi/BnHdmi.h>
+#include <aidl/android/hardware/tv/hdmi/Result.h>
#include <algorithm>
#include <vector>
@@ -29,8 +30,10 @@
using ::aidl::android::hardware::tv::hdmi::BnHdmi;
using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::HpdSignal;
using ::aidl::android::hardware::tv::hdmi::IHdmi;
using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
+using ::aidl::android::hardware::tv::hdmi::Result;
#define HDMI_MSG_IN_FIFO "/dev/hdmi_in_pipe"
#define MESSAGE_BODY_MAX_LENGTH 4
@@ -41,6 +44,8 @@
::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
::ndk::ScopedAStatus setCallback(const std::shared_ptr<IHdmiCallback>& callback) override;
+ ::ndk::ScopedAStatus setHpdSignal(HpdSignal signal) override;
+ ::ndk::ScopedAStatus getHpdSignal(HpdSignal* _aidl_return) override;
void printEventBuf(const char* msg_buf, int len);
@@ -62,6 +67,9 @@
uint16_t mPhysicalAddress = 0xFFFF;
int mTotalPorts = 1;
+ // HPD Signal being used
+ HpdSignal mHpdSignal = HpdSignal::HDMI_HPD_PHYSICAL;
+
// Testing variables
// Input file descriptor
int mInputFile;
diff --git a/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp b/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp
index 78c2590..fd4d94f 100644
--- a/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp
+++ b/tv/hdmi/aidl/vts/functional/VtsHalTvHdmiAidlTargetTest.cpp
@@ -31,6 +31,7 @@
using ::aidl::android::hardware::tv::hdmi::BnHdmiCallback;
using ::aidl::android::hardware::tv::hdmi::HdmiPortInfo;
using ::aidl::android::hardware::tv::hdmi::HdmiPortType;
+using ::aidl::android::hardware::tv::hdmi::HpdSignal;
using ::aidl::android::hardware::tv::hdmi::IHdmi;
using ::aidl::android::hardware::tv::hdmi::IHdmiCallback;
using ::ndk::SpAIBinder;
@@ -101,3 +102,18 @@
ASSERT_TRUE(hdmi->isConnected(ports[i].portId, &connected).isOk());
}
}
+
+TEST_P(HdmiTest, HdpSignal) {
+ HpdSignal originalSignal;
+ HpdSignal signal = HpdSignal::HDMI_HPD_STATUS_BIT;
+ HpdSignal readSignal;
+ ASSERT_TRUE(hdmi->getHpdSignal(&originalSignal).isOk());
+ ASSERT_TRUE(hdmi->setHpdSignal(signal).isOk());
+ ASSERT_TRUE(hdmi->getHpdSignal(&readSignal).isOk());
+ EXPECT_EQ(readSignal, signal);
+ signal = HpdSignal::HDMI_HPD_PHYSICAL;
+ ASSERT_TRUE(hdmi->setHpdSignal(signal).isOk());
+ ASSERT_TRUE(hdmi->getHpdSignal(&readSignal).isOk());
+ EXPECT_EQ(readSignal, signal);
+ ASSERT_TRUE(hdmi->setHpdSignal(originalSignal).isOk());
+}