Merge changes from topic "RRN" into main
* changes:
[Composer3-VTS] Test Composer3-V3 for refreshPeriodNanos and vsyncPeriodNanos
[HWC3] AIDL change to add refreshPeriodNanos to RefreshRateChangedDebugData
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 e14e9c0..07a85f8 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
@@ -74,6 +74,7 @@
boolean supportsVariableLatency();
int getAAudioMixerBurstCount();
int getAAudioHardwareBurstMinUsec();
+ void prepareToDisconnectExternalDevice(int portId);
const int DEFAULT_AAUDIO_MIXER_BURST_COUNT = 2;
const int DEFAULT_AAUDIO_HARDWARE_BURST_MIN_DURATION_US = 1000;
@VintfStability
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
index bcbf870..046c220 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Flags.aidl
@@ -43,6 +43,8 @@
boolean audioModeIndication;
boolean audioSourceIndication;
boolean bypass;
+ boolean sinkMetadataIndication;
+ boolean sourceMetadataIndication;
@Backing(type="byte") @VintfStability
enum Type {
INSERT = 0,
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
index 7313b57..ff33c42 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Parameter.aidl
@@ -41,6 +41,8 @@
boolean offload;
android.hardware.audio.effect.Parameter.VolumeStereo volumeStereo;
android.hardware.audio.effect.Parameter.Specific specific;
+ android.hardware.audio.common.SinkMetadata sinkMetadata;
+ android.hardware.audio.common.SourceMetadata sourceMetadata;
@VintfStability
union Id {
android.hardware.audio.effect.VendorExtension vendorEffectTag;
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index e736c32..2d4d283 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -206,8 +206,10 @@
* after successful connection of an external device.
*
* Handling of a disconnect is done in a reverse order:
- * 1. Reset port configuration using the 'resetAudioPortConfig' method.
- * 2. Release the connected device port by calling the 'disconnectExternalDevice'
+ * 1. Notify the HAL module to prepare for device disconnection using
+ * 'prepareToDisconnectExternalDevice' method.
+ * 2. Reset port configuration using the 'resetAudioPortConfig' method.
+ * 3. Release the connected device port by calling the 'disconnectExternalDevice'
* method. This also removes the audio routes associated with this
* device port.
*
@@ -234,11 +236,15 @@
* instance previously instantiated using the 'connectExternalDevice'
* method.
*
- * The framework will call this method before closing streams and resetting
- * patches. This call can be used by the HAL module to prepare itself to
- * device disconnection. If the HAL module indicates an error after the first
- * call, the framework will call this method once again after closing associated
- * streams and patches.
+ * On AIDL HAL v1, the framework will call this method before closing streams
+ * and resetting patches. This call can be used by the HAL module to prepare
+ * itself to device disconnection. If the HAL module indicates an error after
+ * the first call, the framework will call this method once again after closing
+ * associated streams and patches.
+ *
+ * On AIDL HAL v2 and later, the framework will call 'prepareToDisconnectExternalDevice'
+ * method to notify the HAL module to prepare itself for device disconnection. The
+ * framework will only call this method after closing associated streams and patches.
*
* @throws EX_ILLEGAL_ARGUMENT In the following cases:
* - If the port can not be found by the ID.
@@ -912,4 +918,20 @@
* @throw EX_UNSUPPORTED_OPERATION If the module does not support aaudio MMAP.
*/
int getAAudioHardwareBurstMinUsec();
+
+ /**
+ * Notify the HAL module to prepare for disconnecting an external device.
+ *
+ * This method is used to inform the HAL module that 'disconnectExternalDevice' will be
+ * called soon. The HAL module can rely on this method to abort active data operations
+ * early. The 'portId' must be of a connected device Port instance previously instantiated
+ * using 'connectExternalDevice' method. 'disconnectExternalDevice' method will be called
+ * soon after this method with the same 'portId'.
+ *
+ * @param portId The ID of the audio port that is about to disconnect
+ * @throws EX_ILLEGAL_ARGUMENT In the following cases:
+ * - If the port can not be found by the ID.
+ * - If this is not a connected device port.
+ */
+ void prepareToDisconnectExternalDevice(int portId);
}
diff --git a/audio/aidl/android/hardware/audio/effect/Flags.aidl b/audio/aidl/android/hardware/audio/effect/Flags.aidl
index 28685c3..70668a3 100644
--- a/audio/aidl/android/hardware/audio/effect/Flags.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Flags.aidl
@@ -144,4 +144,18 @@
* Set to true if the effect instance bypass audio data (no processing).
*/
boolean bypass;
+
+ /**
+ * Effect instance sets this flag to true if it requires record AudioTrack metadata update. In
+ * this case the framework must call IEffect.setParameter to notify effect instance when there
+ * is a change in sinkMetadata.
+ */
+ boolean sinkMetadataIndication;
+
+ /**
+ * Effect instance sets this flag to true if it requires playback AudioTrack metadata update. In
+ * this case the framework must call IEffect.setParameter to notify effect instance when there
+ * is a change in sourceMetadata.
+ */
+ boolean sourceMetadataIndication;
}
diff --git a/audio/aidl/android/hardware/audio/effect/Parameter.aidl b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
index 6ec7226..6fd9161 100644
--- a/audio/aidl/android/hardware/audio/effect/Parameter.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Parameter.aidl
@@ -16,6 +16,8 @@
package android.hardware.audio.effect;
+import android.hardware.audio.common.SinkMetadata;
+import android.hardware.audio.common.SourceMetadata;
import android.hardware.audio.effect.AcousticEchoCanceler;
import android.hardware.audio.effect.AutomaticGainControlV1;
import android.hardware.audio.effect.AutomaticGainControlV2;
@@ -198,4 +200,20 @@
Spatializer spatializer;
}
Specific specific;
+
+ /**
+ * SinkMetadata defines the metadata of record AudioTracks which the effect instance associate
+ * with.
+ * The effect engine is required to set Flags.sinkMetadataIndication to true if it wants to
+ * receive sinkMetadata update from the audio framework.
+ */
+ SinkMetadata sinkMetadata;
+
+ /**
+ * SourceMetadata defines the metadata of playback AudioTracks which the effect instance
+ * associate with.
+ * The effect engine is required to set Flags.sourceMetadataIndication to true if it wants to
+ * receive sourceMetadata update from the audio framework.
+ */
+ SourceMetadata sourceMetadata;
}
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index 254eb46..d63e353 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -320,9 +320,9 @@
// - no profiles specified
//
// Mix ports:
-// * "r_submix output", maximum 20 opened streams, maximum 10 active streams
+// * "r_submix output", maximum 10 opened streams, maximum 10 active streams
// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
-// * "r_submix input", maximum 20 opened streams, maximum 10 active streams
+// * "r_submix input", maximum 10 opened streams, maximum 10 active streams
// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000
//
// Routes:
@@ -355,12 +355,12 @@
// Mix ports
AudioPort rsubmixOutMix =
- createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(20, 10));
+ createPort(c.nextPortId++, "r_submix output", 0, false, createPortMixExt(10, 10));
rsubmixOutMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixOutMix);
AudioPort rsubmixInMix =
- createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(20, 10));
+ createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(10, 10));
rsubmixInMix.profiles = remoteSubmixPcmAudioProfiles;
c.ports.push_back(rsubmixInMix);
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 66c2169..d0e8745 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -762,6 +762,28 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Module::prepareToDisconnectExternalDevice(int32_t in_portId) {
+ auto& ports = getConfig().ports;
+ auto portIt = findById<AudioPort>(ports, in_portId);
+ if (portIt == ports.end()) {
+ LOG(ERROR) << __func__ << ": port id " << in_portId << " not found";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ if (portIt->ext.getTag() != AudioPortExt::Tag::device) {
+ LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a device port";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ auto connectedPortsIt = mConnectedDevicePorts.find(in_portId);
+ if (connectedPortsIt == mConnectedDevicePorts.end()) {
+ LOG(ERROR) << __func__ << ": port id " << in_portId << " is not a connected device port";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ onPrepareToDisconnectExternalDevice(*portIt);
+
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus Module::getAudioPatches(std::vector<AudioPatch>* _aidl_return) {
*_aidl_return = getConfig().patches;
LOG(DEBUG) << __func__ << ": returning " << _aidl_return->size() << " patches";
@@ -1541,6 +1563,11 @@
LOG(DEBUG) << __func__ << ": do nothing and return";
}
+void Module::onPrepareToDisconnectExternalDevice(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort __unused) {
+ LOG(DEBUG) << __func__ << ": do nothing and return";
+}
+
ndk::ScopedAStatus Module::onMasterMuteChanged(bool mute __unused) {
LOG(VERBOSE) << __func__ << ": do nothing and return ok";
return ndk::ScopedAStatus::ok();
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index e8c1693..a805b87 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -582,7 +582,7 @@
const size_t frameSize = mContext->getFrameSize();
bool fatal = false;
int32_t latency = mContext->getNominalLatencyMs();
- if (bool success = readByteCount > 0 ? dataMQ->read(&mDataBuffer[0], readByteCount) : true) {
+ if (readByteCount > 0 ? dataMQ->read(&mDataBuffer[0], readByteCount) : true) {
const bool isConnected = mIsConnected;
LOG(VERBOSE) << __func__ << ": reading of " << readByteCount << " bytes from data MQ"
<< " succeeded; connected? " << isConnected;
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 00de797..6f0af21 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -96,8 +96,8 @@
<libsw library="bundle" uuid="ce772f20-847d-11df-bb17-0002a5d5c51b"/>
</effectProxy>
<effect name="extension_effect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002" type="fa81de0e-588b-11ed-9b6a-0242ac120002"/>
- <effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
- <effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
+ <effect name="acoustic_echo_canceler" library="pre_processing" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
+ <effect name="noise_suppression" library="pre_processing" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
</effects>
<preprocess>
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index caf43f1..572b597 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -70,6 +70,7 @@
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override;
+ ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override;
ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override;
ndk::ScopedAStatus getAudioPort(
int32_t in_portId,
@@ -195,6 +196,8 @@
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks);
virtual void onExternalDeviceConnectionChanged(
const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
+ virtual void onPrepareToDisconnectExternalDevice(
+ const ::aidl::android::media::audio::common::AudioPort& audioPort);
virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute);
virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume);
virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos();
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 21592b3..ee10abf 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -71,6 +71,10 @@
static constexpr int kMaxReadFailureAttempts = 3;
// 5ms between two read attempts when pipe is empty
static constexpr int kReadAttemptSleepUs = 5000;
+
+ long mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
+ int mReadErrorCount = 0;
};
class StreamInRemoteSubmix final : public StreamIn, public StreamSwitcher {
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index b22ef32..7325a91 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -116,8 +116,8 @@
GetBoolProperty("ro.boot.audio.tinyalsa.simulate_input", false);
return kSimulateInput || device.type.type == AudioDeviceType::IN_TELEPHONY_RX ||
device.type.type == AudioDeviceType::IN_FM_TUNER ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS ||
- (device.type.type == AudioDeviceType::IN_DEVICE && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated */ ||
+ (device.type.type == AudioDeviceType::IN_BUS && device.type.connection.empty());
}
StreamSwitcher::DeviceSwitchBehavior StreamInPrimary::switchCurrentStream(
@@ -188,8 +188,8 @@
static const bool kSimulateOutput =
GetBoolProperty("ro.boot.audio.tinyalsa.ignore_output", false);
return kSimulateOutput || device.type.type == AudioDeviceType::OUT_TELEPHONY_TX ||
- device.type.connection == AudioDeviceDescription::CONNECTION_BUS ||
- (device.type.type == AudioDeviceType::OUT_DEVICE && device.type.connection.empty());
+ device.type.connection == AudioDeviceDescription::CONNECTION_BUS /*deprecated*/ ||
+ (device.type.type == AudioDeviceType::OUT_BUS && device.type.connection.empty());
}
StreamSwitcher::DeviceSwitchBehavior StreamOutPrimary::switchCurrentStream(
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index fc61dcb..6258c93 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -16,6 +16,9 @@
#define LOG_TAG "AHAL_StreamRemoteSubmix"
#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+#include <error/Result.h>
+#include <error/expected_utils.h>
#include "core-impl/StreamRemoteSubmix.h"
@@ -50,37 +53,33 @@
if (routeItr != sSubmixRoutes.end()) {
mCurrentRoute = routeItr->second;
}
- }
- // If route is not available for this port, add it.
- if (mCurrentRoute == nullptr) {
- // Initialize the pipe.
- mCurrentRoute = std::make_shared<SubmixRoute>();
- if (::android::OK != mCurrentRoute->createPipe(mStreamConfig)) {
- LOG(ERROR) << __func__ << ": create pipe failed";
- return ::android::NO_INIT;
- }
- {
- std::lock_guard guard(sSubmixRoutesLock);
- sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
- }
- } else {
- if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
- LOG(ERROR) << __func__ << ": invalid stream config";
- return ::android::NO_INIT;
- }
- sp<MonoPipe> sink = mCurrentRoute->getSink();
- if (sink == nullptr) {
- LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
- return ::android::NO_INIT;
- }
- // If the sink has been shutdown or pipe recreation is forced, delete the pipe and
- // recreate it.
- if (sink->isShutdown()) {
- LOG(DEBUG) << __func__ << ": Non-nullptr shut down sink when opening stream";
- if (::android::OK != mCurrentRoute->resetPipe()) {
- LOG(ERROR) << __func__ << ": reset pipe failed";
+ // If route is not available for this port, add it.
+ if (mCurrentRoute == nullptr) {
+ // Initialize the pipe.
+ mCurrentRoute = std::make_shared<SubmixRoute>();
+ if (::android::OK != mCurrentRoute->createPipe(mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": create pipe failed";
return ::android::NO_INIT;
}
+ sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
+ }
+ }
+ if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
+ LOG(ERROR) << __func__ << ": invalid stream config";
+ return ::android::NO_INIT;
+ }
+ sp<MonoPipe> sink = mCurrentRoute->getSink();
+ if (sink == nullptr) {
+ LOG(ERROR) << __func__ << ": nullptr sink when opening stream";
+ return ::android::NO_INIT;
+ }
+ // If the sink has been shutdown or pipe recreation is forced, delete the pipe and
+ // recreate it.
+ if (sink->isShutdown()) {
+ LOG(DEBUG) << __func__ << ": Non-nullptr shut down sink when opening stream";
+ if (::android::OK != mCurrentRoute->resetPipe()) {
+ LOG(ERROR) << __func__ << ": reset pipe failed";
+ return ::android::NO_INIT;
}
}
@@ -110,6 +109,8 @@
::android::status_t StreamRemoteSubmix::start() {
mCurrentRoute->exitStandby(mIsInput);
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
return ::android::OK;
}
@@ -161,8 +162,21 @@
*latencyMs = getDelayInUsForFrameCount(getStreamPipeSizeInFrames()) / 1000;
LOG(VERBOSE) << __func__ << ": Latency " << *latencyMs << "ms";
mCurrentRoute->exitStandby(mIsInput);
- return (mIsInput ? inRead(buffer, frameCount, actualFrameCount)
- : outWrite(buffer, frameCount, actualFrameCount));
+ RETURN_STATUS_IF_ERROR(mIsInput ? inRead(buffer, frameCount, actualFrameCount)
+ : outWrite(buffer, frameCount, actualFrameCount));
+ const long bufferDurationUs =
+ (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
+ const long totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ mFramesSinceStart += *actualFrameCount;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ }
+ return ::android::OK;
}
::android::status_t StreamRemoteSubmix::refinePosition(StreamDescriptor::Position* position) {
@@ -200,12 +214,7 @@
if (sink != nullptr) {
if (sink->isShutdown()) {
sink.clear();
- const auto delayUs = getDelayInUsForFrameCount(frameCount);
- LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write, sleeping for "
- << delayUs << " us";
- // the pipe has already been shutdown, this buffer will be lost but we must
- // simulate timing so we don't drain the output faster than realtime
- usleep(delayUs);
+ LOG(DEBUG) << __func__ << ": pipe shutdown, ignoring the write";
*actualFrameCount = frameCount;
return ::android::OK;
}
@@ -214,6 +223,9 @@
return ::android::UNKNOWN_ERROR;
}
+ LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ << " frames";
+
const bool shouldBlockWrite = mCurrentRoute->shouldBlockWrite();
size_t availableToWrite = sink->availableToWrite();
// NOTE: sink has been checked above and sink and source life cycles are synchronized
@@ -236,6 +248,8 @@
availableToWrite = sink->availableToWrite();
if (!shouldBlockWrite && frameCount > availableToWrite) {
+ LOG(WARNING) << __func__ << ": writing " << availableToWrite << " vs. requested "
+ << frameCount;
// Truncate the request to avoid blocking.
frameCount = availableToWrite;
}
@@ -258,92 +272,59 @@
*actualFrameCount = 0;
return ::android::UNKNOWN_ERROR;
}
- LOG(VERBOSE) << __func__ << ": wrote " << writtenFrames << "frames";
+ if (writtenFrames > 0 && frameCount > (size_t)writtenFrames) {
+ LOG(WARNING) << __func__ << ": wrote " << writtenFrames << " vs. requested " << frameCount;
+ }
*actualFrameCount = writtenFrames;
return ::android::OK;
}
::android::status_t StreamRemoteSubmix::inRead(void* buffer, size_t frameCount,
size_t* actualFrameCount) {
+ // in any case, it is emulated that data for the entire buffer was available
+ memset(buffer, 0, mStreamConfig.frameSize * frameCount);
+ *actualFrameCount = frameCount;
+
// about to read from audio source
sp<MonoPipeReader> source = mCurrentRoute->getSource();
if (source == nullptr) {
- int readErrorCount = mCurrentRoute->notifyReadError();
- if (readErrorCount < kMaxReadErrorLogs) {
+ if (++mReadErrorCount < kMaxReadErrorLogs) {
LOG(ERROR) << __func__
<< ": no audio pipe yet we're trying to read! (not all errors will be "
"logged)";
- } else {
- LOG(ERROR) << __func__ << ": Read errors " << readErrorCount;
}
- const auto delayUs = getDelayInUsForFrameCount(frameCount);
- LOG(DEBUG) << __func__ << ": no source, ignoring the read, sleeping for " << delayUs
- << " us";
- usleep(delayUs);
- memset(buffer, 0, mStreamConfig.frameSize * frameCount);
- *actualFrameCount = frameCount;
return ::android::OK;
}
+ LOG(VERBOSE) << __func__ << ": " << mDeviceAddress.toString() << ", " << frameCount
+ << " frames";
// read the data from the pipe
- int attempts = 0;
- const long delayUs = kReadAttemptSleepUs;
char* buff = (char*)buffer;
- size_t remainingFrames = frameCount;
- int availableToRead = source->availableToRead();
-
- while ((remainingFrames > 0) && (availableToRead > 0) && (attempts < kMaxReadFailureAttempts)) {
- LOG(VERBOSE) << __func__ << ": frames available to read " << availableToRead;
-
+ size_t actuallyRead = 0;
+ long remainingFrames = frameCount;
+ const long deadlineTimeNs = ::android::uptimeNanos() +
+ getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
+ while (remainingFrames > 0) {
ssize_t framesRead = source->read(buff, remainingFrames);
-
LOG(VERBOSE) << __func__ << ": frames read " << framesRead;
-
if (framesRead > 0) {
remainingFrames -= framesRead;
buff += framesRead * mStreamConfig.frameSize;
- availableToRead -= framesRead;
- LOG(VERBOSE) << __func__ << ": (attempts = " << attempts << ") got " << framesRead
+ LOG(VERBOSE) << __func__ << ": got " << framesRead
<< " frames, remaining =" << remainingFrames;
- } else {
- attempts++;
- LOG(WARNING) << __func__ << ": read returned " << framesRead
- << " , read failure attempts = " << attempts << ", sleeping for "
- << delayUs << " us";
- usleep(delayUs);
+ actuallyRead += framesRead;
+ }
+ if (::android::uptimeNanos() >= deadlineTimeNs) break;
+ if (framesRead <= 0) {
+ LOG(VERBOSE) << __func__ << ": read returned " << framesRead
+ << ", read failure, sleeping for " << kReadAttemptSleepUs << " us";
+ usleep(kReadAttemptSleepUs);
}
}
- // done using the source
- source.clear();
-
- if (remainingFrames > 0) {
- const size_t remainingBytes = remainingFrames * mStreamConfig.frameSize;
- LOG(VERBOSE) << __func__ << ": clearing remaining_frames = " << remainingFrames;
- memset(((char*)buffer) + (mStreamConfig.frameSize * frameCount) - remainingBytes, 0,
- remainingBytes);
+ if (actuallyRead < frameCount) {
+ LOG(WARNING) << __func__ << ": read " << actuallyRead << " vs. requested " << frameCount;
}
-
- long readCounterFrames = mCurrentRoute->updateReadCounterFrames(frameCount);
- *actualFrameCount = frameCount;
-
- // compute how much we need to sleep after reading the data by comparing the wall clock with
- // the projected time at which we should return.
- // wall clock after reading from the pipe
- auto recordDurationUs = std::chrono::duration_cast<std::chrono::microseconds>(
- std::chrono::steady_clock::now() - mCurrentRoute->getRecordStartTime());
-
- // readCounterFrames contains the number of frames that have been read since the beginning of
- // recording (including this call): it's converted to usec and compared to how long we've been
- // recording for, which gives us how long we must wait to sync the projected recording time, and
- // the observed recording time.
- const long projectedVsObservedOffsetUs =
- getDelayInUsForFrameCount(readCounterFrames) - recordDurationUs.count();
-
- LOG(VERBOSE) << __func__ << ": record duration " << recordDurationUs.count()
- << " us, will wait: " << projectedVsObservedOffsetUs << " us";
- if (projectedVsObservedOffsetUs > 0) {
- usleep(projectedVsObservedOffsetUs);
- }
+ mCurrentRoute->updateReadCounterFrames(*actualFrameCount);
return ::android::OK;
}
diff --git a/audio/aidl/default/r_submix/SubmixRoute.cpp b/audio/aidl/default/r_submix/SubmixRoute.cpp
index ddac64d..f04e607 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.cpp
+++ b/audio/aidl/default/r_submix/SubmixRoute.cpp
@@ -81,11 +81,6 @@
return (mStreamInOpen || (mStreamInStandby && (mReadCounterFrames != 0)));
}
-int SubmixRoute::notifyReadError() {
- std::lock_guard guard(mLock);
- return ++mReadErrorCount;
-}
-
long SubmixRoute::updateReadCounterFrames(size_t frameCount) {
std::lock_guard guard(mLock);
mReadCounterFrames += frameCount;
@@ -103,7 +98,6 @@
}
mStreamInStandby = true;
mReadCounterFrames = 0;
- mReadErrorCount = 0;
} else {
mStreamOutOpen = true;
}
@@ -214,9 +208,6 @@
if (mStreamInStandby || mStreamOutStandbyTransition) {
mStreamInStandby = false;
mStreamOutStandbyTransition = false;
- // keep track of when we exit input standby (== first read == start "real recording")
- // or when we start recording silence, and reset projected time
- mRecordStartTime = std::chrono::steady_clock::now();
mReadCounterFrames = 0;
}
} else {
diff --git a/audio/aidl/default/r_submix/SubmixRoute.h b/audio/aidl/default/r_submix/SubmixRoute.h
index 92b95e9..252b1c9 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.h
+++ b/audio/aidl/default/r_submix/SubmixRoute.h
@@ -16,7 +16,6 @@
#pragma once
-#include <chrono>
#include <mutex>
#include <android-base/thread_annotations.h>
@@ -83,14 +82,6 @@
std::lock_guard guard(mLock);
return mReadCounterFrames;
}
- int getReadErrorCount() {
- std::lock_guard guard(mLock);
- return mReadErrorCount;
- }
- std::chrono::time_point<std::chrono::steady_clock> getRecordStartTime() {
- std::lock_guard guard(mLock);
- return mRecordStartTime;
- }
sp<MonoPipe> getSink() {
std::lock_guard guard(mLock);
return mSink;
@@ -126,9 +117,6 @@
bool mStreamOutStandby GUARDED_BY(mLock) = true;
// how many frames have been requested to be read since standby
long mReadCounterFrames GUARDED_BY(mLock) = 0;
- int mReadErrorCount GUARDED_BY(mLock) = 0;
- // wall clock when recording starts
- std::chrono::time_point<std::chrono::steady_clock> mRecordStartTime GUARDED_BY(mLock);
// Pipe variables: they handle the ring buffer that "pipes" audio:
// - from the submix virtual audio output == what needs to be played
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index ad816c7..191f928 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -86,6 +86,9 @@
name: "VtsHalDownmixTargetTest",
defaults: ["VtsHalAudioTargetTestDefaults"],
srcs: ["VtsHalDownmixTargetTest.cpp"],
+ shared_libs: [
+ "libaudioutils",
+ ],
}
cc_test {
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index 2c8edf2..d813554 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -283,4 +283,32 @@
}
return functor(result);
}
+
+ static void processAndWriteToOutput(std::vector<float>& inputBuffer,
+ std::vector<float>& outputBuffer,
+ const std::shared_ptr<IEffect>& mEffect,
+ IEffect::OpenEffectReturn* mOpenEffectReturn) {
+ // Initialize AidlMessagequeues
+ auto statusMQ = std::make_unique<EffectHelper::StatusMQ>(mOpenEffectReturn->statusMQ);
+ ASSERT_TRUE(statusMQ->isValid());
+ auto inputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn->inputDataMQ);
+ ASSERT_TRUE(inputMQ->isValid());
+ auto outputMQ = std::make_unique<EffectHelper::DataMQ>(mOpenEffectReturn->outputDataMQ);
+ ASSERT_TRUE(outputMQ->isValid());
+
+ // Enabling the process
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::PROCESSING));
+
+ // Write from buffer to message queues and calling process
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer));
+
+ // Read the updated message queues into buffer
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 1, outputMQ,
+ outputBuffer.size(), outputBuffer));
+
+ // Disable the process
+ ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::RESET));
+ ASSERT_NO_FATAL_FAILURE(expectState(mEffect, State::IDLE));
+ }
};
diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h
index e9f3251..515b8a2 100644
--- a/audio/aidl/vts/TestUtils.h
+++ b/audio/aidl/vts/TestUtils.h
@@ -69,6 +69,23 @@
<< "\n but is has completed with: " << status;
}
+inline ::testing::AssertionResult assertIsOkOrUnknownTransaction(
+ const char* expr, const ::ndk::ScopedAStatus& status) {
+ if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) {
+ return ::testing::AssertionSuccess();
+ }
+ return assertIsOk(expr, status);
+}
+
+inline ::testing::AssertionResult assertResultOrUnknownTransaction(
+ const char* exp_expr, const char* act_expr, int32_t expected,
+ const ::ndk::ScopedAStatus& status) {
+ if (status.getStatus() == STATUS_UNKNOWN_TRANSACTION) {
+ return ::testing::AssertionSuccess();
+ }
+ return assertResult(exp_expr, act_expr, expected, status);
+}
+
} // namespace detail
} // namespace android::hardware::audio::common::testing
@@ -93,3 +110,15 @@
GTEST_SKIP() << "Skip data path for offload"; \
} \
})
+
+// Test that the transaction status 'isOk' if it is a known transaction
+#define EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(ret) \
+ EXPECT_PRED_FORMAT1( \
+ ::android::hardware::audio::common::testing::detail::assertIsOkOrUnknownTransaction, \
+ ret)
+
+// Test that the transaction status is as expected if it is a known transaction
+#define EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(expected, ret) \
+ EXPECT_PRED_FORMAT2( \
+ ::android::hardware::audio::common::testing::detail::assertResultOrUnknownTransaction, \
+ expected, ret)
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 697aae9..f91795b 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -573,6 +573,8 @@
WithDevicePortConnectedState& operator=(const WithDevicePortConnectedState&) = delete;
~WithDevicePortConnectedState() {
if (mModule != nullptr) {
+ EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(mModule->prepareToDisconnectExternalDevice(getId()))
+ << "when preparing to disconnect device port ID " << getId();
EXPECT_IS_OK(mModule->disconnectExternalDevice(getId()))
<< "when disconnecting device port ID " << getId();
}
@@ -1753,6 +1755,9 @@
ScopedAStatus status = module->connectExternalDevice(portWithData, &connectedPort);
EXPECT_STATUS(EX_ILLEGAL_STATE, status) << "static port " << portWithData.toString();
if (status.isOk()) {
+ EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(
+ module->prepareToDisconnectExternalDevice(connectedPort.id))
+ << "when preparing to disconnect device port ID " << connectedPort.id;
EXPECT_IS_OK(module->disconnectExternalDevice(connectedPort.id))
<< "when disconnecting device port ID " << connectedPort.id;
}
@@ -1782,6 +1787,9 @@
invalidPort.id = portId;
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(invalidPort, &ignored))
<< "port ID " << portId << ", when setting CONNECTED state";
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(EX_ILLEGAL_ARGUMENT,
+ module->prepareToDisconnectExternalDevice(portId))
+ << "port ID " << portId << ", when preparing to disconnect";
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(portId))
<< "port ID " << portId << ", when setting DISCONNECTED state";
}
@@ -1792,6 +1800,9 @@
if (port.ext.getTag() != AudioPortExt::Tag::device) {
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(port, &ignored))
<< "non-device port ID " << port.id << " when setting CONNECTED state";
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(EX_ILLEGAL_ARGUMENT,
+ module->prepareToDisconnectExternalDevice(port.id))
+ << "non-device port ID " << port.id << " when preparing to disconnect";
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "non-device port ID " << port.id << " when setting DISCONNECTED state";
} else {
@@ -1800,6 +1811,10 @@
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->connectExternalDevice(port, &ignored))
<< "for a permanently attached device port ID " << port.id
<< " when setting CONNECTED state";
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(
+ EX_ILLEGAL_ARGUMENT, module->prepareToDisconnectExternalDevice(port.id))
+ << "for a permanently attached device port ID " << port.id
+ << " when preparing to disconnect";
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "for a permanently attached device port ID " << port.id
<< " when setting DISCONNECTED state";
@@ -1817,6 +1832,9 @@
GTEST_SKIP() << "No external devices in the module.";
}
for (const auto& port : ports) {
+ EXPECT_STATUS_OR_UNKNOWN_TRANSACTION(EX_ILLEGAL_ARGUMENT,
+ module->prepareToDisconnectExternalDevice(port.id))
+ << "when preparing to disconnect already disconnected device port ID " << port.id;
EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->disconnectExternalDevice(port.id))
<< "when disconnecting already disconnected device port ID " << port.id;
AudioPort portWithData = GenerateUniqueDeviceAddress(port);
@@ -1851,6 +1869,10 @@
// Our test assumes that 'getAudioPort' returns at least one profile, and it
// is not a dynamic profile.
ASSERT_NO_FATAL_FAILURE(config.SetUp(module.get()));
+ EXPECT_IS_OK_OR_UNKNOWN_TRANSACTION(
+ module->prepareToDisconnectExternalDevice(portConnected.getId()))
+ << "when preparing to disconnect device port ID " << port.id
+ << " with active configuration " << config.getId();
EXPECT_STATUS(EX_ILLEGAL_STATE, module->disconnectExternalDevice(portConnected.getId()))
<< "when trying to disconnect device port ID " << port.id
<< " with active configuration " << config.getId();
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index c01a9a2..d7db567 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -18,88 +18,114 @@
#define LOG_TAG "VtsHalDownmixTargetTest"
#include <android-base/logging.h>
+#include <audio_utils/ChannelMix.h>
#include "EffectHelper.h"
using namespace android;
+using aidl::android::hardware::audio::common::getChannelCount;
using aidl::android::hardware::audio::effect::Descriptor;
using aidl::android::hardware::audio::effect::Downmix;
using aidl::android::hardware::audio::effect::getEffectTypeUuidDownmix;
using aidl::android::hardware::audio::effect::IEffect;
using aidl::android::hardware::audio::effect::IFactory;
using aidl::android::hardware::audio::effect::Parameter;
+using android::audio_utils::channels::ChannelMix;
using android::hardware::audio::common::testing::detail::TestExecutionTracer;
-/**
- * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
- * VtsAudioEffectTargetTest.
- */
-enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
-using DownmixParamTestParam =
- std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
// Testing for enum values
-const std::vector<Downmix::Type> kTypeValues = {Downmix::Type::STRIP, Downmix::Type::FOLD};
+static const std::vector<Downmix::Type> kTypeValues = {ndk::enum_range<Downmix::Type>().begin(),
+ ndk::enum_range<Downmix::Type>().end()};
-class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
- public EffectHelper {
+// Testing for supported layouts from AudioChannelLayout.h
+static const std::vector<int32_t> kLayoutValues = {
+ AudioChannelLayout::LAYOUT_STEREO, AudioChannelLayout::LAYOUT_2POINT1,
+ AudioChannelLayout::LAYOUT_TRI, AudioChannelLayout::LAYOUT_TRI_BACK,
+ AudioChannelLayout::LAYOUT_3POINT1, AudioChannelLayout::LAYOUT_2POINT0POINT2,
+ AudioChannelLayout::LAYOUT_2POINT1POINT2, AudioChannelLayout::LAYOUT_3POINT0POINT2,
+ AudioChannelLayout::LAYOUT_3POINT1POINT2, AudioChannelLayout::LAYOUT_QUAD,
+ AudioChannelLayout::LAYOUT_QUAD_SIDE, AudioChannelLayout::LAYOUT_SURROUND,
+ AudioChannelLayout::LAYOUT_PENTA, AudioChannelLayout::LAYOUT_5POINT1,
+ AudioChannelLayout::LAYOUT_5POINT1_SIDE, AudioChannelLayout::LAYOUT_5POINT1POINT2,
+ AudioChannelLayout::LAYOUT_5POINT1POINT4, AudioChannelLayout::LAYOUT_6POINT1,
+ AudioChannelLayout::LAYOUT_7POINT1, AudioChannelLayout::LAYOUT_7POINT1POINT2,
+ AudioChannelLayout::LAYOUT_7POINT1POINT4, AudioChannelLayout::LAYOUT_9POINT1POINT4,
+ AudioChannelLayout::LAYOUT_9POINT1POINT6, AudioChannelLayout::LAYOUT_13POINT_360RA,
+ AudioChannelLayout::LAYOUT_22POINT2};
+
+static const std::vector<int32_t> kChannels = {
+ AudioChannelLayout::CHANNEL_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY,
+ AudioChannelLayout::CHANNEL_BACK_LEFT,
+ AudioChannelLayout::CHANNEL_BACK_RIGHT,
+ AudioChannelLayout::CHANNEL_BACK_CENTER,
+ AudioChannelLayout::CHANNEL_SIDE_LEFT,
+ AudioChannelLayout::CHANNEL_SIDE_RIGHT,
+ AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER,
+ AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_TOP_BACK_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_BACK_CENTER,
+ AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT,
+ AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT,
+ AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER,
+ AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT,
+ AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2,
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT,
+ AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT,
+};
+
+class DownmixEffectHelper : public EffectHelper {
public:
- DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
- std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
- }
-
- void SetUp() override {
+ void SetUpDownmix(int32_t inputBufferLayout = AudioChannelLayout::LAYOUT_STEREO) {
ASSERT_NE(nullptr, mFactory);
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+ AudioChannelLayout inputChannelLayout =
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(inputBufferLayout);
+
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));
+ kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */,
+ inputChannelLayout);
+ ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &mOpenEffectReturn, EX_NONE));
ASSERT_NE(nullptr, mEffect);
}
- void TearDown() override {
+ void TearDownDownmix() {
ASSERT_NO_FATAL_FAILURE(close(mEffect));
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+ mOpenEffectReturn = IEffect::OpenEffectReturn{};
}
- static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
- std::shared_ptr<IFactory> mFactory;
- std::shared_ptr<IEffect> mEffect;
- Descriptor mDescriptor;
- Downmix::Type mParamType = Downmix::Type::STRIP;
-
- void SetAndGetDownmixParameters() {
- for (auto& it : mTags) {
- auto& tag = it.first;
- auto& dm = it.second;
-
- // set parameter
- Parameter expectParam;
- Parameter::Specific specific;
- specific.set<Parameter::Specific::downmix>(dm);
- expectParam.set<Parameter::specific>(specific);
- // All values are valid, set parameter should succeed
- EXPECT_STATUS(EX_NONE, mEffect->setParameter(expectParam)) << expectParam.toString();
-
- // get parameter
- Parameter getParam;
- Parameter::Id id;
- Downmix::Id dmId;
- dmId.set<Downmix::Id::commonTag>(tag);
- id.set<Parameter::Id::downmixTag>(dmId);
- EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
-
- EXPECT_EQ(expectParam, getParam);
- }
+ Parameter createDownmixParam(Downmix::Type type) {
+ return Parameter::make<Parameter::specific>(
+ Parameter::Specific::make<Parameter::Specific::downmix>(
+ Downmix::make<Downmix::type>(type)));
+ }
+ void setParameters(Downmix::Type type) {
+ // set parameter
+ auto param = createDownmixParam(type);
+ EXPECT_STATUS(EX_NONE, mEffect->setParameter(param)) << param.toString();
}
- void addTypeParam(Downmix::Type type) {
- Downmix dm;
- dm.set<Downmix::type>(type);
- mTags.push_back({Downmix::type, dm});
+ void validateParameters(Downmix::Type type) {
+ auto leId = Downmix::Id::make<Downmix::Id::commonTag>(Downmix::Tag(Downmix::type));
+ auto id = Parameter::Id::make<Parameter::Id::downmixTag>(leId);
+ // get parameter
+ Parameter getParam;
+ EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
+ auto expectedParam = createDownmixParam(type);
+ EXPECT_EQ(expectedParam, getParam) << "\nexpectedParam:" << expectedParam.toString()
+ << "\ngetParam:" << getParam.toString();
}
Parameter::Specific getDefaultParamSpecific() {
@@ -108,14 +134,281 @@
return specific;
}
- private:
- std::vector<std::pair<Downmix::Tag, Downmix>> mTags;
- void CleanUp() { mTags.clear(); }
+ void setDataTestParams(int32_t layoutType) {
+ mInputBuffer.resize(kBufferSize);
+ mOutputBuffer.resize(kBufferSize);
+
+ // Get the number of channels used
+ mInputChannelCount = getChannelCount(
+ AudioChannelLayout::make<AudioChannelLayout::layoutMask>(layoutType));
+
+ // In case of downmix, output is always configured to stereo layout.
+ mOutputBufferSize = (mInputBuffer.size() / mInputChannelCount) * kOutputChannelCount;
+ }
+
+ // Generate mInputBuffer values between -kMaxDownmixSample to kMaxDownmixSample
+ void generateInputBuffer(size_t position, bool isStrip) {
+ size_t increment;
+ if (isStrip)
+ // Fill input at all the channels
+ increment = 1;
+ else
+ // Fill input at only one channel
+ increment = mInputChannelCount;
+
+ for (size_t i = position; i < mInputBuffer.size(); i += increment) {
+ mInputBuffer[i] =
+ ((static_cast<float>(std::rand()) / RAND_MAX) * 2 - 1) * kMaxDownmixSample;
+ }
+ }
+
+ bool isLayoutValid(int32_t inputLayout) {
+ if (inputLayout & kMaxChannelMask) {
+ return false;
+ }
+ return true;
+ }
+
+ static constexpr long kInputFrameCount = 100, kOutputFrameCount = 100;
+ std::shared_ptr<IFactory> mFactory;
+ Descriptor mDescriptor;
+ std::shared_ptr<IEffect> mEffect;
+ IEffect::OpenEffectReturn mOpenEffectReturn;
+
+ std::vector<float> mInputBuffer;
+ std::vector<float> mOutputBuffer;
+ size_t mInputChannelCount;
+ size_t mOutputBufferSize;
+ static constexpr size_t kBufferSize = 128;
+ static constexpr float kMaxDownmixSample = 1;
+ static constexpr int kOutputChannelCount = 2;
+ // Mask for layouts greater than MAX_INPUT_CHANNELS_SUPPORTED
+ static constexpr int32_t kMaxChannelMask =
+ ~((1 << ChannelMix<AUDIO_CHANNEL_OUT_STEREO>::MAX_INPUT_CHANNELS_SUPPORTED) - 1);
+};
+
+/**
+ * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
+ * VtsAudioEffectTargetTest.
+ */
+enum ParamName { PARAM_INSTANCE_NAME, PARAM_TYPE };
+
+using DownmixParamTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Downmix::Type>;
+
+class DownmixParamTest : public ::testing::TestWithParam<DownmixParamTestParam>,
+ public DownmixEffectHelper {
+ public:
+ DownmixParamTest() : mParamType(std::get<PARAM_TYPE>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override { SetUpDownmix(); }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ const Downmix::Type mParamType;
};
TEST_P(DownmixParamTest, SetAndGetType) {
- EXPECT_NO_FATAL_FAILURE(addTypeParam(mParamType));
- SetAndGetDownmixParameters();
+ ASSERT_NO_FATAL_FAILURE(setParameters(mParamType));
+ ASSERT_NO_FATAL_FAILURE(validateParameters(mParamType));
+}
+
+enum FoldParamName { FOLD_INSTANCE_NAME, FOLD_INPUT_LAYOUT, FOLD_TEST_CHANNEL };
+
+using DownmixDataTestParamFold =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class DownmixFoldDataTest : public ::testing::TestWithParam<DownmixDataTestParamFold>,
+ public DownmixEffectHelper {
+ public:
+ DownmixFoldDataTest() : mInputChannelLayout(std::get<FOLD_INPUT_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<FOLD_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ SetUpDownmix(mInputChannelLayout);
+ if (!isLayoutValid(mInputChannelLayout)) {
+ GTEST_SKIP() << "Layout not supported \n";
+ }
+ setDataTestParams(mInputChannelLayout);
+ }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ void checkAtLeft(int32_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate Left channel has audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i], 0);
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[j]);
+ }
+ // Validate Right channel has no audio
+ ASSERT_EQ(mOutputBuffer[i + 1], 0);
+ }
+ }
+
+ void checkAtRight(int32_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate Left channel has no audio
+ ASSERT_EQ(mOutputBuffer[i], 0);
+ // Validate Right channel has audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i + 1], 0);
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]);
+ }
+ }
+ }
+
+ void checkAtCenter(size_t position) {
+ for (size_t i = 0, j = position; i < mOutputBufferSize;
+ i += kOutputChannelCount, j += mInputChannelCount) {
+ // Validate both channels have audio
+ if (mInputBuffer[j] != 0) {
+ ASSERT_NE(mOutputBuffer[i], 0);
+ ASSERT_NE(mOutputBuffer[i + 1], 0);
+
+ } else {
+ // No change in output when input is 0
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[j]);
+ ASSERT_EQ(mOutputBuffer[i + 1], mInputBuffer[j]);
+ }
+ }
+ }
+
+ void validateOutput(int32_t channel, size_t position) {
+ switch (channel) {
+ case AudioChannelLayout::CHANNEL_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_BACK_LEFT:
+ case AudioChannelLayout::CHANNEL_SIDE_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_LEFT:
+ case AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT:
+ case AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT:
+ checkAtLeft(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_BACK_RIGHT:
+ case AudioChannelLayout::CHANNEL_SIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT:
+ case AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT:
+ case AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2:
+ checkAtRight(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_BACK_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER:
+ case AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER:
+ case AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_CENTER:
+ case AudioChannelLayout::CHANNEL_TOP_BACK_CENTER:
+ checkAtCenter(position);
+ break;
+
+ case AudioChannelLayout::CHANNEL_LOW_FREQUENCY:
+ // If CHANNEL_LOW_FREQUENCY_2 is supported
+ if (mInputChannelLayout & AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2) {
+ // Validate that only Left channel has audio
+ checkAtLeft(position);
+ } else {
+ // Validate that both channels have audio
+ checkAtCenter(position);
+ }
+ break;
+ }
+ }
+
+ std::set<int32_t> getInputChannelLayouts() {
+ std::set<int32_t> supportedChannels;
+ for (int32_t channel : kChannels) {
+ if ((mInputChannelLayout & channel) == channel) {
+ supportedChannels.insert(channel);
+ }
+ }
+ return supportedChannels;
+ }
+
+ int32_t mInputChannelLayout;
+};
+
+TEST_P(DownmixFoldDataTest, DownmixProcessData) {
+ // Set FOLD type parameter
+ ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::FOLD));
+
+ // Get all the channels from input layout
+ std::set<int32_t> supportedChannels = getInputChannelLayouts();
+
+ for (int32_t channel : supportedChannels) {
+ size_t position = std::distance(supportedChannels.begin(), supportedChannels.find(channel));
+ generateInputBuffer(position, false /*isStripe*/);
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
+ validateOutput(channel, position);
+ std::fill(mInputBuffer.begin(), mInputBuffer.end(), 0);
+ }
+}
+
+enum StripParamName { STRIP_INSTANCE_NAME, STRIP_INPUT_LAYOUT };
+
+using DownmixStripDataTestParam =
+ std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t>;
+
+class DownmixStripDataTest : public ::testing::TestWithParam<DownmixStripDataTestParam>,
+ public DownmixEffectHelper {
+ public:
+ DownmixStripDataTest() : mInputChannelLayout(std::get<STRIP_INPUT_LAYOUT>(GetParam())) {
+ std::tie(mFactory, mDescriptor) = std::get<STRIP_INSTANCE_NAME>(GetParam());
+ }
+
+ void SetUp() override {
+ SetUpDownmix(mInputChannelLayout);
+ if (!isLayoutValid(mInputChannelLayout)) {
+ GTEST_SKIP() << "Layout not supported \n";
+ }
+ setDataTestParams(mInputChannelLayout);
+ }
+
+ void TearDown() override { TearDownDownmix(); }
+
+ void validateOutput() {
+ ASSERT_EQ(kBufferSize, mInputBuffer.size());
+ ASSERT_GE(kBufferSize, mOutputBufferSize);
+ for (size_t i = 0, j = 0; i < kBufferSize && j < mOutputBufferSize;
+ i += mInputChannelCount, j += kOutputChannelCount) {
+ ASSERT_EQ(mOutputBuffer[j], mInputBuffer[i]);
+ ASSERT_EQ(mOutputBuffer[j + 1], mInputBuffer[i + 1]);
+ }
+ for (size_t i = mOutputBufferSize; i < kBufferSize; i++) {
+ ASSERT_EQ(mOutputBuffer[i], mInputBuffer[i]);
+ }
+ }
+
+ int32_t mInputChannelLayout;
+};
+
+TEST_P(DownmixStripDataTest, DownmixProcessData) {
+ // Set STRIP type parameter
+ ASSERT_NO_FATAL_FAILURE(setParameters(Downmix::Type::STRIP));
+
+ // Generate input buffer, call process and compare outputs
+ generateInputBuffer(0 /*position*/, true /*isStripe*/);
+ ASSERT_NO_FATAL_FAILURE(
+ processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
+ validateOutput();
}
INSTANTIATE_TEST_SUITE_P(
@@ -134,6 +427,39 @@
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixParamTest);
+INSTANTIATE_TEST_SUITE_P(
+ DownmixTest, DownmixFoldDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDownmix())),
+ testing::ValuesIn(kLayoutValues)),
+ [](const testing::TestParamInfo<DownmixFoldDataTest::ParamType>& info) {
+ auto descriptor = std::get<FOLD_INSTANCE_NAME>(info.param).second;
+ std::string layout = std::to_string(std::get<FOLD_INPUT_LAYOUT>(info.param));
+ std::string name = getPrefix(descriptor) + "_fold" + "_layout" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixFoldDataTest);
+
+INSTANTIATE_TEST_SUITE_P(
+ DownmixTest, DownmixStripDataTest,
+ ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+ IFactory::descriptor, getEffectTypeUuidDownmix())),
+ testing::ValuesIn(kLayoutValues)),
+ [](const testing::TestParamInfo<DownmixStripDataTest::ParamType>& info) {
+ auto descriptor = std::get<STRIP_INSTANCE_NAME>(info.param).second;
+ std::string layout =
+ std::to_string(static_cast<int>(std::get<STRIP_INPUT_LAYOUT>(info.param)));
+ std::string name = getPrefix(descriptor) + "_strip" + "_layout" + layout;
+ std::replace_if(
+ name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+ return name;
+ });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DownmixStripDataTest);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
diff --git a/audio/effect/5.0/xml/Android.bp b/audio/effect/5.0/xml/Android.bp
index 7982e2a..ed12e38 100644
--- a/audio/effect/5.0/xml/Android.bp
+++ b/audio/effect/5.0/xml/Android.bp
@@ -9,6 +9,6 @@
xsd_config {
name: "audio_effects_conf_V5_0",
- srcs: ["audio_effects_conf.xsd"],
+ srcs: [":audio_effects_conf_V2_0"],
package_name: "audio.effects.V5_0",
}
diff --git a/audio/effect/5.0/xml/audio_effects_conf.xsd b/audio/effect/5.0/xml/audio_effects_conf.xsd
deleted file mode 120000
index 9d85fa7..0000000
--- a/audio/effect/5.0/xml/audio_effects_conf.xsd
+++ /dev/null
@@ -1 +0,0 @@
-../../2.0/xml/audio_effects_conf.xsd
\ No newline at end of file
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index aad07de..fe749f6 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -102,7 +102,7 @@
static bool hasIpv4(std::string ifname) {
auto ifr = ifreqs::fromName(ifname);
- switch (const auto status = ifreqs::trySend(SIOCGIFADDR, ifr)) {
+ switch (ifreqs::trySend(SIOCGIFADDR, ifr)) {
case 0:
return true;
case EADDRNOTAVAIL:
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
index 6a02cf3..abbcd35 100644
--- a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VehiclePropertyStore.h
@@ -70,6 +70,16 @@
* example wasn't registered. */
bool writeValue(const VehiclePropValue& propValue, bool updateStatus);
+ /*
+ * Stores provided value. Returns true if value was written returns false if config for
+ * example wasn't registered.
+ *
+ * The property value's timestamp will be set to the current ElapsedRealTimeNano.
+ */
+ bool writeValueWithCurrentTimestamp(VehiclePropValue* propValuePtr, bool updateStatus);
+
+ std::unique_ptr<VehiclePropValue> refreshTimestamp(int32_t propId, int32_t areaId);
+
void removeValue(const VehiclePropValue& propValue);
void removeValuesForProperty(int32_t propId);
@@ -94,6 +104,8 @@
std::unordered_map<int32_t /* VehicleProperty */, RecordConfig> mConfigs;
PropertyMap mPropertyValues; // Sorted map of RecordId : VehiclePropValue.
+
+ bool writeValueLocked(const VehiclePropValue& propValue, bool updateStatus);
};
} // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
index 6087bfa..c12904e 100644
--- a/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/2.0/default/common/src/VehiclePropertyStore.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "VehiclePropertyStore"
#include <log/log.h>
+#include <utils/SystemClock.h>
#include <common/include/vhal_v2_0/VehicleUtils.h>
#include "VehiclePropertyStore.h"
@@ -41,9 +42,7 @@
mConfigs.insert({ config.prop, RecordConfig { config, tokenFunc } });
}
-bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue,
- bool updateStatus) {
- MuxGuard g(mLock);
+bool VehiclePropertyStore::writeValueLocked(const VehiclePropValue& propValue, bool updateStatus) {
if (!mConfigs.count(propValue.prop)) return false;
RecordId recId = getRecordIdLocked(propValue);
@@ -68,6 +67,36 @@
return true;
}
+bool VehiclePropertyStore::writeValue(const VehiclePropValue& propValue, bool updateStatus) {
+ MuxGuard g(mLock);
+
+ return writeValueLocked(propValue, updateStatus);
+}
+
+bool VehiclePropertyStore::writeValueWithCurrentTimestamp(VehiclePropValue* propValuePtr,
+ bool updateStatus) {
+ MuxGuard g(mLock);
+
+ propValuePtr->timestamp = elapsedRealtimeNano();
+ return writeValueLocked(*propValuePtr, updateStatus);
+}
+
+std::unique_ptr<VehiclePropValue> VehiclePropertyStore::refreshTimestamp(int32_t propId,
+ int32_t areaId) {
+ MuxGuard g(mLock);
+ RecordId recId = getRecordIdLocked(VehiclePropValue{
+ .prop = propId,
+ .areaId = areaId,
+ });
+ auto it = mPropertyValues.find(recId);
+ if (it == mPropertyValues.end()) {
+ return nullptr;
+ }
+
+ it->second.timestamp = elapsedRealtimeNano();
+ return std::make_unique<VehiclePropValue>(it->second);
+}
+
void VehiclePropertyStore::removeValue(const VehiclePropValue& propValue) {
MuxGuard g(mLock);
RecordId recId = getRecordIdLocked(propValue);
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
index 318e9dd..b56a190 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHal.cpp
@@ -57,12 +57,6 @@
return nullptr;
}
-VehicleHal::VehiclePropValuePtr addTimestamp(VehicleHal::VehiclePropValuePtr v) {
- if (v.get()) {
- v->timestamp = elapsedRealtimeNano();
- }
- return v;
-}
} // namespace
VehicleHal::VehiclePropValuePtr DefaultVehicleHal::createVhalHeartBeatProp() {
@@ -102,7 +96,7 @@
*outStatus = StatusCode::INTERNAL_ERROR;
}
}
- return addTimestamp(std::move(v));
+ return v;
}
VehicleHal::VehiclePropValuePtr DefaultVehicleHal::get(const VehiclePropValue& requestedPropValue,
@@ -118,13 +112,13 @@
if (propId == OBD2_FREEZE_FRAME) {
v = getValuePool()->obtainComplex();
*outStatus = fillObd2FreezeFrame(mPropStore, requestedPropValue, v.get());
- return addTimestamp(std::move(v));
+ return v;
}
if (propId == OBD2_FREEZE_FRAME_INFO) {
v = getValuePool()->obtainComplex();
*outStatus = fillObd2DtcInfo(mPropStore, v.get());
- return addTimestamp(std::move(v));
+ return v;
}
auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue);
@@ -139,7 +133,7 @@
} else {
*outStatus = StatusCode::TRY_AGAIN;
}
- return addTimestamp(std::move(v));
+ return v;
}
std::vector<VehiclePropConfig> DefaultVehicleHal::listProperties() {
@@ -486,26 +480,42 @@
void DefaultVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) {
auto& pool = *getValuePool();
-
for (int32_t property : properties) {
- VehiclePropValuePtr v;
+ std::vector<VehiclePropValuePtr> events;
if (isContinuousProperty(property)) {
- auto internalPropValue = mPropStore->readValueOrNull(property);
- if (internalPropValue != nullptr) {
- v = pool.obtain(*internalPropValue);
+ const VehiclePropConfig* config = mPropStore->getConfigOrNull(property);
+ std::vector<int32_t> areaIds;
+ if (isGlobalProp(property)) {
+ areaIds.push_back(0);
+ } else {
+ for (auto& c : config->areaConfigs) {
+ areaIds.push_back(c.areaId);
+ }
+ }
+
+ for (int areaId : areaIds) {
+ auto v = pool.obtain(*mPropStore->refreshTimestamp(property, areaId));
+ if (v.get()) {
+ events.push_back(std::move(v));
+ }
}
} else if (property == static_cast<int32_t>(VehicleProperty::VHAL_HEARTBEAT)) {
// VHAL_HEARTBEAT is not a continuous value, but it needs to be updated periodically.
// So, the update is done through onContinuousPropertyTimer.
- v = doInternalHealthCheck();
+ auto v = doInternalHealthCheck();
+ if (!v.get()) {
+ // Internal health check failed.
+ continue;
+ }
+ mPropStore->writeValueWithCurrentTimestamp(v.get(), /*updateStatus=*/true);
+ events.push_back(std::move(v));
} else {
ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property);
continue;
}
- if (v.get()) {
- v->timestamp = elapsedRealtimeNano();
- doHalEvent(std::move(v));
+ for (VehiclePropValuePtr& event : events) {
+ doHalEvent(std::move(event));
}
}
}
@@ -556,7 +566,7 @@
void DefaultVehicleHal::onPropertyValue(const VehiclePropValue& value, bool updateStatus) {
VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value);
- if (mPropStore->writeValue(*updatedPropValue, updateStatus)) {
+ if (mPropStore->writeValueWithCurrentTimestamp(updatedPropValue.get(), updateStatus)) {
doHalEvent(std::move(updatedPropValue));
}
}
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index edd4484..c876836 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -81,8 +81,13 @@
using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_CLEAR;
using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_FREEZE_FRAME_INFO;
using ::android::hardware::automotive::vehicle::V2_0::impl::OBD2_LIVE_FRAME;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_FRONT_LEFT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_FRONT_RIGHT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_REAR_LEFT;
+using ::android::hardware::automotive::vehicle::V2_0::impl::WHEEL_REAR_RIGHT;
using ::testing::HasSubstr;
+using ::testing::UnorderedElementsAre;
using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
@@ -152,7 +157,7 @@
TEST_F(DefaultVhalImplTest, testListProperties) {
std::vector<VehiclePropConfig> configs = mHal->listProperties();
- EXPECT_EQ((size_t)124, configs.size());
+ EXPECT_EQ((size_t)125, configs.size());
}
TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
@@ -346,6 +351,38 @@
EXPECT_EQ(1.0f, lastEvent->value.floatValues[0]);
}
+TEST_F(DefaultVhalImplTest, testSubscribeContinuous_withMultipleAreaIds) {
+ // Clear existing events.
+ mEventQueue.flush();
+ int propId = toInt(VehicleProperty::TIRE_PRESSURE);
+
+ auto status = mHal->subscribe(propId, 1);
+
+ ASSERT_EQ(StatusCode::OK, status);
+
+ std::vector<VehiclePropValuePtr> receivedEvents;
+ // Wait for 2 updates, each for 4 area IDs.
+ waitForEvents(&receivedEvents, 4 * 2);
+
+ std::vector<int> areasForUpdate1;
+ std::vector<int> areasForUpdate2;
+
+ for (size_t i = 0; i < receivedEvents.size(); i++) {
+ ASSERT_EQ(receivedEvents[i]->prop, propId);
+
+ if (i < 4) {
+ areasForUpdate1.push_back(receivedEvents[i]->areaId);
+ } else {
+ areasForUpdate2.push_back(receivedEvents[i]->areaId);
+ }
+ }
+
+ ASSERT_THAT(areasForUpdate1, UnorderedElementsAre(WHEEL_FRONT_LEFT, WHEEL_FRONT_RIGHT,
+ WHEEL_REAR_LEFT, WHEEL_REAR_RIGHT));
+ ASSERT_THAT(areasForUpdate2, UnorderedElementsAre(WHEEL_FRONT_LEFT, WHEEL_FRONT_RIGHT,
+ WHEEL_REAR_LEFT, WHEEL_REAR_RIGHT));
+}
+
TEST_F(DefaultVhalImplTest, testSubscribeInvalidProp) {
EXPECT_EQ(StatusCode::INVALID_ARG, mHal->subscribe(toInt(VehicleProperty::INFO_MAKE), 10));
}
@@ -1318,7 +1355,6 @@
ASSERT_EQ((size_t)1, events.size());
ASSERT_EQ((size_t)1, events[0]->value.int32Values.size());
EXPECT_EQ(2022, events[0]->value.int32Values[0]);
- EXPECT_EQ(1000, events[0]->timestamp);
VehiclePropValue value;
StatusCode status;
@@ -1352,7 +1388,6 @@
ASSERT_EQ((size_t)1, events.size());
EXPECT_EQ(0, events[0]->value.int32Values[0]);
EXPECT_EQ(DOOR_1_LEFT, events[0]->areaId);
- EXPECT_EQ(1000, events[0]->timestamp);
VehiclePropValue value;
StatusCode status;
@@ -1391,7 +1426,6 @@
ASSERT_EQ((size_t)1, events.size());
ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
EXPECT_EQ(10.5, events[0]->value.floatValues[0]);
- EXPECT_EQ(1000, events[0]->timestamp);
VehiclePropValue value;
StatusCode status;
diff --git a/automotive/vehicle/OWNERS b/automotive/vehicle/OWNERS
index d6969e5..9a6b65d 100644
--- a/automotive/vehicle/OWNERS
+++ b/automotive/vehicle/OWNERS
@@ -1,2 +1,9 @@
ericjeong@google.com
shanyu@google.com
+
+# GRPC VHAL
+per-file aidl/impl/grpc/** = chenhaosjtuacm@google.com, egranata@google.com
+
+# Property definition
+per-file aidl_property/** = tylertrephan@google.com
+per-file aidl/generated_lib/** = tylertrephan@google.com
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index c4e2c64..6b94277 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -68,9 +68,11 @@
{VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess::READ},
{VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess::READ},
{VehicleProperty::RANGE_REMAINING, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess::READ},
{VehicleProperty::TIRE_PRESSURE, VehiclePropertyAccess::READ},
{VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess::READ},
{VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::IMPACT_DETECTED, VehiclePropertyAccess::READ},
{VehicleProperty::GEAR_SELECTION, VehiclePropertyAccess::READ},
{VehicleProperty::CURRENT_GEAR, VehiclePropertyAccess::READ},
{VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyAccess::READ},
@@ -83,6 +85,7 @@
{VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
{VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
{VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
@@ -120,6 +123,7 @@
{VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyAccess::READ},
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
@@ -169,11 +173,13 @@
{VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess::READ},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess::READ},
{VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyAccess::READ},
{VehicleProperty::WINDOW_POS, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::WINDOW_MOVE, VehiclePropertyAccess::READ_WRITE},
@@ -248,6 +254,7 @@
{VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyAccess::WRITE},
{VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyAccess::WRITE},
+ {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess::READ},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
@@ -273,6 +280,16 @@
{VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index bd6c705..94cf4e8 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -68,9 +68,11 @@
{VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::RANGE_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+ {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::TIRE_PRESSURE, VehiclePropertyChangeMode::CONTINUOUS},
{VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::IMPACT_DETECTED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::GEAR_SELECTION, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CURRENT_GEAR, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyChangeMode::ON_CHANGE},
@@ -83,6 +85,7 @@
{VehicleProperty::ABS_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -120,6 +123,7 @@
{VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode::STATIC},
{VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -169,11 +173,13 @@
{VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::WINDOW_POS, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::WINDOW_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
@@ -248,6 +254,7 @@
{VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::VEHICLE_IN_USE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
@@ -273,6 +280,16 @@
{VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode::ON_CHANGE},
{VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+ {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index 6e66632..0232eba 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -60,9 +60,11 @@
Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyAccess.READ),
@@ -75,6 +77,7 @@
Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
@@ -112,6 +115,7 @@
Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
@@ -161,11 +165,13 @@
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyAccess.READ_WRITE),
@@ -240,6 +246,7 @@
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE),
Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyAccess.WRITE),
+ Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
@@ -264,7 +271,17 @@
Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess.READ),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ)
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
index 522c82f..d4ef724 100644
--- a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
@@ -60,9 +60,11 @@
Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+ Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyChangeMode.ON_CHANGE),
@@ -75,6 +77,7 @@
Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -112,6 +115,7 @@
Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode.STATIC),
Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -161,11 +165,13 @@
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
@@ -240,6 +246,7 @@
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
@@ -264,7 +271,17 @@
Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode.ON_CHANGE),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE)
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
);
}
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
index 144d0e1..80fd556 100644
--- a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
@@ -37,6 +37,7 @@
Map.entry(VehicleProperty.INFO_DRIVER_SEAT, List.of(VehicleAreaSeat.class)),
Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, List.of(PortLocationType.class)),
Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, List.of(VehicleOilLevel.class)),
+ Map.entry(VehicleProperty.IMPACT_DETECTED, List.of(ImpactSensorLocation.class)),
Map.entry(VehicleProperty.GEAR_SELECTION, List.of(VehicleGear.class)),
Map.entry(VehicleProperty.CURRENT_GEAR, List.of(VehicleGear.class)),
Map.entry(VehicleProperty.TURN_SIGNAL_STATE, List.of(VehicleTurnSignal.class)),
@@ -53,6 +54,7 @@
Map.entry(VehicleProperty.HW_CUSTOM_INPUT, List.of(CustomInputType.class)),
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, List.of(VehicleLightState.class)),
Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, List.of(VehicleLightSwitch.class)),
+ Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, List.of(VehicleAirbagLocation.class)),
Map.entry(VehicleProperty.SEAT_OCCUPANCY, List.of(VehicleSeatOccupancyState.class)),
Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, List.of(WindshieldWipersState.class)),
Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, List.of(WindshieldWipersSwitch.class)),
@@ -81,6 +83,7 @@
Map.entry(VehicleProperty.TRAILER_PRESENT, List.of(TrailerState.class)),
Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, List.of(GsrComplianceRequirementType.class)),
Map.entry(VehicleProperty.SHUTDOWN_REQUEST, List.of(VehicleApPowerStateShutdownParam.class)),
+ Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, List.of(VehicleAutonomousState.class)),
Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(AutomaticEmergencyBrakingState.class, ErrorState.class)),
Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, List.of(ForwardCollisionWarningState.class, ErrorState.class)),
Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, List.of(BlindSpotWarningState.class, ErrorState.class)),
@@ -93,7 +96,12 @@
Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, List.of(CruiseControlState.class, ErrorState.class)),
Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, List.of(CruiseControlCommand.class)),
Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, List.of(HandsOnDetectionDriverState.class, ErrorState.class)),
- Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, List.of(HandsOnDetectionWarning.class, ErrorState.class))
+ Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, List.of(HandsOnDetectionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, List.of(DriverDrowsinessAttentionState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, List.of(DriverDrowsinessAttentionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, List.of(DriverDistractionState.class, ErrorState.class)),
+ Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, List.of(DriverDistractionWarning.class, ErrorState.class)),
+ Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, List.of(LowSpeedCollisionWarningState.class, ErrorState.class))
);
}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 82dc8a6..2b99d7a 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -41,6 +41,10 @@
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlState;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
using ::aidl::android::hardware::automotive::vehicle::EmergencyLaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
@@ -51,17 +55,21 @@
using ::aidl::android::hardware::automotive::vehicle::GsrComplianceRequirementType;
using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionDriverState;
using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionWarning;
+using ::aidl::android::hardware::automotive::vehicle::ImpactSensorLocation;
using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistCommand;
using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistState;
using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
+using ::aidl::android::hardware::automotive::vehicle::LowSpeedCollisionWarningState;
using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAirbagLocation;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAutonomousState;
using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
@@ -240,6 +248,12 @@
std::make_unique<ConstantParser<WindshieldWipersState>>();
mConstantParsersByType["WindshieldWipersSwitch"] =
std::make_unique<ConstantParser<WindshieldWipersSwitch>>();
+ mConstantParsersByType["VehicleAutonomousState"] =
+ std::make_unique<ConstantParser<VehicleAutonomousState>>();
+ mConstantParsersByType["VehicleAirbagLocation"] =
+ std::make_unique<ConstantParser<VehicleAirbagLocation>>();
+ mConstantParsersByType["ImpactSensorLocation"] =
+ std::make_unique<ConstantParser<ImpactSensorLocation>>();
mConstantParsersByType["EmergencyLaneKeepAssistState"] =
std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
mConstantParsersByType["CruiseControlType"] =
@@ -252,6 +266,14 @@
std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
mConstantParsersByType["HandsOnDetectionWarning"] =
std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
+ mConstantParsersByType["DriverDrowsinessAttentionState"] =
+ std::make_unique<ConstantParser<DriverDrowsinessAttentionState>>();
+ mConstantParsersByType["DriverDrowsinessAttentionWarning"] =
+ std::make_unique<ConstantParser<DriverDrowsinessAttentionWarning>>();
+ mConstantParsersByType["DriverDistractionState"] =
+ std::make_unique<ConstantParser<DriverDistractionState>>();
+ mConstantParsersByType["DriverDistractionWarning"] =
+ std::make_unique<ConstantParser<DriverDistractionWarning>>();
mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
mConstantParsersByType["AutomaticEmergencyBrakingState"] =
std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
@@ -267,6 +289,8 @@
std::make_unique<ConstantParser<LaneCenteringAssistCommand>>();
mConstantParsersByType["LaneCenteringAssistState"] =
std::make_unique<ConstantParser<LaneCenteringAssistState>>();
+ mConstantParsersByType["LowSpeedCollisionWarningState"] =
+ std::make_unique<ConstantParser<LowSpeedCollisionWarningState>>();
mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
mConstantParsersByType["TestVendorProperty"] =
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index d3bb60c..3dcdb9d 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -1328,6 +1328,75 @@
]
},
{
+ "property": "VehicleProperty::SEAT_AIRBAGS_DEPLOYED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::KNEE",
+ "VehicleAirbagLocation::LEFT_SIDE",
+ "VehicleAirbagLocation::RIGHT_SIDE",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::KNEE",
+ "VehicleAirbagLocation::LEFT_SIDE",
+ "VehicleAirbagLocation::RIGHT_SIDE",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT",
+ "supportedEnumValues": [
+ "VehicleAirbagLocation::FRONT",
+ "VehicleAirbagLocation::CURTAIN"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": "Constants::SEAT_1_LEFT"
+ },
+ {
+ "areaId": "Constants::SEAT_1_RIGHT"
+ },
+ {
+ "areaId": "Constants::SEAT_2_LEFT"
+ },
+ {
+ "areaId": "Constants::SEAT_2_RIGHT"
+ },
+ {
+ "areaId": "Constants::SEAT_2_CENTER"
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::SEAT_OCCUPANCY",
"defaultValue": {
"int32Values": [
@@ -1560,6 +1629,16 @@
"minSampleRate": 1.0
},
{
+ "property": "VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE",
+ "defaultValue": {
+ "floatValues": [
+ 25.0
+ ]
+ },
+ "maxSampleRate": 2.0,
+ "minSampleRate": 1.0
+ },
+ {
"property": "VehicleProperty::TIRE_PRESSURE",
"defaultValue": {
"floatValues": [
@@ -2503,6 +2582,27 @@
}
},
{
+ "property": "VehicleProperty::IMPACT_DETECTED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ImpactSensorLocation::FRONT",
+ "ImpactSensorLocation::FRONT_LEFT_DOOR_SIDE",
+ "ImpactSensorLocation::FRONT_RIGHT_DOOR_SIDE",
+ "ImpactSensorLocation::REAR_LEFT_DOOR_SIDE",
+ "ImpactSensorLocation::REAR_RIGHT_DOOR_SIDE",
+ "ImpactSensorLocation::REAR"
+ ]
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::DOOR_LOCK",
"areas": [
{
@@ -3111,6 +3211,14 @@
]
},
{
+ "property": "VehicleProperty::VALET_MODE_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 0
+ ]
+ }
+ },
+ {
"property": "VehicleProperty::OBD2_LIVE_FRAME",
"configArray": [
0,
@@ -3546,6 +3654,117 @@
]
},
{
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDrowsinessAttentionState::KSS_RATING_1_EXTREMELY_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_2_VERY_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_4_RATHER_ALERT",
+ "DriverDrowsinessAttentionState::KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
+ "DriverDrowsinessAttentionState::KSS_RATING_6_SOME_SLEEPINESS",
+ "DriverDrowsinessAttentionState::KSS_RATING_7_SLEEPY_NO_EFFORT",
+ "DriverDrowsinessAttentionState::KSS_RATING_8_SLEEPY_SOME_EFFORT",
+ "DriverDrowsinessAttentionState::KSS_RATING_9_VERY_SLEEPY"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDrowsinessAttentionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDrowsinessAttentionWarning::NO_WARNING",
+ "DriverDrowsinessAttentionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDistractionState::NOT_DISTRACTED"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDistractionState::NOT_DISTRACTED",
+ "DriverDistractionState::DISTRACTED"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING",
+ "defaultValue": {
+ "int32Values": [
+ "DriverDistractionWarning::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "DriverDistractionWarning::NO_WARNING",
+ "DriverDistractionWarning::WARNING"
+ ]
+ }
+ ]
+ },
+ {
"property": "VehicleProperty::INITIAL_USER_INFO"
},
{
@@ -3675,6 +3894,14 @@
}
},
{
+ "property": "VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL",
+ "defaultValue": {
+ "int32Values": [
+ "VehicleAutonomousState::LEVEL_0"
+ ]
+ }
+ },
+ {
"property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
"defaultValue": {
"int32Values": [
@@ -3872,6 +4099,43 @@
]
}
]
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
+ },
+ {
+ "property": "VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE",
+ "defaultValue": {
+ "int32Values": [
+ "LowSpeedCollisionWarningState::NO_WARNING"
+ ]
+ },
+ "areas": [
+ {
+ "areaId": 0,
+ "supportedEnumValues": [
+ "ErrorState::NOT_AVAILABLE_SAFETY",
+ "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+ "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+ "ErrorState::NOT_AVAILABLE_DISABLED",
+ "LowSpeedCollisionWarningState::NO_WARNING",
+ "LowSpeedCollisionWarningState::WARNING"
+ ]
+ }
+ ]
+ },
+ {
+ "property": "VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED",
+ "defaultValue": {
+ "int32Values": [
+ 1
+ ]
+ }
}
]
}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 26fdee6..8cd92b3 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -142,6 +142,16 @@
void handleRequestsOnce();
};
+ struct RefreshInfo {
+ VehiclePropertyStore::EventMode eventMode;
+ int64_t intervalInNanos;
+ };
+
+ struct ActionForInterval {
+ std::unordered_set<PropIdAreaId, PropIdAreaIdHash> propIdAreaIdsToRefresh;
+ std::shared_ptr<RecurrentTimer::Callback> recurrentAction;
+ };
+
const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
const std::unique_ptr<FakeUserHal> mFakeUserHal;
// RecurrentTimer is thread-safe.
@@ -154,8 +164,9 @@
std::unique_ptr<const PropertySetErrorCallback> mOnPropertySetErrorCallback;
std::mutex mLock;
- std::unordered_map<PropIdAreaId, std::shared_ptr<RecurrentTimer::Callback>, PropIdAreaIdHash>
- mRecurrentActions GUARDED_BY(mLock);
+ std::unordered_map<PropIdAreaId, RefreshInfo, PropIdAreaIdHash> mRefreshInfoByPropIdAreaId
+ GUARDED_BY(mLock);
+ std::unordered_map<int64_t, ActionForInterval> mActionByIntervalInNanos GUARDED_BY(mLock);
std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
mSavedProps GUARDED_BY(mLock);
std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
@@ -183,6 +194,10 @@
void onValueChangeCallback(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)
EXCLUDES(mLock);
+ // The callback that would be called when multiple vehicle property value changes happen.
+ void onValuesChangeCallback(
+ std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue> values)
+ EXCLUDES(mLock);
// Load the config files in format '*.json' from the directory and parse the config files
// into a map from property ID to ConfigDeclarations.
void loadPropConfigsFromDir(const std::string& dirPath,
@@ -276,6 +291,11 @@
const aidl::android::hardware::automotive::vehicle::VehiclePropConfig&
vehiclePropConfig) REQUIRES(mLock);
+ void registerRefreshLocked(PropIdAreaId propIdAreaId, VehiclePropertyStore::EventMode eventMode,
+ float sampleRateHz) REQUIRES(mLock);
+ void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
+ void refreshTimeStampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
+
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
int32_t keyCode, int32_t targetDisplay);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index acee9b3..8df0451 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -53,6 +53,10 @@
using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
using ::aidl::android::hardware::automotive::vehicle::ErrorState;
using ::aidl::android::hardware::automotive::vehicle::GetValueRequest;
using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
@@ -192,6 +196,42 @@
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
+ // Driver Drowsiness and Attention
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE),
+ },
+ },
+ // Driver Drowsiness and Attention Warning
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING),
+ },
+ },
+ // Driver Distraction
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_STATE),
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING),
+ },
+ },
+ // Driver Distraction Warning
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::DRIVER_DISTRACTION_WARNING),
+ },
+ },
+ // LSCW
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE),
+ },
+ },
};
} // namespace
@@ -304,17 +344,18 @@
}
// OBD2_LIVE_FRAME and OBD2_FREEZE_FRAME must be configured in default configs.
- auto maybeObd2LiveFrame = mServerSidePropStore->getConfig(OBD2_LIVE_FRAME);
+ auto maybeObd2LiveFrame = mServerSidePropStore->getPropConfig(OBD2_LIVE_FRAME);
if (maybeObd2LiveFrame.has_value()) {
- mFakeObd2Frame->initObd2LiveFrame(*maybeObd2LiveFrame.value());
+ mFakeObd2Frame->initObd2LiveFrame(maybeObd2LiveFrame.value());
}
- auto maybeObd2FreezeFrame = mServerSidePropStore->getConfig(OBD2_FREEZE_FRAME);
+ auto maybeObd2FreezeFrame = mServerSidePropStore->getPropConfig(OBD2_FREEZE_FRAME);
if (maybeObd2FreezeFrame.has_value()) {
- mFakeObd2Frame->initObd2FreezeFrame(*maybeObd2FreezeFrame.value());
+ mFakeObd2Frame->initObd2FreezeFrame(maybeObd2FreezeFrame.value());
}
- mServerSidePropStore->setOnValueChangeCallback(
- [this](const VehiclePropValue& value) { return onValueChangeCallback(value); });
+ mServerSidePropStore->setOnValuesChangeCallback([this](std::vector<VehiclePropValue> values) {
+ return onValuesChangeCallback(std::move(values));
+ });
}
std::vector<VehiclePropConfig> FakeVehicleHardware::getAllPropertyConfigs() const {
@@ -472,7 +513,7 @@
VhalResult<void> FakeVehicleHardware::setHvacTemperatureValueSuggestion(
const VehiclePropValue& hvacTemperatureValueSuggestion) {
auto hvacTemperatureSetConfigResult =
- mServerSidePropStore->getConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
+ mServerSidePropStore->getPropConfig(toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
if (!hvacTemperatureSetConfigResult.ok()) {
return StatusError(getErrorCode(hvacTemperatureSetConfigResult)) << StringPrintf(
@@ -499,7 +540,7 @@
}
auto updatedValue = mValuePool->obtain(hvacTemperatureValueSuggestion);
- const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value()->configArray;
+ const auto& hvacTemperatureSetConfigArray = hvacTemperatureSetConfigResult.value().configArray;
auto& hvacTemperatureValueSuggestionInput = updatedValue->value.floatValues;
updateHvacTemperatureValueSuggestionInput(hvacTemperatureSetConfigArray,
@@ -822,14 +863,14 @@
void FakeVehicleHardware::sendAdasPropertiesState(int32_t propertyId, int32_t state) {
auto& adasDependentPropIds = mAdasEnabledPropToAdasPropWithErrorState.find(propertyId)->second;
for (auto dependentPropId : adasDependentPropIds) {
- auto dependentPropConfigResult = mServerSidePropStore->getConfig(dependentPropId);
+ auto dependentPropConfigResult = mServerSidePropStore->getPropConfig(dependentPropId);
if (!dependentPropConfigResult.ok()) {
ALOGW("Failed to get config for ADAS property 0x%x, error: %s", dependentPropId,
getErrorMsg(dependentPropConfigResult).c_str());
continue;
}
auto& dependentPropConfig = dependentPropConfigResult.value();
- for (auto& areaConfig : dependentPropConfig->areaConfigs) {
+ for (auto& areaConfig : dependentPropConfig.areaConfigs) {
int32_t hardcoded_state = state;
// TODO: restore old/initial values here instead of hardcoded value (b/295542701)
if (state == 1 && dependentPropId == toInt(VehicleProperty::CRUISE_CONTROL_TYPE)) {
@@ -1702,12 +1743,12 @@
continue;
}
int32_t prop = propResult.value();
- auto result = mServerSidePropStore->getConfig(prop);
+ auto result = mServerSidePropStore->getPropConfig(prop);
if (!result.ok()) {
msg += StringPrintf("No property %d\n", prop);
continue;
}
- msg += dumpOnePropertyByConfig(rowNumber++, *result.value());
+ msg += dumpOnePropertyByConfig(rowNumber++, result.value());
}
return msg;
}
@@ -2014,7 +2055,7 @@
StatusCode FakeVehicleHardware::subscribe(SubscribeOptions options) {
int32_t propId = options.propId;
- auto configResult = mServerSidePropStore->getConfig(propId);
+ auto configResult = mServerSidePropStore->getPropConfig(propId);
if (!configResult.ok()) {
ALOGE("subscribe: property: %" PRId32 " is not supported", propId);
return StatusCode::INVALID_ARG;
@@ -2024,7 +2065,7 @@
for (int areaId : options.areaIds) {
if (StatusCode status = subscribePropIdAreaIdLocked(propId, areaId, options.sampleRate,
options.enableVariableUpdateRate,
- *configResult.value());
+ configResult.value());
status != StatusCode::OK) {
return status;
}
@@ -2047,6 +2088,81 @@
return false;
}
+void FakeVehicleHardware::refreshTimeStampForInterval(int64_t intervalInNanos) {
+ std::unordered_map<PropIdAreaId, VehiclePropertyStore::EventMode, PropIdAreaIdHash>
+ eventModeByPropIdAreaId;
+
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
+
+ if (mActionByIntervalInNanos.find(intervalInNanos) == mActionByIntervalInNanos.end()) {
+ ALOGE("No actions scheduled for the interval: %" PRId64 ", ignore the refresh request",
+ intervalInNanos);
+ return;
+ }
+
+ ActionForInterval actionForInterval = mActionByIntervalInNanos[intervalInNanos];
+
+ // Make a copy so that we don't hold the lock while trying to refresh the timestamp.
+ // Refreshing the timestamp will inovke onValueChangeCallback which also requires lock, so
+ // we must not hold lock.
+ for (const PropIdAreaId& propIdAreaId : actionForInterval.propIdAreaIdsToRefresh) {
+ const RefreshInfo& refreshInfo = mRefreshInfoByPropIdAreaId[propIdAreaId];
+ eventModeByPropIdAreaId[propIdAreaId] = refreshInfo.eventMode;
+ }
+ }
+
+ mServerSidePropStore->refreshTimestamps(eventModeByPropIdAreaId);
+}
+
+void FakeVehicleHardware::registerRefreshLocked(PropIdAreaId propIdAreaId,
+ VehiclePropertyStore::EventMode eventMode,
+ float sampleRateHz) {
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) != mRefreshInfoByPropIdAreaId.end()) {
+ unregisterRefreshLocked(propIdAreaId);
+ }
+
+ int64_t intervalInNanos = static_cast<int64_t>(1'000'000'000. / sampleRateHz);
+ RefreshInfo refreshInfo = {
+ .eventMode = eventMode,
+ .intervalInNanos = intervalInNanos,
+ };
+ mRefreshInfoByPropIdAreaId[propIdAreaId] = refreshInfo;
+
+ if (mActionByIntervalInNanos.find(intervalInNanos) != mActionByIntervalInNanos.end()) {
+ // If we have already registered for this interval, then add the action info to the
+ // actions list.
+ mActionByIntervalInNanos[intervalInNanos].propIdAreaIdsToRefresh.insert(propIdAreaId);
+ return;
+ }
+
+ // This is the first action for the interval, register a timer callback for that interval.
+ auto action = std::make_shared<RecurrentTimer::Callback>(
+ [this, intervalInNanos] { refreshTimeStampForInterval(intervalInNanos); });
+ mActionByIntervalInNanos[intervalInNanos] = ActionForInterval{
+ .propIdAreaIdsToRefresh = {propIdAreaId},
+ .recurrentAction = action,
+ };
+ mRecurrentTimer->registerTimerCallback(intervalInNanos, action);
+}
+
+void FakeVehicleHardware::unregisterRefreshLocked(PropIdAreaId propIdAreaId) {
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) == mRefreshInfoByPropIdAreaId.end()) {
+ ALOGW("PropId: %" PRId32 ", areaId: %" PRId32 " was not registered for refresh, ignore",
+ propIdAreaId.propId, propIdAreaId.areaId);
+ return;
+ }
+
+ int64_t intervalInNanos = mRefreshInfoByPropIdAreaId[propIdAreaId].intervalInNanos;
+ auto& actionForInterval = mActionByIntervalInNanos[intervalInNanos];
+ actionForInterval.propIdAreaIdsToRefresh.erase(propIdAreaId);
+ if (actionForInterval.propIdAreaIdsToRefresh.empty()) {
+ mRecurrentTimer->unregisterTimerCallback(actionForInterval.recurrentAction);
+ mActionByIntervalInNanos.erase(intervalInNanos);
+ }
+ mRefreshInfoByPropIdAreaId.erase(propIdAreaId);
+}
+
StatusCode FakeVehicleHardware::subscribePropIdAreaIdLocked(
int32_t propId, int32_t areaId, float sampleRateHz, bool enableVariableUpdateRate,
const VehiclePropConfig& vehiclePropConfig) {
@@ -2066,11 +2182,6 @@
ALOGE("Must not use sample rate 0 for a continuous property");
return StatusCode::INTERNAL_ERROR;
}
- if (mRecurrentActions.find(propIdAreaId) != mRecurrentActions.end()) {
- mRecurrentTimer->unregisterTimerCallback(mRecurrentActions[propIdAreaId]);
- }
- int64_t intervalInNanos = static_cast<int64_t>(1'000'000'000. / sampleRateHz);
-
// For continuous properties, we must generate a new onPropertyChange event
// periodically according to the sample rate.
auto eventMode = VehiclePropertyStore::EventMode::ALWAYS;
@@ -2078,12 +2189,8 @@
enableVariableUpdateRate) {
eventMode = VehiclePropertyStore::EventMode::ON_VALUE_CHANGE;
}
- auto action =
- std::make_shared<RecurrentTimer::Callback>([this, propId, areaId, eventMode] {
- mServerSidePropStore->refreshTimestamp(propId, areaId, eventMode);
- });
- mRecurrentTimer->registerTimerCallback(intervalInNanos, action);
- mRecurrentActions[propIdAreaId] = action;
+
+ registerRefreshLocked(propIdAreaId, eventMode, sampleRateHz);
return StatusCode::OK;
}
}
@@ -2094,39 +2201,47 @@
.propId = propId,
.areaId = areaId,
};
- if (mRecurrentActions.find(propIdAreaId) != mRecurrentActions.end()) {
- mRecurrentTimer->unregisterTimerCallback(mRecurrentActions[propIdAreaId]);
- mRecurrentActions.erase(propIdAreaId);
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) != mRefreshInfoByPropIdAreaId.end()) {
+ unregisterRefreshLocked(propIdAreaId);
}
mSubOnChangePropIdAreaIds.erase(propIdAreaId);
return StatusCode::OK;
}
void FakeVehicleHardware::onValueChangeCallback(const VehiclePropValue& value) {
- if (mOnPropertyChangeCallback == nullptr) {
- return;
- }
+ ATRACE_CALL();
+ onValuesChangeCallback({value});
+}
- PropIdAreaId propIdAreaId{
- .propId = value.prop,
- .areaId = value.areaId,
- };
+void FakeVehicleHardware::onValuesChangeCallback(std::vector<VehiclePropValue> values) {
+ ATRACE_CALL();
+ std::vector<VehiclePropValue> subscribedUpdatedValues;
{
std::scoped_lock<std::mutex> lockGuard(mLock);
- if (mRecurrentActions.find(propIdAreaId) == mRecurrentActions.end() &&
- mSubOnChangePropIdAreaIds.find(propIdAreaId) == mSubOnChangePropIdAreaIds.end()) {
- if (FAKE_VEHICLEHARDWARE_DEBUG) {
- ALOGD("The updated property value: %s is not subscribed, ignore",
- value.toString().c_str());
- }
+ if (mOnPropertyChangeCallback == nullptr) {
return;
}
+
+ for (const auto& value : values) {
+ PropIdAreaId propIdAreaId{
+ .propId = value.prop,
+ .areaId = value.areaId,
+ };
+ if (mRefreshInfoByPropIdAreaId.find(propIdAreaId) == mRefreshInfoByPropIdAreaId.end() &&
+ mSubOnChangePropIdAreaIds.find(propIdAreaId) == mSubOnChangePropIdAreaIds.end()) {
+ if (FAKE_VEHICLEHARDWARE_DEBUG) {
+ ALOGD("The updated property value: %s is not subscribed, ignore",
+ value.toString().c_str());
+ }
+ continue;
+ }
+
+ subscribedUpdatedValues.push_back(value);
+ }
}
- std::vector<VehiclePropValue> updatedValues;
- updatedValues.push_back(value);
- (*mOnPropertyChangeCallback)(std::move(updatedValues));
+ (*mOnPropertyChangeCallback)(std::move(subscribedUpdatedValues));
}
void FakeVehicleHardware::loadPropConfigsFromDir(
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 3b6f717..e1506c7 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -1593,6 +1593,61 @@
},
},
SetSpecialValueTestCase{
+ .name = "set_low_speed_collision_warning_enabled_false",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {0},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {0},
+ },
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_STATE),
+ .value.int32Values = {toInt(
+ ErrorState::NOT_AVAILABLE_DISABLED)},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
+ .name = "set_low_speed_collision_warning_enabled_true",
+ .valuesToSet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {1},
+ },
+ },
+ .expectedValuesToGet =
+ {
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_ENABLED),
+ .value.int32Values = {1},
+ },
+ VehiclePropValue{
+ .prop = toInt(
+ VehicleProperty::
+ LOW_SPEED_COLLISION_WARNING_STATE),
+ .value.int32Values = {1},
+ },
+ },
+ },
+ SetSpecialValueTestCase{
.name = "set_shutdown_request",
.valuesToSet =
{
@@ -2149,6 +2204,13 @@
toInt(VehicleProperty::HANDS_ON_DETECTION_WARNING),
},
},
+ // LSCW
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED),
+ {
+ toInt(VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE),
+ },
+ },
};
// First subscribe to all the properties that we will change.
diff --git a/automotive/vehicle/aidl/impl/grpc/OWNERS b/automotive/vehicle/aidl/impl/grpc/OWNERS
deleted file mode 100644
index 7a96f23..0000000
--- a/automotive/vehicle/aidl/impl/grpc/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-shanyu@google.com
-chenhaosjtuacm@google.com
-egranata@google.com
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
index 491aa10..1ea0df4 100644
--- a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
+++ b/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
@@ -67,6 +67,7 @@
for (auto& areaConfig : in.areaConfigs) {
auto* protoACfg = out->add_area_configs();
protoACfg->set_area_id(areaConfig.areaId);
+ protoACfg->set_access(static_cast<proto::VehiclePropertyAccess>(toInt(areaConfig.access)));
protoACfg->set_min_int64_value(areaConfig.minInt64Value);
protoACfg->set_max_int64_value(areaConfig.maxInt64Value);
protoACfg->set_min_float_value(areaConfig.minFloatValue);
@@ -95,6 +96,7 @@
auto cast_to_acfg = [](const proto::VehicleAreaConfig& protoAcfg) {
auto vehicleAreaConfig = aidl_vehicle::VehicleAreaConfig{
.areaId = protoAcfg.area_id(),
+ .access = static_cast<aidl_vehicle::VehiclePropertyAccess>(protoAcfg.access()),
.minInt32Value = protoAcfg.min_int32_value(),
.maxInt32Value = protoAcfg.max_int32_value(),
.minInt64Value = protoAcfg.min_int64_value(),
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
index 8093658..7ea8540 100644
--- a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
+++ b/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
@@ -18,6 +18,8 @@
package android.hardware.automotive.vehicle.proto;
+import "android/hardware/automotive/vehicle/VehiclePropertyAccess.proto";
+
/* Must be in sync with VehicleAreaConfig.aidl. */
message VehicleAreaConfig {
/* Area id is ignored for VehiclePropertyGroup:GLOBAL properties. */
@@ -43,6 +45,6 @@
* assumed all @data_enum values are supported unless specified through another mechanism.
*/
repeated int64 supported_enum_values = 8;
- int32 access = 9;
+ VehiclePropertyAccess access = 9;
bool support_variable_update_rate = 10;
};
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
index cd2b727..712359a 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
@@ -19,6 +19,8 @@
#include <android-base/thread_annotations.h>
+#include <utils/Looper.h>
+#include <atomic>
#include <memory>
#include <mutex>
#include <queue>
@@ -31,6 +33,9 @@
namespace automotive {
namespace vehicle {
+// Forward declaration
+class RecurrentMessageHandler;
+
// A thread-safe recurrent timer.
class RecurrentTimer final {
public:
@@ -43,49 +48,44 @@
// Registers a recurrent callback for a given interval.
// Registering the same callback twice will override the interval provided before.
- void registerTimerCallback(int64_t intervalInNano, std::shared_ptr<Callback> callback);
+ void registerTimerCallback(int64_t intervalInNanos, std::shared_ptr<Callback> callback);
// Unregisters a previously registered recurrent callback.
void unregisterTimerCallback(std::shared_ptr<Callback> callback);
private:
- // friend class for unit testing.
+ friend class RecurrentMessageHandler;
+
+ // For unit test
friend class RecurrentTimerTest;
struct CallbackInfo {
std::shared_ptr<Callback> callback;
- int64_t interval;
- int64_t nextTime;
- // A flag to indicate whether this CallbackInfo is already outdated and should be ignored.
- // The reason we need this flag is because we cannot easily remove an element from a heap.
- bool outdated = false;
-
- static bool cmp(const std::unique_ptr<CallbackInfo>& lhs,
- const std::unique_ptr<CallbackInfo>& rhs);
+ int64_t intervalInNanos;
+ int64_t nextTimeInNanos;
};
+ android::sp<Looper> mLooper;
+ android::sp<RecurrentMessageHandler> mHandler;
+
+ std::atomic<bool> mStopRequested = false;
+ std::atomic<int> mCallbackId = 0;
std::mutex mLock;
std::thread mThread;
- std::condition_variable mCond;
- bool mStopRequested GUARDED_BY(mLock) = false;
- // A map to map each callback to its current active CallbackInfo in the mCallbackQueue.
- std::unordered_map<std::shared_ptr<Callback>, CallbackInfo*> mCallbacks GUARDED_BY(mLock);
- // A min-heap sorted by nextTime. Note that because we cannot remove arbitrary element from the
- // heap, a single Callback can have multiple entries in this queue, all but one should be valid.
- // The rest should be mark as outdated. The valid one is one stored in mCallbacks.
- std::vector<std::unique_ptr<CallbackInfo>> mCallbackQueue GUARDED_BY(mLock);
+ std::unordered_map<std::shared_ptr<Callback>, int> mIdByCallback GUARDED_BY(mLock);
+ std::unordered_map<int, std::unique_ptr<CallbackInfo>> mCallbackInfoById GUARDED_BY(mLock);
- void loop();
+ void handleMessage(const android::Message& message) EXCLUDES(mLock);
+ int getCallbackIdLocked(std::shared_ptr<Callback> callback) REQUIRES(mLock);
+};
- // Mark the callbackInfo as outdated and should be ignored when popped from the heap.
- void markOutdatedLocked(CallbackInfo* callback) REQUIRES(mLock);
- // Remove all outdated callbackInfos from the top of the heap. This function must be called
- // each time we might introduce outdated elements to the top. We must make sure the heap is
- // always valid from the top.
- void removeInvalidCallbackLocked() REQUIRES(mLock);
- // Gets the next calblack to run (must be valid) from the heap, update its nextTime and put
- // it back to the heap.
- std::shared_ptr<Callback> getNextCallbackLocked(int64_t now) REQUIRES(mLock);
+class RecurrentMessageHandler final : public android::MessageHandler {
+ public:
+ RecurrentMessageHandler(RecurrentTimer* timer) { mTimer = timer; }
+ void handleMessage(const android::Message& message) override;
+
+ private:
+ RecurrentTimer* mTimer;
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index e6d657d..1e83c8a 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -24,6 +24,10 @@
#include <aidl/android/hardware/automotive/vehicle/CruiseControlType.h>
#include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
#include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.h>
#include <aidl/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/ErrorState.h>
#include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
@@ -38,11 +42,13 @@
#include <aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.h>
#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.h>
#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/ImpactSensorLocation.h>
#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.h>
#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/LaneDepartureWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/LaneKeepAssistState.h>
#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
+#include <aidl/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
#include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
@@ -55,6 +61,7 @@
#include <aidl/android/hardware/automotive/vehicle/SetValueResults.h>
#include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
#include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAirbagLocation.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>
@@ -63,6 +70,7 @@
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAutonomousState.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleGear.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.h>
#include <aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index ef36532..d9599ed 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -48,21 +48,21 @@
enum class EventMode : uint8_t {
/**
- * Only invoke OnValueChangeCallback if the new property value (ignoring timestamp) is
- * different than the existing value.
+ * Only invoke OnValueChangeCallback or OnValuesChangeCallback if the new property value
+ * (ignoring timestamp) is different than the existing value.
*
* This should be used for regular cases.
*/
ON_VALUE_CHANGE,
/**
- * Always invoke OnValueChangeCallback.
+ * Always invoke OnValueChangeCallback or OnValuesChangeCallback.
*
* This should be used for the special properties that are used for delivering event, e.g.
* HW_KEY_INPUT.
*/
ALWAYS,
/**
- * Never invoke OnValueChangeCallback.
+ * Never invoke OnValueChangeCallback or OnValuesChangeCalblack.
*
* This should be used for continuous property subscription when the sample rate for the
* subscription is smaller than the refresh rate for the property. E.g., the vehicle speed
@@ -82,6 +82,10 @@
using OnValueChangeCallback = std::function<void(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue&)>;
+ // Callback when one or more property values have been updated or new values added.
+ using OnValuesChangeCallback = std::function<void(
+ std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>)>;
+
// Function that used to calculate unique token for given VehiclePropValue.
using TokenFunction = std::function<int64_t(
const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value)>;
@@ -99,7 +103,8 @@
// 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
// override an existing value, the status for the existing value would be used for the
// overridden value.
- // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
+ // 'EventMode' controls whether the 'OnValueChangeCallback' or 'OnValuesChangeCallback' will be
+ // called for this operation.
// If 'useCurrentTimestamp' is true, the property value will be set to the current timestamp.
VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
bool updateStatus = false,
@@ -111,6 +116,11 @@
// without generating event. This operation is atomic with other writeValue operations.
void refreshTimestamp(int32_t propId, int32_t areaId, EventMode eventMode) EXCLUDES(mLock);
+ // Refresh the timestamp for multiple [propId, areaId]s.
+ void refreshTimestamps(
+ std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId)
+ EXCLUDES(mLock);
+
// Remove a given property value from the property store. The 'propValue' would be used to
// generate the key for the value to remove.
void removeValue(
@@ -143,14 +153,27 @@
std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropConfig> getAllConfigs()
const EXCLUDES(mLock);
- // Get the property config for the requested property.
+ // Deprecated, use getPropConfig instead. This is unsafe to use if registerProperty overwrites
+ // an existing config.
android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*,
VhalError>
getConfig(int32_t propId) const EXCLUDES(mLock);
+ // Get the property config for the requested property.
+ android::base::Result<aidl::android::hardware::automotive::vehicle::VehiclePropConfig,
+ VhalError>
+ getPropConfig(int32_t propId) const EXCLUDES(mLock);
+
// Set a callback that would be called when a property value has been updated.
void setOnValueChangeCallback(const OnValueChangeCallback& callback) EXCLUDES(mLock);
+ // Set a callback that would be called when one or more property values have been updated.
+ // For backward compatibility, this is optional. If this is not set, then multiple property
+ // updates will be delivered through multiple OnValueChangeCallback instead.
+ // It is recommended to set this and batch the property update events for better performance.
+ // If this is set, then OnValueChangeCallback will not be used.
+ void setOnValuesChangeCallback(const OnValuesChangeCallback& callback) EXCLUDES(mLock);
+
inline std::shared_ptr<VehiclePropValuePool> getValuePool() { return mValuePool; }
private:
@@ -178,6 +201,7 @@
mutable std::mutex mLock;
std::unordered_map<int32_t, Record> mRecordsByPropId GUARDED_BY(mLock);
OnValueChangeCallback mOnValueChangeCallback GUARDED_BY(mLock);
+ OnValuesChangeCallback mOnValuesChangeCallback GUARDED_BY(mLock);
const Record* getRecordLocked(int32_t propId) const;
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index c6d3687..8dec695 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -17,6 +17,7 @@
#include "RecurrentTimer.h"
#include <utils/Log.h>
+#include <utils/Looper.h>
#include <utils/SystemClock.h>
#include <inttypes.h>
@@ -27,153 +28,119 @@
namespace automotive {
namespace vehicle {
+namespace {
+
using ::android::base::ScopedLockAssertion;
+constexpr int INVALID_ID = -1;
+
+} // namespace
+
RecurrentTimer::RecurrentTimer() {
- mThread = std::thread(&RecurrentTimer::loop, this);
+ mHandler = sp<RecurrentMessageHandler>::make(this);
+ mLooper = sp<Looper>::make(/*allowNonCallbacks=*/false);
+ mThread = std::thread([this] {
+ Looper::setForThread(mLooper);
+
+ while (!mStopRequested) {
+ mLooper->pollOnce(/*timeoutMillis=*/-1);
+ }
+ });
}
RecurrentTimer::~RecurrentTimer() {
- {
- std::scoped_lock<std::mutex> lockGuard(mLock);
- mStopRequested = true;
- }
- mCond.notify_one();
+ mStopRequested = true;
+ mLooper->removeMessages(mHandler);
+ mLooper->wake();
if (mThread.joinable()) {
mThread.join();
}
}
-void RecurrentTimer::registerTimerCallback(int64_t intervalInNano,
+int RecurrentTimer::getCallbackIdLocked(std::shared_ptr<RecurrentTimer::Callback> callback) {
+ const auto& it = mIdByCallback.find(callback);
+ if (it != mIdByCallback.end()) {
+ return it->second;
+ }
+ return INVALID_ID;
+}
+
+void RecurrentTimer::registerTimerCallback(int64_t intervalInNanos,
std::shared_ptr<RecurrentTimer::Callback> callback) {
{
std::scoped_lock<std::mutex> lockGuard(mLock);
+ int callbackId = getCallbackIdLocked(callback);
+
+ if (callbackId == INVALID_ID) {
+ callbackId = mCallbackId++;
+ mIdByCallback.insert({callback, callbackId});
+ } else {
+ ALOGI("Replacing an existing timer callback with a new interval, current: %" PRId64
+ " ns, new: %" PRId64 " ns",
+ mCallbackInfoById[callbackId]->intervalInNanos, intervalInNanos);
+ mLooper->removeMessages(mHandler, callbackId);
+ }
+
// Aligns the nextTime to multiply of interval.
- int64_t nextTime = ceil(uptimeNanos() / intervalInNano) * intervalInNano;
+ int64_t nextTimeInNanos = ceil(uptimeNanos() / intervalInNanos) * intervalInNanos;
std::unique_ptr<CallbackInfo> info = std::make_unique<CallbackInfo>();
info->callback = callback;
- info->interval = intervalInNano;
- info->nextTime = nextTime;
+ info->intervalInNanos = intervalInNanos;
+ info->nextTimeInNanos = nextTimeInNanos;
+ mCallbackInfoById.insert({callbackId, std::move(info)});
- auto it = mCallbacks.find(callback);
- if (it != mCallbacks.end()) {
- ALOGI("Replacing an existing timer callback with a new interval, current: %" PRId64
- " ns, new: %" PRId64 " ns",
- it->second->interval, intervalInNano);
- markOutdatedLocked(it->second);
- }
- mCallbacks[callback] = info.get();
- mCallbackQueue.push_back(std::move(info));
- // Insert the last element into the heap.
- std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+ mLooper->sendMessageAtTime(nextTimeInNanos, mHandler, Message(callbackId));
}
- mCond.notify_one();
}
void RecurrentTimer::unregisterTimerCallback(std::shared_ptr<RecurrentTimer::Callback> callback) {
{
std::scoped_lock<std::mutex> lockGuard(mLock);
- auto it = mCallbacks.find(callback);
- if (it == mCallbacks.end()) {
+ int callbackId = getCallbackIdLocked(callback);
+
+ if (callbackId == INVALID_ID) {
ALOGE("No event found to unregister");
return;
}
- markOutdatedLocked(it->second);
- mCallbacks.erase(it);
- }
-
- mCond.notify_one();
-}
-
-void RecurrentTimer::markOutdatedLocked(RecurrentTimer::CallbackInfo* info) {
- info->outdated = true;
- info->callback = nullptr;
- // Make sure the first element is always valid.
- removeInvalidCallbackLocked();
-}
-
-void RecurrentTimer::removeInvalidCallbackLocked() {
- while (mCallbackQueue.size() != 0 && mCallbackQueue[0]->outdated) {
- std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
- mCallbackQueue.pop_back();
+ mLooper->removeMessages(mHandler, callbackId);
+ mCallbackInfoById.erase(callbackId);
+ mIdByCallback.erase(callback);
}
}
-std::shared_ptr<RecurrentTimer::Callback> RecurrentTimer::getNextCallbackLocked(int64_t now) {
- std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
- auto& callbackInfo = mCallbackQueue[mCallbackQueue.size() - 1];
- auto nextCallback = callbackInfo->callback;
- // intervalCount is the number of interval we have to advance until we pass now.
- size_t intervalCount = (now - callbackInfo->nextTime) / callbackInfo->interval + 1;
- callbackInfo->nextTime += intervalCount * callbackInfo->interval;
- std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+void RecurrentTimer::handleMessage(const Message& message) {
+ std::shared_ptr<RecurrentTimer::Callback> callback;
+ {
+ std::scoped_lock<std::mutex> lockGuard(mLock);
- // Make sure the first element is always valid.
- removeInvalidCallbackLocked();
+ int callbackId = message.what;
- return nextCallback;
-}
-
-void RecurrentTimer::loop() {
- std::vector<std::shared_ptr<Callback>> callbacksToRun;
- while (true) {
- {
- std::unique_lock<std::mutex> uniqueLock(mLock);
- ScopedLockAssertion lockAssertion(mLock);
- // Wait until the timer exits or we have at least one recurrent callback.
- mCond.wait(uniqueLock, [this] {
- ScopedLockAssertion lockAssertion(mLock);
- return mStopRequested || mCallbackQueue.size() != 0;
- });
-
- int64_t interval;
- if (mStopRequested) {
- return;
- }
- // The first element is the nearest next event.
- int64_t nextTime = mCallbackQueue[0]->nextTime;
- int64_t now = uptimeNanos();
-
- if (nextTime > now) {
- interval = nextTime - now;
- } else {
- interval = 0;
- }
-
- // Wait for the next event or the timer exits.
- if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
- ScopedLockAssertion lockAssertion(mLock);
- return mStopRequested;
- })) {
- return;
- }
-
- now = uptimeNanos();
- callbacksToRun.clear();
- while (mCallbackQueue.size() > 0) {
- int64_t nextTime = mCallbackQueue[0]->nextTime;
- if (nextTime > now) {
- break;
- }
-
- callbacksToRun.push_back(getNextCallbackLocked(now));
- }
+ auto it = mCallbackInfoById.find(callbackId);
+ if (it == mCallbackInfoById.end()) {
+ ALOGW("The event for callback ID: %d is outdated, ignore", callbackId);
+ return;
}
- // Do not execute the callback while holding the lock.
- for (size_t i = 0; i < callbacksToRun.size(); i++) {
- (*callbacksToRun[i])();
- }
+ CallbackInfo* callbackInfo = it->second.get();
+ callback = callbackInfo->callback;
+ int64_t nowNanos = uptimeNanos();
+ // intervalCount is the number of interval we have to advance until we pass now.
+ size_t intervalCount =
+ (nowNanos - callbackInfo->nextTimeInNanos) / callbackInfo->intervalInNanos + 1;
+ callbackInfo->nextTimeInNanos += intervalCount * callbackInfo->intervalInNanos;
+
+ mLooper->sendMessageAtTime(callbackInfo->nextTimeInNanos, mHandler, Message(callbackId));
}
+
+ (*callback)();
}
-bool RecurrentTimer::CallbackInfo::cmp(const std::unique_ptr<RecurrentTimer::CallbackInfo>& lhs,
- const std::unique_ptr<RecurrentTimer::CallbackInfo>& rhs) {
- return lhs->nextTime > rhs->nextTime;
+void RecurrentMessageHandler::handleMessage(const Message& message) {
+ mTimer->handleMessage(message);
}
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index 7d9d8b7..6a2a695 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -113,6 +113,9 @@
bool valueUpdated = true;
VehiclePropValue updatedValue;
OnValueChangeCallback onValueChangeCallback = nullptr;
+ OnValuesChangeCallback onValuesChangeCallback = nullptr;
+ int32_t propId;
+ int32_t areaId;
{
std::scoped_lock<std::mutex> g(mLock);
@@ -122,7 +125,8 @@
propValue->timestamp = elapsedRealtimeNano();
}
- int32_t propId = propValue->prop;
+ propId = propValue->prop;
+ areaId = propValue->areaId;
VehiclePropertyStore::Record* record = getRecordLocked(propId);
if (record == nullptr) {
@@ -163,52 +167,96 @@
return {};
}
updatedValue = *(record->values[recId]);
- if (mOnValueChangeCallback == nullptr) {
- return {};
- }
+
+ onValuesChangeCallback = mOnValuesChangeCallback;
onValueChangeCallback = mOnValueChangeCallback;
}
+ if (onValuesChangeCallback == nullptr && onValueChangeCallback == nullptr) {
+ ALOGW("No callback registered, ignoring property update for propId: %" PRId32
+ ", area ID: %" PRId32,
+ propId, areaId);
+ return {};
+ }
+
// Invoke the callback outside the lock to prevent dead-lock.
if (eventMode == EventMode::ALWAYS || valueUpdated) {
- onValueChangeCallback(updatedValue);
+ if (onValuesChangeCallback != nullptr) {
+ onValuesChangeCallback({updatedValue});
+ } else {
+ onValueChangeCallback(updatedValue);
+ }
}
return {};
}
void VehiclePropertyStore::refreshTimestamp(int32_t propId, int32_t areaId, EventMode eventMode) {
- VehiclePropValue updatedValue;
+ std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId;
+ PropIdAreaId propIdAreaId = {
+ .propId = propId,
+ .areaId = areaId,
+ };
+ eventModeByPropIdAreaId[propIdAreaId] = eventMode;
+ refreshTimestamps(eventModeByPropIdAreaId);
+}
+
+void VehiclePropertyStore::refreshTimestamps(
+ std::unordered_map<PropIdAreaId, EventMode, PropIdAreaIdHash> eventModeByPropIdAreaId) {
+ std::vector<VehiclePropValue> updatedValues;
+ OnValuesChangeCallback onValuesChangeCallback = nullptr;
OnValueChangeCallback onValueChangeCallback = nullptr;
{
std::scoped_lock<std::mutex> g(mLock);
- VehiclePropertyStore::Record* record = getRecordLocked(propId);
- if (record == nullptr) {
- return;
- }
-
- VehiclePropValue propValue = {
- .areaId = areaId,
- .prop = propId,
- .value = {},
- };
-
- VehiclePropertyStore::RecordId recId = getRecordIdLocked(propValue, *record);
- if (auto it = record->values.find(recId); it != record->values.end()) {
- it->second->timestamp = elapsedRealtimeNano();
- updatedValue = *(it->second);
- } else {
- return;
- }
- if (!mOnValueChangeCallback) {
- return;
- }
+ onValuesChangeCallback = mOnValuesChangeCallback;
onValueChangeCallback = mOnValueChangeCallback;
+
+ for (const auto& [propIdAreaId, eventMode] : eventModeByPropIdAreaId) {
+ int32_t propId = propIdAreaId.propId;
+ int32_t areaId = propIdAreaId.areaId;
+ VehiclePropertyStore::Record* record = getRecordLocked(propId);
+ if (record == nullptr) {
+ continue;
+ }
+
+ VehiclePropValue propValue = {
+ .areaId = areaId,
+ .prop = propId,
+ .value = {},
+ };
+
+ VehiclePropertyStore::RecordId recId = getRecordIdLocked(propValue, *record);
+ if (auto it = record->values.find(recId); it != record->values.end()) {
+ it->second->timestamp = elapsedRealtimeNano();
+ if (eventMode == EventMode::ALWAYS) {
+ updatedValues.push_back(*(it->second));
+ }
+ } else {
+ continue;
+ }
+ }
}
// Invoke the callback outside the lock to prevent dead-lock.
- if (eventMode == EventMode::ALWAYS) {
- onValueChangeCallback(updatedValue);
+ if (updatedValues.empty()) {
+ return;
+ }
+ if (!onValuesChangeCallback && !onValueChangeCallback) {
+ // If no callback is set, then we don't have to do anything.
+ for (const auto& updateValue : updatedValues) {
+ ALOGW("No callback registered, ignoring property update for propId: %" PRId32
+ ", area ID: %" PRId32,
+ updateValue.prop, updateValue.areaId);
+ }
+ return;
+ }
+ if (onValuesChangeCallback != nullptr) {
+ onValuesChangeCallback(updatedValues);
+ } else {
+ // Fallback to use multiple onValueChangeCallback
+ for (const auto& updateValue : updatedValues) {
+ onValueChangeCallback(updateValue);
+ }
}
}
@@ -318,6 +366,17 @@
return &record->propConfig;
}
+VhalResult<VehiclePropConfig> VehiclePropertyStore::getPropConfig(int32_t propId) const {
+ std::scoped_lock<std::mutex> g(mLock);
+
+ const VehiclePropertyStore::Record* record = getRecordLocked(propId);
+ if (record == nullptr) {
+ return StatusError(StatusCode::INVALID_ARG) << "property: " << propId << " not registered";
+ }
+
+ return record->propConfig;
+}
+
void VehiclePropertyStore::setOnValueChangeCallback(
const VehiclePropertyStore::OnValueChangeCallback& callback) {
std::scoped_lock<std::mutex> g(mLock);
@@ -325,6 +384,13 @@
mOnValueChangeCallback = callback;
}
+void VehiclePropertyStore::setOnValuesChangeCallback(
+ const VehiclePropertyStore::OnValuesChangeCallback& callback) {
+ std::scoped_lock<std::mutex> g(mLock);
+
+ mOnValuesChangeCallback = callback;
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
index 62046f3..e8ac2a5 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
@@ -60,9 +60,14 @@
mCallbacks.clear();
}
- size_t countTimerCallbackQueue(RecurrentTimer* timer) {
+ size_t countCallbackInfoById(RecurrentTimer* timer) {
std::scoped_lock<std::mutex> lockGuard(timer->mLock);
- return timer->mCallbackQueue.size();
+ return timer->mCallbackInfoById.size();
+ }
+
+ size_t countIdByCallback(RecurrentTimer* timer) {
+ std::scoped_lock<std::mutex> lockGuard(timer->mLock);
+ return timer->mIdByCallback.size();
}
private:
@@ -109,6 +114,9 @@
<< "Not enough callbacks called before timeout";
timer.unregisterTimerCallback(action);
+
+ ASSERT_EQ(countCallbackInfoById(&timer), 0u);
+ ASSERT_EQ(countIdByCallback(&timer), 0u);
}
TEST_F(RecurrentTimerTest, testDestroyTimerWithCallback) {
@@ -198,8 +206,8 @@
timer.unregisterTimerCallback(action);
- // Make sure there is no item in the callback queue.
- ASSERT_EQ(countTimerCallbackQueue(&timer), static_cast<size_t>(0));
+ ASSERT_EQ(countCallbackInfoById(&timer), 0u);
+ ASSERT_EQ(countIdByCallback(&timer), 0u);
}
TEST_F(RecurrentTimerTest, testRegisterCallbackMultipleTimesNoDeadLock) {
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 625652e..6646b7e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -20,6 +20,7 @@
#include <VehicleUtils.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <utils/SystemClock.h>
namespace android {
namespace hardware {
@@ -101,16 +102,16 @@
ASSERT_EQ(configs.size(), static_cast<size_t>(2));
}
-TEST_F(VehiclePropertyStoreTest, testGetConfig) {
- VhalResult<const VehiclePropConfig*> result =
- mStore->getConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
+TEST_F(VehiclePropertyStoreTest, testGetPropConfig) {
+ VhalResult<VehiclePropConfig> result =
+ mStore->getPropConfig(toInt(VehicleProperty::INFO_FUEL_CAPACITY));
ASSERT_RESULT_OK(result);
- ASSERT_EQ(*(result.value()), mConfigFuelCapacity);
+ ASSERT_EQ(result.value(), mConfigFuelCapacity);
}
-TEST_F(VehiclePropertyStoreTest, testGetConfigWithInvalidPropId) {
- VhalResult<const VehiclePropConfig*> result = mStore->getConfig(INVALID_PROP_ID);
+TEST_F(VehiclePropertyStoreTest, testGetPropConfigWithInvalidPropId) {
+ VhalResult<VehiclePropConfig> result = mStore->getPropConfig(INVALID_PROP_ID);
EXPECT_FALSE(result.ok()) << "expect error when getting a config for an invalid property ID";
EXPECT_EQ(result.error().code(), StatusCode::INVALID_ARG);
@@ -527,6 +528,133 @@
ASSERT_EQ(configs.size(), static_cast<size_t>(2));
}
+TEST_F(VehiclePropertyStoreTest, testOnValuesChangeCallback) {
+ std::vector<VehiclePropValue> updatedValues;
+ VehiclePropValue fuelCapacity = {
+ .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ fuelCapacity.value.floatValues[0] = 2.0;
+ fuelCapacity.timestamp = 1;
+
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ ASSERT_THAT(updatedValues, ElementsAre(fuelCapacity));
+}
+
+TEST_F(VehiclePropertyStoreTest, testRefreshTimestamp) {
+ std::vector<VehiclePropValue> updatedValues;
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ int64_t now = elapsedRealtimeNano();
+ int propId = toInt(VehicleProperty::TIRE_PRESSURE);
+ int areaId = WHEEL_FRONT_LEFT;
+ VehiclePropValue tirePressure = {
+ .prop = propId,
+ .areaId = areaId,
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(tirePressure)));
+ updatedValues.clear();
+
+ mStore->refreshTimestamp(propId, areaId, VehiclePropertyStore::EventMode::ALWAYS);
+
+ ASSERT_EQ(updatedValues.size(), 1u);
+ ASSERT_EQ(updatedValues[0].prop, propId);
+ ASSERT_EQ(updatedValues[0].areaId, areaId);
+ ASSERT_EQ(updatedValues[0].value.floatValues[0], 1.0);
+ int64_t timestamp = updatedValues[0].timestamp;
+ ASSERT_GE(timestamp, now);
+
+ auto result = mStore->readValue(tirePressure);
+
+ ASSERT_RESULT_OK(result);
+ ASSERT_EQ((result.value())->timestamp, timestamp);
+}
+
+TEST_F(VehiclePropertyStoreTest, testRefreshTimestamp_eventModeOnValueChange) {
+ std::vector<VehiclePropValue> updatedValues;
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ int64_t now = elapsedRealtimeNano();
+ int propId = toInt(VehicleProperty::TIRE_PRESSURE);
+ int areaId = WHEEL_FRONT_LEFT;
+ VehiclePropValue tirePressure = {
+ .prop = propId,
+ .areaId = areaId,
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(tirePressure)));
+ updatedValues.clear();
+
+ mStore->refreshTimestamp(propId, areaId, VehiclePropertyStore::EventMode::ON_VALUE_CHANGE);
+
+ ASSERT_EQ(updatedValues.size(), 0u)
+ << "Must generate no property update events if only the timestamp is refreshed";
+
+ auto result = mStore->readValue(tirePressure);
+
+ ASSERT_RESULT_OK(result);
+ ASSERT_GE((result.value())->timestamp, now)
+ << "Even though event mode is on value change, the store timestamp must be updated";
+}
+
+TEST_F(VehiclePropertyStoreTest, testRefreshTimestamps) {
+ std::vector<VehiclePropValue> updatedValues;
+ mStore->setOnValuesChangeCallback(
+ [&updatedValues](std::vector<VehiclePropValue> values) { updatedValues = values; });
+
+ int64_t now = elapsedRealtimeNano();
+ int propId1 = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
+ int areaId1 = 0;
+ VehiclePropValue fuelCapacity = {
+ .prop = propId1,
+ .areaId = areaId1,
+ .value = {.floatValues = {1.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+ int propId2 = toInt(VehicleProperty::TIRE_PRESSURE);
+ int areaId2 = WHEEL_FRONT_LEFT;
+ VehiclePropValue tirePressure = {
+ .prop = propId2,
+ .areaId = areaId2,
+ .value = {.floatValues = {2.0}},
+ };
+ ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(tirePressure)));
+ updatedValues.clear();
+
+ std::unordered_map<PropIdAreaId, VehiclePropertyStore::EventMode, PropIdAreaIdHash>
+ eventModeByPropIdAreaId;
+ eventModeByPropIdAreaId[PropIdAreaId{
+ .propId = propId1,
+ .areaId = areaId1,
+ }] = VehiclePropertyStore::EventMode::ALWAYS;
+ eventModeByPropIdAreaId[PropIdAreaId{
+ .propId = propId2,
+ .areaId = areaId2,
+ }] = VehiclePropertyStore::EventMode::ALWAYS;
+
+ mStore->refreshTimestamps(eventModeByPropIdAreaId);
+
+ ASSERT_EQ(updatedValues.size(), 2u);
+ ASSERT_EQ(updatedValues[0].prop, propId1);
+ ASSERT_EQ(updatedValues[0].areaId, areaId1);
+ ASSERT_EQ(updatedValues[0].value.floatValues[0], 1.0);
+ ASSERT_GE(updatedValues[0].timestamp, now);
+ ASSERT_EQ(updatedValues[1].prop, propId2);
+ ASSERT_EQ(updatedValues[1].areaId, areaId2);
+ ASSERT_EQ(updatedValues[1].value.floatValues[0], 2.0);
+ ASSERT_GE(updatedValues[1].timestamp, now);
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 847f3b8..76d2f31 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -194,6 +194,7 @@
void DefaultVehicleHal::onPropertyChangeEvent(
const std::weak_ptr<SubscriptionManager>& subscriptionManager,
std::vector<VehiclePropValue>&& updatedValues) {
+ ATRACE_CALL();
auto manager = subscriptionManager.lock();
if (manager == nullptr) {
ALOGW("the SubscriptionManager is destroyed, DefaultVehicleHal is ending");
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index 63964ef..a63cb84 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -59,6 +59,7 @@
using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
diff --git a/automotive/vehicle/aidl_property/OWNERS b/automotive/vehicle/aidl_property/OWNERS
deleted file mode 100644
index 73e45ca..0000000
--- a/automotive/vehicle/aidl_property/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-tylertrephan@google.com
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl
new file mode 100644
index 0000000..54c02d5
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDistractionState {
+ OTHER = 0,
+ NOT_DISTRACTED = 1,
+ DISTRACTED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
new file mode 100644
index 0000000..9236b1c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDistractionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
new file mode 100644
index 0000000..22a90f3
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDrowsinessAttentionState {
+ OTHER = 0,
+ KSS_RATING_1_EXTREMELY_ALERT = 1,
+ KSS_RATING_2_VERY_ALERT = 2,
+ KSS_RATING_3_ALERT = 3,
+ KSS_RATING_4_RATHER_ALERT = 4,
+ KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY = 5,
+ KSS_RATING_6_SOME_SLEEPINESS = 6,
+ KSS_RATING_7_SLEEPY_NO_EFFORT = 7,
+ KSS_RATING_8_SLEEPY_SOME_EFFORT = 8,
+ KSS_RATING_9_VERY_SLEEPY = 9,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
new file mode 100644
index 0000000..dbf2364
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum DriverDrowsinessAttentionWarning {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
new file mode 100644
index 0000000..6b75d8c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum ImpactSensorLocation {
+ OTHER = 0x01,
+ FRONT = 0x02,
+ FRONT_LEFT_DOOR_SIDE = 0x04,
+ FRONT_RIGHT_DOOR_SIDE = 0x08,
+ REAR_LEFT_DOOR_SIDE = 0x10,
+ REAR_RIGHT_DOOR_SIDE = 0x20,
+ REAR = 0x40,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
new file mode 100644
index 0000000..6f6338b
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum LowSpeedCollisionWarningState {
+ OTHER = 0,
+ NO_WARNING = 1,
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
new file mode 100644
index 0000000..9b966d7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAirbagLocation {
+ OTHER = 0x01,
+ FRONT = 0x02,
+ KNEE = 0x04,
+ LEFT_SIDE = 0x08,
+ RIGHT_SIDE = 0x10,
+ CURTAIN = 0x20,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
index db867f4..b63003a 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -40,5 +40,6 @@
SEAT = 0x05000000,
DOOR = 0x06000000,
WHEEL = 0x07000000,
+ VENDOR = 0x08000000,
MASK = 0x0f000000,
}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
new file mode 100644
index 0000000..e15e71e
--- /dev/null
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleAutonomousState {
+ LEVEL_0 = 0,
+ LEVEL_1 = 1,
+ LEVEL_2 = 2,
+ LEVEL_3 = 3,
+ LEVEL_4 = 4,
+ LEVEL_5 = 5,
+}
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 231186f..827aa3e 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -66,9 +66,11 @@
EV_CHARGE_PORT_CONNECTED = (((0x030B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310603 */,
EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = (((0x030C + 0x10000000) + 0x01000000) + 0x00600000) /* 291504908 */,
RANGE_REMAINING = (((0x0308 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504904 */,
+ EV_BATTERY_AVERAGE_TEMPERATURE = (((0x030E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504910 */,
TIRE_PRESSURE = (((0x0309 + 0x10000000) + 0x07000000) + 0x00600000) /* 392168201 */,
CRITICALLY_LOW_TIRE_PRESSURE = (((0x030A + 0x10000000) + 0x07000000) + 0x00600000) /* 392168202 */,
ENGINE_IDLE_AUTO_STOP_ENABLED = (((0x0320 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310624 */,
+ IMPACT_DETECTED = (((0x0330 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289407792 */,
GEAR_SELECTION = (((0x0400 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408000 */,
CURRENT_GEAR = (((0x0401 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408001 */,
PARKING_BRAKE_ON = (((0x0402 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310850 */,
@@ -81,6 +83,7 @@
ABS_ACTIVE = (((0x040A + 0x10000000) + 0x01000000) + 0x00200000) /* 287310858 */,
TRACTION_CONTROL_ACTIVE = (((0x040B + 0x10000000) + 0x01000000) + 0x00200000) /* 287310859 */,
EV_STOPPING_MODE = (((0x040D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408013 */,
+ ELECTRONIC_STABILITY_CONTROL_ENABLED = (((0x040E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310862 */,
HVAC_FAN_SPEED = (((0x0500 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517120 */,
HVAC_FAN_DIRECTION = (((0x0501 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517121 */,
HVAC_TEMPERATURE_CURRENT = (((0x0502 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614274 */,
@@ -118,6 +121,7 @@
AP_POWER_BOOTUP_REASON = (((0x0A02 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409538 */,
DISPLAY_BRIGHTNESS = (((0x0A03 + 0x10000000) + 0x01000000) + 0x00400000) /* 289409539 */,
PER_DISPLAY_BRIGHTNESS = (((0x0A04 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475076 */,
+ VALET_MODE_ENABLED = (((0x0A05 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287312389 */,
HW_KEY_INPUT = (((0x0A10 + 0x10000000) + 0x01000000) + 0x00410000) /* 289475088 */,
HW_KEY_INPUT_V2 = (((0x0A11 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004177 */,
HW_MOTION_INPUT = (((0x0A12 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 367004178 */,
@@ -167,11 +171,13 @@
SEAT_FOOTWELL_LIGHTS_SWITCH = (((0x0B9C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518812 */,
SEAT_EASY_ACCESS_ENABLED = (((0x0B9D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421661 */,
SEAT_AIRBAG_ENABLED = (((0x0B9E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421662 */,
+ SEAT_AIRBAGS_DEPLOYED = (((0x0BA5 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518821 */,
SEAT_CUSHION_SIDE_SUPPORT_POS = (((0x0B9F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518815 */,
SEAT_CUSHION_SIDE_SUPPORT_MOVE = (((0x0BA0 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518816 */,
SEAT_LUMBAR_VERTICAL_POS = (((0x0BA1 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518817 */,
SEAT_LUMBAR_VERTICAL_MOVE = (((0x0BA2 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518818 */,
SEAT_WALK_IN_POS = (((0x0BA3 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 356518819 */,
+ SEAT_BELT_PRETENSIONER_DEPLOYED = (((0x0BA6 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.SEAT) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 354421670 */,
SEAT_OCCUPANCY = (((0x0BB0 + 0x10000000) + 0x05000000) + 0x00400000) /* 356518832 */,
WINDOW_POS = (((0x0BC0 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964416 */,
WINDOW_MOVE = (((0x0BC1 + 0x10000000) + 0x03000000) + 0x00400000) /* 322964417 */,
@@ -246,6 +252,7 @@
SHUTDOWN_REQUEST = (((0x0F49 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410889 */,
VEHICLE_IN_USE = (((0x0F4A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313738 */,
CLUSTER_HEARTBEAT = (((0x0F4B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 299896651 */,
+ VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL = (((0x0F4C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410892 */,
AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1000 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313920 */,
AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1001 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411073 */,
FORWARD_COLLISION_WARNING_ENABLED = (((0x1002 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313922 */,
@@ -271,4 +278,14 @@
HANDS_ON_DETECTION_ENABLED = (((0x1016 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313942 */,
HANDS_ON_DETECTION_DRIVER_STATE = (((0x1017 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411095 */,
HANDS_ON_DETECTION_WARNING = (((0x1018 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411096 */,
+ DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED = (((0x1019 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313945 */,
+ DRIVER_DROWSINESS_ATTENTION_STATE = (((0x101A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411098 */,
+ DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED = (((0x101B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313947 */,
+ DRIVER_DROWSINESS_ATTENTION_WARNING = (((0x101C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411100 */,
+ DRIVER_DISTRACTION_SYSTEM_ENABLED = (((0x101D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313949 */,
+ DRIVER_DISTRACTION_STATE = (((0x101E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411102 */,
+ DRIVER_DISTRACTION_WARNING_ENABLED = (((0x101F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313951 */,
+ DRIVER_DISTRACTION_WARNING = (((0x1020 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411104 */,
+ LOW_SPEED_COLLISION_WARNING_ENABLED = (((0x1021 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313953 */,
+ LOW_SPEED_COLLISION_WARNING_STATE = (((0x1022 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411106 */,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
new file mode 100644
index 0000000..f350a6c
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of driver distraction monitoring.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDistractionState {
+ /**
+ * This state is used as an alternative for any DriverDistractionState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DISTRACTION_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDistractionState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * The system detects that the driver is attentive / not distracted.
+ */
+ NOT_DISTRACTED = 1,
+ /**
+ * The system detects that the driver is distracted, which can be anything that reduces the
+ * driver's foucs on the primary task of driving/controlling the vehicle.
+ */
+ DISTRACTED = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
new file mode 100644
index 0000000..a4b1984
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of the driver distraction monitoring system.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDistractionWarning {
+ /**
+ * This state is used as an alternative for any DriverDistractionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DISTRACTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDistractionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * When the driver distraction warning is enabled and the driver's current distraction level
+ * does not warrant the system to send a warning.
+ */
+ NO_WARNING = 1,
+ /**
+ * When the driver distraction warning is enabled and the system is warning the driver based on
+ * its assessment of the driver's current distraction level.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
new file mode 100644
index 0000000..d2aec1f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current state of driver drowsiness and attention monitoring.
+ *
+ * This enum could be extended in future releases to include additional feature states.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDrowsinessAttentionState {
+ /**
+ * This state is used as an alternative for any DriverDrowsinessAttentionState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DROWSINESS_ATTENTION_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDrowsinessAttentionState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Karolinska Sleepiness Scale Rating 1 described as extermely alert.
+ */
+ KSS_RATING_1_EXTREMELY_ALERT = 1,
+ /**
+ * Karolinska Sleepiness Scale Rating 2 described as very alert.
+ */
+ KSS_RATING_2_VERY_ALERT = 2,
+ /**
+ * Karolinska Sleepiness Scale Rating 3 described as alert.
+ */
+ KSS_RATING_3_ALERT = 3,
+ /**
+ * Karolinska Sleepiness Scale Rating 4 described as rather alert.
+ */
+ KSS_RATING_4_RATHER_ALERT = 4,
+ /**
+ * Karolinska Sleepiness Scale Rating 5 described as neither alert nor sleepy.
+ */
+ KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY = 5,
+ /**
+ * Karolinska Sleepiness Scale Rating 6 described as some signs of sleepiness.
+ */
+ KSS_RATING_6_SOME_SLEEPINESS = 6,
+ /**
+ * Karolinska Sleepiness Scale Rating 7 described as sleepy with no effort to
+ * keep awake.
+ */
+ KSS_RATING_7_SLEEPY_NO_EFFORT = 7,
+ /**
+ * Karolinska Sleepiness Scale Rating 8 described as sleepy with some effort to
+ * keep awake.
+ */
+ KSS_RATING_8_SLEEPY_SOME_EFFORT = 8,
+ /**
+ * Karolinska Sleepiness Scale Rating 9 described as very sleepy, with great
+ * effort to keep away, and fighthing sleep.
+ */
+ KSS_RATING_9_VERY_SLEEPY = 9,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
new file mode 100644
index 0000000..53b66b9
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the current warning state of the driver drowsiness and attention monitoring
+ * system.
+ */
+@VintfStability
+@Backing(type="int")
+enum DriverDrowsinessAttentionWarning {
+ /**
+ * This state is used as an alternative for any DriverDrowsinessAttentionWarning value that is
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#DRIVER_DROWSINESS_ATTENTION_WARNING should not use this state. The framework
+ * can use this field to remain backwards compatible if DriverDrowsinessAttentionWarning is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * When the driver drowsiness and attention warning is enabled, and the driver's current
+ * drowsiness and attention level does not warrant the system to send a warning.
+ */
+ NO_WARNING = 1,
+ /**
+ * When the driver drowsiness and attention warning is enabled, and the system is warning the
+ * driver based on its assessment of the driver's current drowsiness and attention level.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
new file mode 100644
index 0000000..0fc1a50
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various impact sensor locations on the car.
+ */
+@VintfStability
+@Backing(type="int")
+enum ImpactSensorLocation {
+ /**
+ * Other impact sensor location. Ideally this should never be used.
+ */
+ OTHER = 0x01,
+ /**
+ * Frontal impact sensor. Used for the sensor that detects head-on impact.
+ */
+ FRONT = 0x02,
+ /**
+ * Front-left door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the front-left door.
+ */
+ FRONT_LEFT_DOOR_SIDE = 0x04,
+ /**
+ * Front-right door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the front-right door.
+ */
+ FRONT_RIGHT_DOOR_SIDE = 0x08,
+ /**
+ * Rear-left door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the rear-left door.
+ */
+ REAR_LEFT_DOOR_SIDE = 0x10,
+ /**
+ * Rear-right door side impact sensor. Used for the sensor that detects collisions from the
+ * side, in particular on the rear-right door.
+ */
+ REAR_RIGHT_DOOR_SIDE = 0x20,
+ /**
+ * Rear impact sensor. Used for the sensor that detects collisions from the rear.
+ */
+ REAR = 0x40,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
new file mode 100644
index 0000000..028a2d9
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the state of Low Speed Collision Warning State.
+ */
+@VintfStability
+@Backing(type="int")
+enum LowSpeedCollisionWarningState {
+
+ /**
+ * This state is used as an alternative to any LowSpeedCollisionWarningState value that is not
+ * defined in the platform. Ideally, implementations of
+ * VehicleProperty#LOW_SPEED_COLLISION_WARNING_STATE should not use this state. The framework
+ * can use this field to remain backwards compatible if LowSpeedCollisionWarningState is
+ * extended to include additional states.
+ */
+ OTHER = 0,
+ /**
+ * Low Speed Collision Warning is enabled and monitoring for potential collision, but no
+ * potential collision is detected.
+ */
+ NO_WARNING = 1,
+ /**
+ * Low Speed Collision Warning is enabled, detects a potential collision, and is actively
+ * warning the user.
+ */
+ WARNING = 2,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
new file mode 100644
index 0000000..e4c43f7
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various airbag locations per seat.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleAirbagLocation {
+ /**
+ * This state is used as an alternative to any VehicleAirbagLocation value that is not defined
+ * in the platform. Ideally, implementations of VehicleProperty::SEAT_AIRBAGS_DEPLOYED should
+ * not use this state. The framework can use this field to remain backwards compatible if
+ * VehicleAirbagLocation is extended to include additional states.
+ */
+ OTHER = 0x01,
+ /**
+ * Front airbags. This enum is for the airbags that protect the seated person from the front,
+ * particularly the seated person's torso.
+ */
+ FRONT = 0x02,
+ /**
+ * Knee airbags. This enum is for the airbags that protect the seated person's knees.
+ */
+ KNEE = 0x04,
+ /**
+ * Left side airbags. This enum is for the side airbags that protect the left side of the seated
+ * person.
+ */
+ LEFT_SIDE = 0x08,
+ /**
+ * Right side airbags. This enum is for the side airbags that protect the right side of the
+ * seated person.
+ */
+ RIGHT_SIDE = 0x10,
+ /**
+ * Curtain airbags. This enum is for the airbags lined above the windows of the vehicle.
+ */
+ CURTAIN = 0x20,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
index 6f7f783..259b231 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleArea.aidl
@@ -49,6 +49,11 @@
DOOR = 0x06000000,
/** WHEEL maps to enum VehicleAreaWheel */
WHEEL = 0x07000000,
+ /**
+ * A property with the VENDOR vehicle area contains area IDs that are vendor defined. Each area
+ * ID within this area type must be unique with no overlapping bits set.
+ */
+ VENDOR = 0x08000000,
MASK = 0x0f000000,
}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
new file mode 100644
index 0000000..3860e7f
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various level of automation that can be expressed by the
+ * VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL property.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleAutonomousState {
+ /**
+ * No automation. ADAS systems are limited to providing warnings and momentary assistance. The
+ * driver is in constant supervision of all driving tasks and must steer, brake or accelerate as
+ * needed to maintain safety, and is still responsible for driving while the ADAS systems are
+ * engaged. Usage should be in accordance to Level 0 definition in J3016_202104 version of
+ * vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_0 = 0,
+ /**
+ * Driver assistance. ADAS systems can provide steering or brake/acceleration support to the
+ * driver. The driver is in constant supervision of all driving tasks and must steer, brake or
+ * accelerate as needed to maintain safety, and is still responsible for driving while the ADAS
+ * systems are engaged. Usage should be in accordance to Level 1 definition in J3016_202104
+ * version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_1 = 1,
+ /**
+ * Partial automation. ADAS systems can provide both steering and brake/acceleration support to
+ * the driver at the same time. The driver is in constant supervision of all driving tasks and
+ * must steer, brake or accelerate as needed to maintain safety, and is still responsible for
+ * driving while the ADAS systems are engaged. Usage should be in accordance to Level 2
+ * definition in J3016_202104 version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_2 = 2,
+ /**
+ * Conditional automation. ADAS systems can drive the vehicle under limited conditions and will
+ * not operate unless all required conditions are met. The driver is required to take over
+ * control of the vehicle when requested to do so by the ADAS systems, however is not
+ * responsible for driving while the ADAS systems are engaged. Usage should be in accordance to
+ * Level 3 definition in J3016_202104 version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_3 = 3,
+ /**
+ * High automation. ADAS systems can drive the vehicle under limited conditions and will not
+ * operate unless all required conditions are met. The driver is not required to take over
+ * control of the vehicle and is not responsible for driving while the ADAS systems are engaged.
+ * Usage should be in accordance to Level 4 definition in J3016_202104 version of vehicle
+ * autonomy levels defined by SAE.
+ */
+ LEVEL_4 = 4,
+ /**
+ * Full automation. ADAS systems can drive the vehicle under all conditions. The driver is not
+ * required to take over control of the vehicle and is not responsible for driving while the
+ * ADAS systems are engaged. Usage should be in accordance to Level 5 definition in J3016_202104
+ * version of vehicle autonomy levels defined by SAE.
+ */
+ LEVEL_5 = 5,
+}
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index af2e903..19537ac 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -427,6 +427,19 @@
RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
+ 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
/**
+ * EV battery average temperature
+ *
+ * Exposes the temperature of the battery in an EV. If multiple batteries exist in the EV, or
+ * multiple temperature sensors exist, this property should be set to the mean or a meaningful
+ * weighted average that best represents the overall temperature of the battery system.
+ *
+ * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+ * @access VehiclePropertyAccess.READ
+ * @unit VehicleUnit:CELSIUS
+ */
+ EV_BATTERY_AVERAGE_TEMPERATURE =
+ 0x030E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+ /**
* Tire pressure
*
* Each tires is identified by its areaConfig.areaId config and their
@@ -484,6 +497,22 @@
ENGINE_IDLE_AUTO_STOP_ENABLED =
0x0320 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
/**
+ * Impact detected.
+ *
+ * Bit flag property to relay information on whether an impact has occurred on a particular side
+ * of the vehicle as described through the ImpactSensorLocation enum. As a bit flag property,
+ * this property can be set to multiple ORed together values of the enum when necessary.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all bit flags of ImpactSensorLocation are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum ImpactSensorLocation
+ */
+ IMPACT_DETECTED =
+ 0x0330 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
* Currently selected gear
*
* This is the gear selected by the user.
@@ -659,6 +688,27 @@
EV_STOPPING_MODE =
0x040D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
/**
+ * Enable or disable Electronic Stability Control (ESC).
+ *
+ * Set true to enable ESC and false to disable ESC. When ESC is enabled, a system in the vehicle
+ * should be controlling the tires during instances with high risk of skidding to actively
+ * prevent the same from happening.
+ *
+ * In general, ELECTRONIC_STABILITY_CONTROL_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, such as the vehicle speed being too
+ * high, that information must be conveyed through the ErrorState values in the
+ * ELECTRONIC_STABILITY_CONTROL_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ ELECTRONIC_STABILITY_CONTROL_ENABLED =
+ 0x040E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
* HVAC Properties
*
* Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
@@ -1506,6 +1556,22 @@
PER_DISPLAY_BRIGHTNESS = 0x0A04 + 0x10000000 + 0x01000000
+ 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
/**
+ * Valet mode enabled
+ *
+ * This property allows the user to enable/disable valet mode in their vehicle. Valet mode is
+ * a privacy and security setting that prevents an untrusted driver to access more private areas
+ * in the vehicle, such as the glove box or the trunk(s).
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ VALET_MODE_ENABLED =
+ 0x0A05 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+ /**
* Property to feed H/W input events to android
*
* int32Values[0] : action defined by VehicleHwKeyInputAction
@@ -2676,6 +2742,28 @@
SEAT_AIRBAG_ENABLED =
0x0B9E + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
/**
+ * Seat airbags deployed
+ *
+ * Bit flag property to relay information on which airbags have been deployed in the vehicle at
+ * each seat, vs which ones are currently still armed. If SEAT_AIRBAG_ENABLED is set to false at
+ * a particular areaId, this property should return status code UNAVAILABLE at that areaId.
+ *
+ * Enums apply to each seat, not the global vehicle. For example, VehicleAirbagsLocation#CURTAIN
+ * at the driver seat areaId represents whether the driver side curtain airbag has been
+ * deployed. Multiple bit flags can be set to indicate that multiple different airbags have been
+ * deployed for the seat.
+ *
+ * For each seat area ID, the VehicleAreaConfig#supportedEnumValues array must be defined unless
+ * all states of VehicleAirbagLocation are supported (including OTHER, which is not
+ * recommended).
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleAirbagLocation
+ */
+ SEAT_AIRBAGS_DEPLOYED =
+ 0x0BA5 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
+ /**
* Represents property for seat’s hipside (bottom cushion’s side) support position.
*
* The maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers
@@ -2804,6 +2892,24 @@
SEAT_WALK_IN_POS =
0x0BA3 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
/**
+ * Seat belt pretensioner deployed.
+ *
+ * Property to relay information on whether the seat belt pretensioner has been deployed for a
+ * particular seat due to a collision. This is different from the regular seat belt tightening
+ * system that continuously adds tension to the seat belts so that they fit snugly around the
+ * person sitting in the seat, nor is it the seat belt retractor system that locks the seat belt
+ * in place during sudden brakes or when the user jerks the seat belt.
+ *
+ * If this property is dependant on the state of other properties, and those properties are
+ * currently in the state that doesn't support this property, this should return
+ * StatusCode#NOT_AVAILABLE
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ */
+ SEAT_BELT_PRETENSIONER_DEPLOYED =
+ 0x0BA6 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
+ /**
* Seat Occupancy
*
* Indicates whether a particular seat is occupied or not, to the best of the car's ability
@@ -4501,6 +4607,25 @@
CLUSTER_HEARTBEAT =
0x0F4B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.MIXED,
+ /**
+ * Current state of vehicle autonomy.
+ *
+ * Defines the level of autonomy currently engaged in the vehicle from the J3016_202104 revision
+ * of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full
+ * driving automation. These levels should be used in accordance with the standards defined in
+ * https://www.sae.org/standards/content/j3016_202104/ and
+ * https://www.sae.org/blog/sae-j3016-update
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of VehicleAutonomousState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum VehicleAutonomousState
+ */
+ VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL =
+ 0x0F4C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
/***********************************************************************************************
* Start of ADAS Properties
*
@@ -5087,6 +5212,236 @@
HANDS_ON_DETECTION_WARNING =
0x1018 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+ /**
+ * Enable or disable driver drowsiness and attention monitoring.
+ *
+ * Set true to enable driver drowsiness and attention monitoring and false to disable driver
+ * drowsiness and attention monitoring. When driver drowsiness and attention monitoring is
+ * enabled, a system inside the vehicle should be monitoring the drowsiness and attention level
+ * of the driver and warn the driver if needed.
+ *
+ * In general, DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, that information must be
+ * conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED =
+ 0x1019 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver drowsiness and attention level state.
+ *
+ * Returns the current detected state of driver drowiness and attention level based on the
+ * Karolinska Sleepiness scale. If alternative measurement methods are used, the value should be
+ * translated to the Karolinska Sleepiness Scale equivalent.
+ *
+ * Generally, this property should return a valid state defined in the
+ * DriverDrowsinessAttentionState or ErrorState. For example, if the feature is not available
+ * due to some temporary state, that information should be conveyed through ErrorState.
+ *
+ * If the vehicle is sending a warning to the user because the driver is too drowsy, the warning
+ * should be surfaced through {@link #DRIVER_DROWSINESS_ATTENTION_WARNING}.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDrowsinessAttentionState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDrowsinessAttentionState
+ * @data_enum ErrorState
+ */
+ DRIVER_DROWSINESS_ATTENTION_STATE =
+ 0x101A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver drowsiness and attention warnings.
+ *
+ * Set true to enable driver drowsiness and attention warnings and false to disable driver
+ * drowsiness and attention warnings.
+ *
+ * When driver drowsiness and attention warnings are enabled, the driver drowsiness and
+ * attention monitoring system inside the vehicle should warn the driver when it detects the
+ * driver is drowsy or not attentive.
+ *
+ * In general, DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED should always return true or false.
+ * If the feature is not available due to some temporary state, that information must be
+ * conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_WARNING property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED =
+ 0x101B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver drowsiness and attention warning.
+ *
+ * Returns whether a warning is being sent to the driver for being drowsy or not attentive.
+ *
+ * Generally, this property should return a valid state defined in
+ * DriverDrowsinessAttentionWarning or ErrorState. For example, if the feature is not available
+ * due to some temporary state, that information should be conveyed through an ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDrowsinessAttentionWarning (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDrowsinessAttentionWarning
+ * @data_enum ErrorState
+ */
+ DRIVER_DROWSINESS_ATTENTION_WARNING =
+ 0x101C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver distraction monitoring.
+ *
+ * Set true to enable driver distraction monitoring and false to disable driver
+ * distraction monitoring. When driver distraction monitoring is enabled, a system
+ * inside the vehicle should be monitoring the distraction level of the driver and
+ * warn the driver if needed.
+ *
+ * In general, DRIVER_DISTRACTION_SYSTEM_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, that information must be conveyed
+ * through the ErrorState values in the DRIVER_DISTRACTION_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DISTRACTION_SYSTEM_ENABLED =
+ 0x101D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver distraction state.
+ *
+ * Returns the current detected driver distraction state.
+ *
+ * Generally, this property should return a valid state defined in the DriverDistractionState or
+ * ErrorState. For example, if the feature is not available due to some temporary state, that
+ * information should be conveyed through ErrorState.
+ *
+ * If the vehicle is sending a warning to the user because the driver is too distracted, the
+ * warning should be surfaced through {@link #DRIVER_DISTRACTION_WARNING}.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDistractionState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDistractionState
+ * @data_enum ErrorState
+ */
+ DRIVER_DISTRACTION_STATE =
+ 0x101E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable driver distraction warnings.
+ *
+ * Set true to enable driver distraction warnings and false to disable driver distraction
+ * warnings.
+ *
+ * When driver distraction warnings are enabled, the driver distraction monitoring system inside
+ * the vehicle should warn the driver when it detects the driver is distracted.
+ *
+ * In general, DRIVER_DISTRACTION_WARNING_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, that information must be conveyed
+ * through the ErrorState values in the DRIVER_DISTRACTION_WARNING property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ DRIVER_DISTRACTION_WARNING_ENABLED =
+ 0x101F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Driver distraction warning.
+ *
+ * Returns whether a warning is being sent to the driver for being distracted.
+ *
+ * Generally, this property should return a valid state defined in DriverDistractionWarning or
+ * ErrorState. For example, if the feature is not available due to some temporary state, that
+ * information should be conveyed through an ErrorState.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both DriverDistractionWarning (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum DriverDistractionWarning
+ * @data_enum ErrorState
+ */
+ DRIVER_DISTRACTION_WARNING =
+ 0x1020 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
+ /**
+ * Enable or disable Low Speed Collision Warning.
+ *
+ * Set true to enable low speed collision warning and false to disable low speed collision
+ * warning. When low speed collision warning is enabled, the ADAS system in the vehicle should
+ * warn the driver of potential collisions at low speeds. This property is different from the
+ * pre-existing FORWARD_COLLISION_WARNING_ENABLED, which should apply to higher speed
+ * applications only. If the vehicle doesn't have a separate collision detection system for low
+ * speed environments, this property should not be implemented.
+ *
+ * In general, LOW_SPEED_COLLISION_WARNING_ENABLED should always return true or false. If the
+ * feature is not available due to some temporary state, such as the vehicle speed being too
+ * high, that information must be conveyed through the ErrorState values in the
+ * LOW_SPEED_COLLISION_WARNING_STATE property.
+ *
+ * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+ * implement it as VehiclePropertyAccess.READ only.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ_WRITE
+ * @access VehiclePropertyAccess.READ
+ */
+ LOW_SPEED_COLLISION_WARNING_ENABLED =
+ 0x1021 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+
+ /**
+ * Low Speed Collision Warning state.
+ *
+ * Returns the current state of Low Speed Collision Warning. This property must always return a
+ * valid state defined in LowSpeedCollisionWarningState or ErrorState. It must not surface
+ * errors through StatusCode and must use the supported error states instead. This property is
+ * different from the pre-existing FORWARD_COLLISION_WARNING_STATE, which should apply to higher
+ * speed applications only. If the vehicle doesn't have a separate collision detection system
+ * for low speed environments, this property should not be implemented.
+ *
+ * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
+ * unless all states of both LowSpeedCollisionWarningState (including OTHER, which is not
+ * recommended) and ErrorState are supported.
+ *
+ * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+ * @access VehiclePropertyAccess.READ
+ * @data_enum LowSpeedCollisionWarningState
+ * @data_enum ErrorState
+ */
+ LOW_SPEED_COLLISION_WARNING_STATE =
+ 0x1022 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+
/***************************************************************************
* End of ADAS Properties
**************************************************************************/
diff --git a/automotive/vehicle/tools/translate_aidl_enums.py b/automotive/vehicle/tools/translate_aidl_enums.py
new file mode 100644
index 0000000..d224f6f
--- /dev/null
+++ b/automotive/vehicle/tools/translate_aidl_enums.py
@@ -0,0 +1,231 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""A script to generate ENUM_NAME.java file and test files using ENUM_NAME.aidl file.
+
+ Need ANDROID_BUILD_TOP environmental variable to be set. This script will update ENUM_NAME.java
+ under packages/services/Car/car-lib/src/android/car/hardware/property, as well as the
+ ENUM_NAMETest.java files in cts/tests/tests/car/src/android/car/cts and
+ packages/services/Car/tests/android_car_api_test/src/android/car/apitest
+
+ Usage:
+ $ python translate_aidl_enums.py ENUM_NAME.aidl
+"""
+import os
+import sys
+
+LICENSE = """/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"""
+
+class EnumParser:
+ def __init__(self, file_path, file_name):
+ self.filePath = file_path
+ self.fileName = file_name
+ self.lowerFileName = self.fileName[0].lower() + self.fileName[1:]
+ self.enums = []
+ self.outputMsg = []
+ self.outputMsg.append(LICENSE)
+ self.outputMsg.append("\npackage android.car.hardware.property;\n")
+ self.outputMsg.append("""
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import com.android.car.internal.util.ConstantDebugUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+""")
+
+ with open(self.filePath, 'r') as f:
+ for line in f.readlines()[16:]:
+ if line in ["package android.hardware.automotive.vehicle;\n",
+ "@VintfStability\n",
+ '@Backing(type="int")\n']:
+ continue
+
+ msg = line
+ msgSplit = msg.strip().split()
+ if len(msgSplit) > 0 and msgSplit[0] == "enum":
+ msgSplit[0] = "public final class"
+ msg = " ".join(msgSplit) + "\n"
+ elif len(msgSplit) > 1 and msgSplit[1] == '=':
+ msgSplit.insert(0, " public static final int")
+ self.enums.append(msgSplit[1])
+ msgSplit[-1] = msgSplit[-1][:-1] + ";\n"
+ msg = " ".join(msgSplit)
+ elif msg == "}\n":
+ self.outputMsg.append("""
+ private {2}() {{}}
+
+ /**
+ * Returns a user-friendly representation of {{@code {2}}}.
+ */
+ @NonNull
+ public static String toString(@{2}Int int {0}) {{
+ String {0}String = ConstantDebugUtils.toName(
+ {2}.class, {0});
+ return ({0}String != null)
+ ? {0}String
+ : "0x" + Integer.toHexString({0});
+ }}
+
+ /** @hide */
+ @IntDef({1})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface {2}Int {{}}\n""".format(self.lowerFileName, "{" + ", ".join(self.enums) + "}",
+ self.fileName))
+ self.outputMsg.append(msg)
+ self.outputMsg.append("TODO: delete this line and manually update this file with app-facing documentation and necessary tags.\n")
+
+ self.outputMsgApiTest = []
+ self.outputMsgApiTest.append(LICENSE)
+ self.outputMsgApiTest.append("""package android.car.apitest;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@SmallTest
+@RunWith(Parameterized.class)
+public class {0}Test {{
+ private final int mJavaConstantValue;
+ private final int mHalConstantValue;
+
+ public {0}Test(int javaConstantValue, int halConstantValue) {{
+ mJavaConstantValue = javaConstantValue;
+ mHalConstantValue = halConstantValue;
+ }}
+
+ @Parameterized.Parameters
+ public static Collection constantValues() {{
+ return Arrays.asList(
+ new Object[][] {{""".format(self.fileName))
+ for enum in self.enums:
+ self.outputMsgApiTest.append("""
+ {{
+ android.car.hardware.property.{0}.{1},
+ android.hardware.automotive.vehicle.{0}.{1}
+ }},""".format(self.fileName, enum))
+ self.outputMsgApiTest.append("""
+ });
+ }
+
+ @Test
+ public void testMatchWithVehicleHal() {
+ assertWithMessage("Java constant")
+ .that(mJavaConstantValue)
+ .isEqualTo(mHalConstantValue);
+ }
+}
+""")
+
+ self.outputMsgCtsTest = []
+ self.outputMsgCtsTest.append(LICENSE)
+ self.outputMsgCtsTest.append("""
+package android.car.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.car.cts.utils.VehiclePropertyUtils;
+import android.car.hardware.property.{0};
+
+import org.junit.Test;
+
+import java.util.List;
+
+public class {0}Test {{
+
+ @Test
+ public void testToString() {{""".format(self.fileName))
+ for enum in self.enums:
+ self.outputMsgCtsTest.append("""
+ assertThat({0}.toString(
+ {0}.{1}))
+ .isEqualTo("{1}");""".format(self.fileName, enum))
+ self.outputMsgCtsTest.append("""
+ assertThat({0}.toString({1})).isEqualTo("{2}");
+ assertThat({0}.toString(12)).isEqualTo("0xc");
+ }}
+
+ @Test
+ public void testAll{0}sAreMappedInToString() {{
+ List<Integer> {3}s =
+ VehiclePropertyUtils.getIntegersFromDataEnums({0}.class);
+ for (Integer {3} : {3}s) {{
+ String {3}String = {0}.toString(
+ {3});
+ assertWithMessage("%s starts with 0x", {3}String).that(
+ {3}String.startsWith("0x")).isFalse();
+ }}
+ }}
+}}
+""".format(self.fileName, len(self.enums), hex(len(self.enums)), self.lowerFileName))
+
+def main():
+ if len(sys.argv) != 2:
+ print("Usage: {} enum_aidl_file".format(sys.argv[0]))
+ sys.exit(1)
+ print("WARNING: This file only generates the base enum values in the framework layer. The "
+ + "generated files must be reviewed by you and edited if any additional changes are "
+ + "required. The java enum file should be updated with app-developer facing "
+ + "documentation, the @FlaggedApi tag for the new API, and with the @SystemApi tag if "
+ + "the new property is system API")
+ file_path = sys.argv[1]
+ file_name = file_path.split('/')[-1][:-5]
+ parser = EnumParser(file_path, file_name)
+
+ android_top = os.environ['ANDROID_BUILD_TOP']
+ if not android_top:
+ print('ANDROID_BUILD_TOP is not in environmental variable, please run source and lunch '
+ + 'at the android root')
+
+ with open(android_top + "/packages/services/Car/car-lib/src/android/car/hardware/property/"
+ + file_name + ".java", 'w') as f:
+ f.write("".join(parser.outputMsg))
+
+ with open(android_top
+ + "/packages/services/Car/tests/android_car_api_test/src/android/car/apitest/"
+ + file_name + "Test.java", 'w') as f:
+ f.write("".join(parser.outputMsgApiTest))
+
+ with open(android_top + "/cts/tests/tests/car/src/android/car/cts/" + file_name + "Test.java",
+ 'w') as f:
+ f.write("".join(parser.outputMsgCtsTest))
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/automotive/vehicle/vts/OWNERS b/automotive/vehicle/vts/OWNERS
index c93a843..0f88eec 100644
--- a/automotive/vehicle/vts/OWNERS
+++ b/automotive/vehicle/vts/OWNERS
@@ -1,3 +1,3 @@
# Bug component: 533426
shanyu@google.com
-kwangsudo@google.com
+tylertrephan@google.com
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 3dca0ae..5929a39 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -621,6 +621,54 @@
VehicleArea::GLOBAL, VehiclePropertyType::INT32);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionSystemEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionStateConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDrowsinessAttentionWarningConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionSystemEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionStateConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyDriverDistractionWarningConfig) {
+ verifyProperty(VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBrakeRegenerationLevelConfig) {
verifyProperty(VehicleProperty::EV_BRAKE_REGENERATION_LEVEL,
VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
@@ -891,6 +939,60 @@
VehicleArea::GLOBAL, VehiclePropertyType::MIXED);
}
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyVehicleDrivingAutomationCurrentLevelConfig) {
+ verifyProperty(VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL,
+ VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatAirbagsDeployedConfig) {
+ verifyProperty(VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifySeatBeltPretensionerDeployedConfig) {
+ verifyProperty(VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::SEAT, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyImpactDetectedConfig) {
+ verifyProperty(VehicleProperty::IMPACT_DETECTED, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyEvBatteryAverageTemperatureConfig) {
+ verifyProperty(VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::CONTINUOUS, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedCollisionWarningEnabledConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyLowSpeedCollisionWarningStateConfig) {
+ verifyProperty(VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyValetModeEnabledConfig) {
+ verifyProperty(VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE,
+ VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+ VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyElectronicStabilityControlEnabledConfig) {
+ verifyProperty(VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED,
+ VehiclePropertyAccess::READ_WRITE, VehiclePropertyChangeMode::ON_CHANGE,
+ VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
bool VtsHalAutomotiveVehicleTargetTest::checkIsSupported(int32_t propertyId) {
auto result = mVhalClient->getPropConfigs({propertyId});
return result.ok();
diff --git a/biometrics/common/aidl/Android.bp b/biometrics/common/aidl/Android.bp
index b41a937..8502a82 100644
--- a/biometrics/common/aidl/Android.bp
+++ b/biometrics/common/aidl/Android.bp
@@ -13,7 +13,7 @@
srcs: [
"android/hardware/biometrics/common/*.aidl",
],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
java: {
diff --git a/biometrics/common/util/Android.bp b/biometrics/common/util/Android.bp
index b990812..599c491 100644
--- a/biometrics/common/util/Android.bp
+++ b/biometrics/common/util/Android.bp
@@ -13,6 +13,6 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
],
}
diff --git a/biometrics/face/aidl/Android.bp b/biometrics/face/aidl/Android.bp
index 6c8cd78..7adf402 100644
--- a/biometrics/face/aidl/Android.bp
+++ b/biometrics/face/aidl/Android.bp
@@ -14,7 +14,7 @@
"android/hardware/biometrics/face/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V3",
+ "android.hardware.biometrics.common-V4",
"android.hardware.common-V2",
"android.hardware.keymaster-V4",
],
@@ -60,8 +60,16 @@
"android.hardware.keymaster-V4",
],
},
+ {
+ version: "4",
+ imports: [
+ "android.hardware.biometrics.common-V4",
+ "android.hardware.common-V2",
+ "android.hardware.keymaster-V4",
+ ],
+ },
],
- frozen: false,
+ frozen: true,
}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/.hash b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/.hash
new file mode 100644
index 0000000..e9a5aa3
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/.hash
@@ -0,0 +1 @@
+c43fbb9be4a662cc9ace640dba21cccdb84c6c21
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AcquiredInfo.aidl
new file mode 100644
index 0000000..1420cdc
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum AcquiredInfo {
+ UNKNOWN,
+ GOOD,
+ INSUFFICIENT,
+ TOO_BRIGHT,
+ TOO_DARK,
+ TOO_CLOSE,
+ TOO_FAR,
+ FACE_TOO_HIGH,
+ FACE_TOO_LOW,
+ FACE_TOO_RIGHT,
+ FACE_TOO_LEFT,
+ POOR_GAZE,
+ NOT_DETECTED,
+ TOO_MUCH_MOTION,
+ RECALIBRATE,
+ TOO_DIFFERENT,
+ TOO_SIMILAR,
+ PAN_TOO_EXTREME,
+ TILT_TOO_EXTREME,
+ ROLL_TOO_EXTREME,
+ FACE_OBSCURED,
+ START,
+ SENSOR_DIRTY,
+ VENDOR,
+ FIRST_FRAME_RECEIVED,
+ DARK_GLASSES_DETECTED,
+ MOUTH_COVERING_DETECTED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AuthenticationFrame.aidl
new file mode 100644
index 0000000..bbaca12
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable AuthenticationFrame {
+ android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/BaseFrame.aidl
new file mode 100644
index 0000000..1dd0a9c
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/BaseFrame.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable BaseFrame {
+ android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN;
+ int vendorCode;
+ float pan;
+ float tilt;
+ float distance;
+ boolean isCancellable;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Cell.aidl
new file mode 100644
index 0000000..d423a69
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Cell.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable Cell {
+ int x;
+ int y;
+ int z;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentFrame.aidl
new file mode 100644
index 0000000..90be5d0
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable EnrollmentFrame {
+ @nullable android.hardware.biometrics.face.Cell cell;
+ android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
+ android.hardware.biometrics.face.BaseFrame data;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStage.aidl
new file mode 100644
index 0000000..89b06ca
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum EnrollmentStage {
+ UNKNOWN,
+ FIRST_FRAME_RECEIVED,
+ WAITING_FOR_CENTERING,
+ HOLD_STILL_IN_CENTER,
+ ENROLLING_MOVEMENT_1,
+ ENROLLING_MOVEMENT_2,
+ ENROLLMENT_FINISHED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
new file mode 100644
index 0000000..ee1c01a
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable EnrollmentStageConfig {
+ android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
+ List<android.hardware.biometrics.face.Cell> cells;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentType.aidl
new file mode 100644
index 0000000..180ea5d
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum EnrollmentType {
+ DEFAULT,
+ ACCESSIBILITY,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Error.aidl
new file mode 100644
index 0000000..5761e31
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Error.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum Error {
+ UNKNOWN,
+ HW_UNAVAILABLE,
+ UNABLE_TO_PROCESS,
+ TIMEOUT,
+ NO_SPACE,
+ CANCELED,
+ UNABLE_TO_REMOVE,
+ VENDOR,
+ REENROLL_REQUIRED,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceEnrollOptions.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceEnrollOptions.aidl
new file mode 100644
index 0000000..c961531
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceEnrollOptions.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable FaceEnrollOptions {
+ android.hardware.keymaster.HardwareAuthToken hardwareAuthToken;
+ android.hardware.biometrics.face.EnrollmentType enrollmentType;
+ android.hardware.biometrics.face.Feature[] features;
+ /**
+ * @deprecated use {@link surfacePreview} instead {@link NativeHandle} a handle used to render content from the face HAL. Note that only one of [{@link surfacePreview}, {@link nativeHandlePreview}] should be set at one time.
+ */
+ @nullable android.hardware.common.NativeHandle nativeHandlePreview;
+ @nullable android.view.Surface surfacePreview;
+ @nullable android.hardware.biometrics.common.OperationContext context;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceSensorType.aidl
new file mode 100644
index 0000000..ec03733
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum FaceSensorType {
+ UNKNOWN,
+ RGB,
+ IR,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Feature.aidl
new file mode 100644
index 0000000..3337df8
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/Feature.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@Backing(type="byte") @VintfStability
+enum Feature {
+ REQUIRE_ATTENTION,
+ REQUIRE_DIVERSE_POSES,
+ DEBUG,
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/IFace.aidl
new file mode 100644
index 0000000..1ae76de
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/IFace.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+interface IFace {
+ android.hardware.biometrics.face.SensorProps[] getSensorProps();
+ android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb);
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISession.aidl
new file mode 100644
index 0000000..b655d5f
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISession.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+interface ISession {
+ void generateChallenge();
+ void revokeChallenge(in long challenge);
+ android.hardware.biometrics.face.EnrollmentStageConfig[] getEnrollmentConfig(in android.hardware.biometrics.face.EnrollmentType enrollmentType);
+ /**
+ * @deprecated use {@link enrollWithOptions} instead.
+ */
+ android.hardware.biometrics.common.ICancellationSignal enroll(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface);
+ android.hardware.biometrics.common.ICancellationSignal authenticate(in long operationId);
+ android.hardware.biometrics.common.ICancellationSignal detectInteraction();
+ void enumerateEnrollments();
+ void removeEnrollments(in int[] enrollmentIds);
+ void getFeatures();
+ void setFeature(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.Feature feature, boolean enabled);
+ void getAuthenticatorId();
+ void invalidateAuthenticatorId();
+ void resetLockout(in android.hardware.keymaster.HardwareAuthToken hat);
+ void close();
+ android.hardware.biometrics.common.ICancellationSignal authenticateWithContext(in long operationId, in android.hardware.biometrics.common.OperationContext context);
+ /**
+ * @deprecated use {@link enrollWithOptions} instead.
+ */
+ android.hardware.biometrics.common.ICancellationSignal enrollWithContext(in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in @nullable android.hardware.common.NativeHandle previewSurface, in android.hardware.biometrics.common.OperationContext context);
+ android.hardware.biometrics.common.ICancellationSignal detectInteractionWithContext(in android.hardware.biometrics.common.OperationContext context);
+ void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
+ android.hardware.biometrics.common.ICancellationSignal enrollWithOptions(in android.hardware.biometrics.face.FaceEnrollOptions options);
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISessionCallback.aidl
new file mode 100644
index 0000000..c6c035b
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+interface ISessionCallback {
+ void onChallengeGenerated(in long challenge);
+ void onChallengeRevoked(in long challenge);
+ void onAuthenticationFrame(in android.hardware.biometrics.face.AuthenticationFrame frame);
+ void onEnrollmentFrame(in android.hardware.biometrics.face.EnrollmentFrame frame);
+ void onError(in android.hardware.biometrics.face.Error error, in int vendorCode);
+ void onEnrollmentProgress(in int enrollmentId, int remaining);
+ void onAuthenticationSucceeded(in int enrollmentId, in android.hardware.keymaster.HardwareAuthToken hat);
+ void onAuthenticationFailed();
+ void onLockoutTimed(in long durationMillis);
+ void onLockoutPermanent();
+ void onLockoutCleared();
+ void onInteractionDetected();
+ void onEnrollmentsEnumerated(in int[] enrollmentIds);
+ void onFeaturesRetrieved(in android.hardware.biometrics.face.Feature[] features);
+ void onFeatureSet(android.hardware.biometrics.face.Feature feature);
+ void onEnrollmentsRemoved(in int[] enrollmentIds);
+ void onAuthenticatorIdRetrieved(in long authenticatorId);
+ void onAuthenticatorIdInvalidated(in long newAuthenticatorId);
+ void onSessionClosed();
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/SensorProps.aidl
new file mode 100644
index 0000000..918332b
--- /dev/null
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/4/android/hardware/biometrics/face/SensorProps.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.biometrics.face;
+/* @hide */
+@VintfStability
+parcelable SensorProps {
+ android.hardware.biometrics.common.CommonProps commonProps;
+ android.hardware.biometrics.face.FaceSensorType sensorType = android.hardware.biometrics.face.FaceSensorType.UNKNOWN;
+ boolean halControlsPreview;
+ int previewDisplayId;
+ int enrollPreviewWidth;
+ int enrollPreviewHeight;
+ float enrollTranslationX;
+ float enrollTranslationY;
+ float enrollPreviewScale;
+ boolean supportsDetectInteraction;
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index 5312ca1..1420cdc 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum AcquiredInfo {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
index 20bc767..bbaca12 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable AuthenticationFrame {
android.hardware.biometrics.face.BaseFrame data;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
index 67b5cf4..1dd0a9c 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable BaseFrame {
android.hardware.biometrics.face.AcquiredInfo acquiredInfo = android.hardware.biometrics.face.AcquiredInfo.UNKNOWN;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
index 6be8c8e..d423a69 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable Cell {
int x;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
index 0ea10d6..90be5d0 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable EnrollmentFrame {
@nullable android.hardware.biometrics.face.Cell cell;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
index a203dbe..89b06ca 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum EnrollmentStage {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index 48db2cf..ee1c01a 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable EnrollmentStageConfig {
android.hardware.biometrics.face.EnrollmentStage stage = android.hardware.biometrics.face.EnrollmentStage.UNKNOWN;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
index da1e8a3..180ea5d 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum EnrollmentType {
DEFAULT,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
index 28eb420..5761e31 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum Error {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl
index 23fa147..c961531 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceEnrollOptions.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable FaceEnrollOptions {
android.hardware.keymaster.HardwareAuthToken hardwareAuthToken;
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
index bf1677c..ec03733 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum FaceSensorType {
UNKNOWN,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
index 924e6af..3337df8 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@Backing(type="byte") @VintfStability
enum Feature {
REQUIRE_ATTENTION,
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
index fc4a4d0..1ae76de 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
interface IFace {
android.hardware.biometrics.face.SensorProps[] getSensorProps();
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index 4d99f5a..b655d5f 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
interface ISession {
void generateChallenge();
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
index bbace29..c6c035b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
interface ISessionCallback {
void onChallengeGenerated(in long challenge);
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index 8b3c51b..918332b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -32,6 +32,7 @@
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.biometrics.face;
+/* @hide */
@VintfStability
parcelable SensorProps {
android.hardware.biometrics.common.CommonProps commonProps;
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index cf68421..48b3e8c 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.face;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum AcquiredInfo {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
index be61a20..08ef973 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -20,6 +20,7 @@
/**
* Describes an individual frame captured during authentication.
+ * @hide
*/
@VintfStability
parcelable AuthenticationFrame {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
index 58ad01a..e407d91 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/BaseFrame.aidl
@@ -22,6 +22,7 @@
* Metadata of an individual frame. Can be used by the framework to provide user feedback.
* This parcelable is part of AuthenticationFrame and EnrollmentFrame, and shouldn't be used
* independently of those parcelables.
+ * @hide
*/
@VintfStability
parcelable BaseFrame {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
index 77f33b9..8960d57 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Cell.aidl
@@ -18,6 +18,7 @@
/**
* Coordinates of an enrollment UI cell in a vendor-defined coordinate system.
+ * @hide
*/
@VintfStability
parcelable Cell {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
index ecb0e79..15f019c 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -22,6 +22,7 @@
/**
* Describes an individual frame captured during enrollment.
+ * @hide
*/
@VintfStability
parcelable EnrollmentFrame {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
index 5974838..1a3c029 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -18,6 +18,7 @@
/**
* Enrollment stages that can be mapped to the enrollment UI actions in the framework.
+ * @hide
*/
@VintfStability
@Backing(type="byte")
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index a8fa9ab..362d752 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -19,6 +19,9 @@
import android.hardware.biometrics.face.Cell;
import android.hardware.biometrics.face.EnrollmentStage;
+/**
+ * @hide
+ */
@VintfStability
parcelable EnrollmentStageConfig {
/**
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
index c960933..5d92087 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -16,6 +16,9 @@
package android.hardware.biometrics.face;
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum EnrollmentType {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
index e99415a..77d4717 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl
@@ -15,7 +15,9 @@
*/
package android.hardware.biometrics.face;
-
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum Error {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl
index 75e3978..c57fb55 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceEnrollOptions.aidl
@@ -26,6 +26,7 @@
/**
* Enroll options used to pass information to the HAL when requesting an enroll operation.
+ * @hide
*/
@VintfStability
parcelable FaceEnrollOptions {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
index a5ed2e8..bf315a5 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -16,6 +16,9 @@
package android.hardware.biometrics.face;
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum FaceSensorType {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
index bff1a02..9cbab55 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/Feature.aidl
@@ -16,6 +16,9 @@
package android.hardware.biometrics.face;
+/**
+ * @hide
+ */
@VintfStability
@Backing(type="byte")
enum Feature {
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
index 65c589f..0ead435 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
@@ -20,6 +20,9 @@
import android.hardware.biometrics.face.ISessionCallback;
import android.hardware.biometrics.face.SensorProps;
+/**
+ * @hide
+ */
@VintfStability
interface IFace {
/**
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 825af0c..26cb361 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -42,6 +42,7 @@
* ISession only supports execution of one operation at a time, regardless of whether it's
* cancellable or not. The framework must wait for a corresponding callback indicating the end of
* the current operation before a new operation can be started.
+ * @hide
*/
@VintfStability
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
index 9eb575c..b38e366 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -23,6 +23,9 @@
import android.hardware.biometrics.face.Feature;
import android.hardware.keymaster.HardwareAuthToken;
+/**
+ * @hide
+ */
@VintfStability
interface ISessionCallback {
/**
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
index 5f881ca..09fd9e5 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/SensorProps.aidl
@@ -19,6 +19,9 @@
import android.hardware.biometrics.common.CommonProps;
import android.hardware.biometrics.face.FaceSensorType;
+/**
+ * @hide
+ */
@VintfStability
parcelable SensorProps {
/**
diff --git a/biometrics/face/aidl/default/Android.bp b/biometrics/face/aidl/default/Android.bp
index ecd0934..4e8390a 100644
--- a/biometrics/face/aidl/default/Android.bp
+++ b/biometrics/face/aidl/default/Android.bp
@@ -30,6 +30,7 @@
"libnativewindow",
],
srcs: [
+ "FakeLockoutTracker.cpp",
"main.cpp",
"Face.cpp",
"FakeFaceEngine.cpp",
@@ -40,7 +41,7 @@
],
stl: "c++_static",
static_libs: [
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.biometrics.face-V4-ndk",
@@ -63,6 +64,7 @@
srcs: [
"tests/FakeFaceEngineTest.cpp",
"FakeFaceEngine.cpp",
+ "FakeLockoutTracker.cpp",
],
shared_libs: [
"libbase",
@@ -75,7 +77,33 @@
static_libs: [
"libandroid.hardware.biometrics.face.VirtualProps",
"android.hardware.biometrics.face-V4-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
+ "android.hardware.keymaster-V4-ndk",
+ "android.hardware.biometrics.common.util",
+ ],
+ vendor: true,
+ test_suites: ["general-tests"],
+ require_root: true,
+}
+
+cc_test {
+ name: "android.hardware.biometrics.face.FakeLockoutTrackerTest",
+ srcs: [
+ "tests/FakeLockoutTrackerTest.cpp",
+ "FakeLockoutTracker.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libnativewindow",
+ ],
+ include_dirs: [
+ "frameworks/native/aidl/gui",
+ ],
+ static_libs: [
+ "libandroid.hardware.biometrics.face.VirtualProps",
+ "android.hardware.biometrics.face-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.cpp b/biometrics/face/aidl/default/FakeFaceEngine.cpp
index 578231d..7380611 100644
--- a/biometrics/face/aidl/default/FakeFaceEngine.cpp
+++ b/biometrics/face/aidl/default/FakeFaceEngine.cpp
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FaceVirtualHalEngine"
+
#include "FakeFaceEngine.h"
#include <android-base/logging.h>
@@ -53,15 +71,6 @@
const std::vector<Feature>& /*features*/,
const std::future<void>& cancel) {
BEGIN_OP(FaceHalProperties::operation_start_enroll_latency().value_or(0));
- // format is "<id>,<bucket_id>:<delay>:<succeeds>,<bucket_id>:<delay>:<succeeds>...
- auto nextEnroll = FaceHalProperties::next_enrollment().value_or("");
- // Erase the next enrollment
- FaceHalProperties::next_enrollment({});
-
- AuthenticationFrame frame;
- frame.data.acquiredInfo = AcquiredInfo::START;
- frame.data.vendorCode = 0;
- cb->onAuthenticationFrame(frame);
// Do proper HAT verification in the real implementation.
if (hat.mac.empty()) {
@@ -70,66 +79,81 @@
return;
}
- if (FaceHalProperties::operation_enroll_fails().value_or(false)) {
- LOG(ERROR) << "Fail: operation_enroll_fails";
+ // Format: <id>:<progress_ms-[acquiredInfo,...],...:<success>
+ // ------:-----------------------------------------:--------------
+ // | | |--->enrollment success (true/false)
+ // | |--> progress_steps
+ // |
+ // |-->enrollment id
+ //
+ //
+ // progress_steps
+ // <progress_duration>-[acquiredInfo,...]+
+ // ---------------------------- ---------------------
+ // | |-> sequence of acquiredInfo code
+ // | --> time duration of the step in ms
+ //
+ // E.g. 1:2000-[21,1108,5,6,1],1000-[1113,4,1]:true
+ // A success enrollement of id 1 by 2 steps
+ // 1st step lasts 2000ms with acquiredInfo codes (21,1108,5,6,1)
+ // 2nd step lasts 1000ms with acquiredInfo codes (1113,4,1)
+ //
+ std::string defaultNextEnrollment =
+ "1:1000-[21,7,1,1103],1500-[1108,1],2000-[1113,1],2500-[1118,1]:true";
+ auto nextEnroll = FaceHalProperties::next_enrollment().value_or(defaultNextEnrollment);
+ auto parts = Util::split(nextEnroll, ":");
+ if (parts.size() != 3) {
+ LOG(ERROR) << "Fail: invalid next_enrollment:" << nextEnroll;
cb->onError(Error::VENDOR, 0 /* vendorError */);
return;
}
-
- auto parts = Util::split(nextEnroll, ",");
- if (parts.size() < 2) {
- LOG(ERROR) << "Fail: invalid next_enrollment for : " << nextEnroll;
- cb->onError(Error::VENDOR, 0 /* vendorError */);
- return;
- }
-
auto enrollmentId = std::stoi(parts[0]);
- const int numBuckets = parts.size() - 1;
- for (size_t i = 1; i < parts.size(); i++) {
- auto enrollHit = Util::split(parts[i], ":");
- if (enrollHit.size() != 3) {
- LOG(ERROR) << "Error when unpacking enrollment hit: " << parts[i];
- cb->onError(Error::VENDOR, 0 /* vendorError */);
- }
- std::string bucket = enrollHit[0];
- std::string delay = enrollHit[1];
- std::string succeeds = enrollHit[2];
+ auto progress = Util::parseEnrollmentCapture(parts[1]);
+ for (size_t i = 0; i < progress.size(); i += 2) {
+ auto left = (progress.size() - i) / 2 - 1;
+ auto duration = progress[i][0];
+ auto acquired = progress[i + 1];
+ auto N = acquired.size();
- SLEEP_MS(std::stoi(delay));
+ for (int j = 0; j < N; j++) {
+ SLEEP_MS(duration / N);
- if (shouldCancel(cancel)) {
- LOG(ERROR) << "Fail: cancel";
- cb->onError(Error::CANCELED, 0 /* vendorCode */);
- return;
+ if (shouldCancel(cancel)) {
+ LOG(ERROR) << "Fail: cancel";
+ cb->onError(Error::CANCELED, 0 /* vendorCode */);
+ return;
+ }
+ EnrollmentFrame frame = {};
+ auto ac = convertAcquiredInfo(acquired[j]);
+ frame.data.acquiredInfo = ac.first;
+ frame.data.vendorCode = ac.second;
+ frame.stage = (i == 0 && j == 0) ? EnrollmentStage::FIRST_FRAME_RECEIVED
+ : (i == progress.size() - 2 && j == N - 1)
+ ? EnrollmentStage::ENROLLMENT_FINISHED
+ : EnrollmentStage::WAITING_FOR_CENTERING;
+ cb->onEnrollmentFrame(frame);
}
- if (!IS_TRUE(succeeds)) { // end and failed
- LOG(ERROR) << "Fail: requested by caller: " << parts[i];
+ if (left == 0 && !IS_TRUE(parts[2])) { // end and failed
+ LOG(ERROR) << "Fail: requested by caller: " << nextEnroll;
+ FaceHalProperties::next_enrollment({});
cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorCode */);
- return;
- }
-
- EnrollmentFrame frame;
-
- frame.data.acquiredInfo = AcquiredInfo::GOOD;
- frame.data.vendorCode = 0;
- cb->onEnrollmentFrame(frame);
-
- frame.data.acquiredInfo = AcquiredInfo::VENDOR;
- frame.data.vendorCode = std::stoi(bucket);
- cb->onEnrollmentFrame(frame);
-
- int remainingBuckets = numBuckets - i;
- if (remainingBuckets > 0) {
- cb->onEnrollmentProgress(enrollmentId, remainingBuckets);
+ } else { // progress and update props if last time
+ LOG(INFO) << "onEnroll: " << enrollmentId << " left: " << left;
+ if (left == 0) {
+ auto enrollments = FaceHalProperties::enrollments();
+ enrollments.emplace_back(enrollmentId);
+ FaceHalProperties::enrollments(enrollments);
+ FaceHalProperties::next_enrollment({});
+ // change authenticatorId after new enrollment
+ auto id = FaceHalProperties::authenticator_id().value_or(0);
+ auto newId = id + 1;
+ FaceHalProperties::authenticator_id(newId);
+ LOG(INFO) << "Enrolled: " << enrollmentId;
+ }
+ cb->onEnrollmentProgress(enrollmentId, left);
}
}
-
- auto enrollments = FaceHalProperties::enrollments();
- enrollments.push_back(enrollmentId);
- FaceHalProperties::enrollments(enrollments);
- LOG(INFO) << "enrolled : " << enrollmentId;
- cb->onEnrollmentProgress(enrollmentId, 0);
}
void FakeFaceEngine::authenticateImpl(ISessionCallback* cb, int64_t /*operationId*/,
@@ -180,6 +204,10 @@
return;
}
+ if (mLockoutTracker.checkIfLockout(cb)) {
+ return;
+ }
+
int i = 0;
do {
if (FaceHalProperties::lockout().value_or(false)) {
@@ -191,6 +219,7 @@
if (FaceHalProperties::operation_authenticate_fails().value_or(false)) {
LOG(ERROR) << "Fail: operation_authenticate_fails";
+ mLockoutTracker.addFailedAttempt(cb);
cb->onAuthenticationFailed();
return;
}
@@ -225,10 +254,12 @@
} while (!Util::hasElapsed(now, duration));
if (id > 0 && isEnrolled) {
+ mLockoutTracker.reset();
cb->onAuthenticationSucceeded(id, {} /* hat */);
return;
} else {
LOG(ERROR) << "Fail: face not enrolled";
+ mLockoutTracker.addFailedAttempt(cb);
cb->onAuthenticationFailed();
cb->onError(Error::TIMEOUT, 0 /* vendorError*/);
return;
@@ -383,6 +414,7 @@
const keymaster::HardwareAuthToken& /*hat*/) {
BEGIN_OP(0);
FaceHalProperties::lockout(false);
+ mLockoutTracker.reset();
cb->onLockoutCleared();
}
diff --git a/biometrics/face/aidl/default/FakeFaceEngine.h b/biometrics/face/aidl/default/FakeFaceEngine.h
index 06dd396..8d9303c 100644
--- a/biometrics/face/aidl/default/FakeFaceEngine.h
+++ b/biometrics/face/aidl/default/FakeFaceEngine.h
@@ -16,18 +16,17 @@
#pragma once
-#define LOG_TAG "FaceVirtualHal"
-
#include <aidl/android/hardware/biometrics/common/SensorStrength.h>
#include <aidl/android/hardware/biometrics/face/BnSession.h>
#include <aidl/android/hardware/biometrics/face/FaceSensorType.h>
#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
-#include <random>
-
#include <future>
+#include <random>
#include <vector>
+#include "FakeLockoutTracker.h"
+
namespace aidl::android::hardware::biometrics::face {
namespace face = aidl::android::hardware::biometrics::face;
@@ -39,6 +38,7 @@
class FakeFaceEngine {
public:
FakeFaceEngine() : mRandom(std::mt19937::default_seed) {}
+ virtual ~FakeFaceEngine() {}
static face::FaceSensorType GetSensorType();
static common::SensorStrength GetSensorStrength();
@@ -61,6 +61,13 @@
void invalidateAuthenticatorIdImpl(ISessionCallback* cb);
void resetLockoutImpl(ISessionCallback* cb, const keymaster::HardwareAuthToken& /*hat*/);
+ virtual std::string toString() const {
+ std::ostringstream os;
+ os << "----- FakeFaceEngine:: -----" << std::endl;
+ os << mLockoutTracker.toString();
+ return os.str();
+ }
+
std::mt19937 mRandom;
private:
@@ -68,6 +75,7 @@
static constexpr int32_t FACE_ERROR_VENDOR_BASE = 1000;
std::pair<AcquiredInfo, int32_t> convertAcquiredInfo(int32_t code);
std::pair<Error, int32_t> convertError(int32_t code);
+ FakeLockoutTracker mLockoutTracker;
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/FakeLockoutTracker.cpp b/biometrics/face/aidl/default/FakeLockoutTracker.cpp
new file mode 100644
index 0000000..70bf08e
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeLockoutTracker.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FaceVirtualHalLockoutTracker"
+
+#include "FakeLockoutTracker.h"
+#include <android-base/logging.h>
+#include <face.sysprop.h>
+#include "util/Util.h"
+
+using namespace ::android::face::virt;
+
+namespace aidl::android::hardware::biometrics::face {
+
+void FakeLockoutTracker::reset(bool dueToTimerExpire) {
+ if (!dueToTimerExpire) {
+ mFailedCount = 0;
+ mLastFailedTime = 0;
+ }
+ mTimedFailedCount = 0;
+ mCurrentMode = LockoutMode::kNone;
+ abortTimer();
+}
+
+void FakeLockoutTracker::addFailedAttempt(ISessionCallback* cb) {
+ bool lockoutEnabled = FaceHalProperties::lockout_enable().value_or(false);
+ bool timedLockoutenabled = FaceHalProperties::lockout_timed_enable().value_or(false);
+ if (lockoutEnabled) {
+ mFailedCount++;
+ mTimedFailedCount++;
+ mLastFailedTime = Util::getSystemNanoTime();
+ int32_t lockoutTimedThreshold = FaceHalProperties::lockout_timed_threshold().value_or(3);
+ int32_t lockoutPermanetThreshold =
+ FaceHalProperties::lockout_permanent_threshold().value_or(5);
+ if (mFailedCount >= lockoutPermanetThreshold) {
+ mCurrentMode = LockoutMode::kPermanent;
+ LOG(ERROR) << "FakeLockoutTracker: lockoutPermanent";
+ cb->onLockoutPermanent();
+ abortTimer();
+ } else if (timedLockoutenabled && mTimedFailedCount >= lockoutTimedThreshold) {
+ if (mCurrentMode == LockoutMode::kNone) {
+ mCurrentMode = LockoutMode::kTimed;
+ startLockoutTimer(getTimedLockoutDuration(), cb);
+ }
+ LOG(ERROR) << "FakeLockoutTracker: lockoutTimed";
+ cb->onLockoutTimed(getLockoutTimeLeft());
+ }
+ } else {
+ reset();
+ }
+}
+
+FakeLockoutTracker::LockoutMode FakeLockoutTracker::getMode() {
+ return mCurrentMode;
+}
+
+int32_t FakeLockoutTracker::getTimedLockoutDuration() {
+ return FaceHalProperties::lockout_timed_duration().value_or(10 * 1000);
+}
+
+int64_t FakeLockoutTracker::getLockoutTimeLeft() {
+ int64_t res = 0;
+
+ if (mLastFailedTime > 0) {
+ auto now = Util::getSystemNanoTime();
+ auto elapsed = (now - mLastFailedTime) / 1000000LL;
+ res = getTimedLockoutDuration() - elapsed;
+ LOG(INFO) << "elapsed=" << elapsed << " now = " << now
+ << " mLastFailedTime=" << mLastFailedTime << " res=" << res;
+ }
+
+ return res;
+}
+
+bool FakeLockoutTracker::checkIfLockout(ISessionCallback* cb) {
+ if (mCurrentMode == LockoutMode::kPermanent) {
+ LOG(ERROR) << "Lockout permanent";
+ cb->onLockoutPermanent();
+ return true;
+ } else if (mCurrentMode == LockoutMode::kTimed) {
+ auto timeLeft = getLockoutTimeLeft();
+ LOG(ERROR) << "Lockout timed " << timeLeft;
+ cb->onLockoutTimed(timeLeft);
+ return true;
+ }
+ return false;
+}
+
+void FakeLockoutTracker::startLockoutTimer(int64_t timeout, ISessionCallback* cb) {
+ LOG(ERROR) << "startLockoutTimer: to=" << timeout;
+ if (mIsLockoutTimerStarted) return;
+ std::function<void(ISessionCallback*)> action =
+ std::bind(&FakeLockoutTracker::lockoutTimerExpired, this, std::placeholders::_1);
+ std::thread([timeout, action, cb]() {
+ std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
+ action(cb);
+ }).detach();
+
+ mIsLockoutTimerStarted = true;
+}
+
+void FakeLockoutTracker::lockoutTimerExpired(ISessionCallback* cb) {
+ LOG(INFO) << "lockout timer expired";
+ mIsLockoutTimerStarted = false;
+
+ if (mIsLockoutTimerAborted) {
+ mIsLockoutTimerAborted = false;
+ return;
+ }
+
+ // if more failures seen since the timer started, need to restart timer again
+ auto deltaTime = getLockoutTimeLeft();
+ if (deltaTime <= 0) {
+ cb->onLockoutCleared();
+ reset(true);
+ } else {
+ startLockoutTimer(deltaTime, cb);
+ }
+}
+
+void FakeLockoutTracker::abortTimer() {
+ if (mIsLockoutTimerStarted) mIsLockoutTimerAborted = true;
+}
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/FakeLockoutTracker.h b/biometrics/face/aidl/default/FakeLockoutTracker.h
new file mode 100644
index 0000000..f2d38f3
--- /dev/null
+++ b/biometrics/face/aidl/default/FakeLockoutTracker.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/face/ISessionCallback.h>
+#include <android/binder_to_string.h>
+#include <stdint.h>
+#include <string>
+
+namespace aidl::android::hardware::biometrics::face {
+
+// Lockout implementation for Face Virtual HAL
+class FakeLockoutTracker {
+ public:
+ FakeLockoutTracker()
+ : mFailedCount(0),
+ mLastFailedTime(0),
+ mIsLockoutTimerStarted(false),
+ mIsLockoutTimerAborted(false) {}
+ ~FakeLockoutTracker() {}
+
+ enum class LockoutMode : int8_t { kNone = 0, kTimed, kPermanent };
+
+ bool checkIfLockout(ISessionCallback*);
+ void addFailedAttempt(ISessionCallback*);
+ int64_t getLockoutTimeLeft();
+ LockoutMode getMode();
+ void reset(bool dueToTimerExpire = false);
+ inline std::string toString() const {
+ std::ostringstream os;
+ os << "----- FakeLockoutTracker:: -----" << std::endl;
+ os << "mFailedCount:" << mFailedCount;
+ os << ", mCurrentMode:" << (int)mCurrentMode;
+ os << ", mLastFailedTime:" << (int)(mLastFailedTime / 1000000LL);
+ os << ", mIsLockoutTimerStarted:" << mIsLockoutTimerStarted;
+ os << ", mIsLockoutTimerAborted:" << mIsLockoutTimerAborted;
+ os << std::endl;
+ return os.str();
+ }
+
+ private:
+ void startLockoutTimer(int64_t timeout, ISessionCallback* cb);
+ void lockoutTimerExpired(ISessionCallback* cb);
+ int32_t getTimedLockoutDuration();
+ void abortTimer();
+
+ private:
+ int32_t mFailedCount;
+ int32_t mTimedFailedCount;
+ int64_t mLastFailedTime;
+ LockoutMode mCurrentMode;
+ bool mIsLockoutTimerStarted;
+ bool mIsLockoutTimerAborted;
+};
+
+} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/README.md b/biometrics/face/aidl/default/README.md
index 516a7aa..c9a8cfe 100644
--- a/biometrics/face/aidl/default/README.md
+++ b/biometrics/face/aidl/default/README.md
@@ -1,30 +1,35 @@
# Face Virtual HAL (VHAL)
-This is a virtual HAL implementation that is backed by system properties
-instead of actual hardware. It's intended for testing and UI development
-on debuggable builds to allow devices to masquerade as alternative device
-types and for emulators.
-Note: The virtual face HAL feature development will be done in phases. Refer to this doc often for
-the latest supported features
+This is a virtual HAL implementation that is backed by system properties instead
+of actual hardware. It's intended for testing and UI development on debuggable
+builds to allow devices to masquerade as alternative device types and for
+emulators. Note: The virtual face HAL feature development will be done in
+phases. Refer to this doc often for the latest supported features
## Supported Devices
-The face virtual hal is automatically built in in all debug builds (userdebug and eng) for the latest pixel devices and CF.
-The instructions in this doc applies to all
+The face virtual hal is automatically built in in all debug builds (userdebug<br/>
+and eng) for the latest pixel devices and CF. The instructions in this doc<br/>
+applies to all
## Enabling Face Virtual HAL
-On pixel devicse (non-CF), by default (after manufacture reset), Face VHAL is not enabled. Therefore real Face HAL is used.
-Face VHAL enabling is gated by the following two AND conditions:
-1. The Face VHAL feature flag (as part of Trunk-development strategy) must be tured until the flags life-cycle ends.
-2. The Face VHAL must be enabled via sysprop
-See adb commands below
+On pixel devicse (non-CF), by default (after manufacture reset), Face VHAL is <br/>
+not enabled. Therefore real Face HAL is used. Face VHAL enabling is gated by the<br/>
+following two AND conditions:<br/>
+1. The Face VHAL feature flag (as part ofTrunk-development strategy) must be<br/>
+ turned on until the flags life-cycle ends.
+2. The Face VHAL must be enabled via sysprop.
-##Getting Stared
+See the adb commands below
-A basic use case for a successful authentication via Face VHAL is given as an exmple below.
+## Getting Stared
+
+A basic use case for a successful authentication via Face VHAL is given as an
+exmple below.
### Enabling VHAL
+
```shell
$ adb root
$ adb shell device_config put biometrics_framework com.android.server.biometrics.face_vhal_feature true
@@ -35,6 +40,7 @@
```
### Direct Enrollment
+
```shell
$ adb shell locksettings set-pin 0000
$ adb shell setprop persist.vendor.face.virtual.enrollments 1
@@ -42,22 +48,80 @@
```
## Authenticating
-To authenticate successfully, the captured (hit) must match the enrollment id set above. To trigger
-authentication failure, set the hit id to a different value.
-```shell
+
+To authenticate successfully, the captured (hit) must match the enrollment id<br/>
+set above. To trigger authentication failure, set the hit id to a different value.
+`shell
$ adb shell setprop vendor.face.virtual.operation_authenticate_duration 800
-$ adb shell setprop vendor.face.virtual.enrollment_hit 1
-```
-Refer to face.sysprop for full supported features of authentication, such as error and acquiredInfo insertion
+$ adb shell setprop vendor.face.virtual.enrollment_hit 1`
+### AcquiredInfo
-## Enrollment via Setup
+AcquiredInfo codes can be sent during authentication by specifying the sysprop.<br/>
+The codes is sent in sequence and in the interval of operation_authentication_duration/numberOfAcquiredInfoCode
+`shell
+$ adb shell setprop vendor.face.virtual.operation_authenticate_acquired 6,9,1013`
+Refer to [AcquiredInfo.aidl](https://source.corp.google.com/h/googleplex-android/platform/superproject/main/+/main:hardware/interfaces/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl) for full face acquiredInfo codes.
+Note: For vendor specific acquired info, acquiredInfo = 1000 + vendorCode.
+
+### Error Insertion
+
+Error can be inserted during authentction by specifying the authenticate_error
+sysprop. `shell $ adb shell setprop
+vendor.face.virtual.operation_authenticate_error 4` Refer to
+[Error.aidl](https://source.corp.google.com/h/googleplex-android/platform/superproject/main/+/main:hardware/interfaces/biometrics/face/aidl/android/hardware/biometrics/face/Error.aidl)
+for full face error codes
+
+## Enrollment via Settings
+
+Enrollment process is specified by sysprop `next_enrollment` in the following
+format
```shell
-# authenticar_id,bucket_id:duration:(true|false)....
-$ adb shell setprop vendor.face.virtual.next_enrollment 1,0:500:true,5:250:true,10:150:true,15:500:true
-$ walk thru the manual enrollment process by following screen instructions
+Format: <id>:<progress_ms-[acquiredInfo,...],...:<success>
+ ----:-----------------------------------:---------
+ | | |--->sucess (true/false)
+ | |--> progress_step(s)
+ |
+ |-->enrollment_id
-# If you would like to get rid of the enrollment, run the follwoing command
-$ adb shell setprop persist.vendor.face.virtual.enrollments \"\"
+E.g.
+$ adb shell setprop vendor.face.virtual.next_enrollment 1:6000-[21,8,1,1108,1,10,1113,1,1118,1124]:true
```
+
+If next_enrollment prop is not set, the following default value is used:<br/>
+ defaultNextEnrollment="1:1000-[21,7,1,1103],1500-[1108,1],2000-[1113,1],2500-[1118,1]:true"<br/>
+Note: Enrollment data and configuration can be supported upon request in case of needs
+
+## Lockout
+
+Device lockout is based on the number of consecutive failed authentication attempts. There are a few
+flavors of lockout mechanisms that are supported by virtula HAL <br/>
+
+### Permanent Lockout
+
+There are two sysprop to control permanent lockout <br/>
+1. general lockout feature enable <br/>
+2. threshold of failed attempts <br/>
+`shell
+$ adb shell setprop persist.vendor.face.virtual.lockout_enable true
+$ adb shell setprop persist.vendor.face.virtual.lockout_permanent_threshold 3`
+
+### Temporary Lockout
+
+There are a few parameters to control temporary lockout (aka timed lockout): <br/>
+1. enable lockout (general lockout feature enable, and timed lcokout enable) <br/>
+2. threshold of failed attempts <br/>
+3. timeout in ms <br/>
+`shell
+$ adb shell setprop persist.vendor.face.virtual.lockout_enable true
+$ adb shell setprop persist.vendor.face.virtual.lockout_timed_enable true
+$ adb shell setprop persist.vendor.face.virtual.lockout_timed_threshold 5
+$ adb shell setprop persist.vendor.face.virtual.lockout_timed_duration 10000`
+
+### Forced Lockout
+
+A permanent lockout can be inserted on next authentication attempt independent of the failed <br/>
+attempt count. This is a feature purely for test purpose.
+`shell
+$ adb shell setprop persist.vendor.face.virtual.lockout true`
diff --git a/biometrics/face/aidl/default/face.sysprop b/biometrics/face/aidl/default/face.sysprop
index be32015..95b0b43 100644
--- a/biometrics/face/aidl/default/face.sysprop
+++ b/biometrics/face/aidl/default/face.sysprop
@@ -92,7 +92,7 @@
api_name: "challenge"
}
-# if locked out
+# if forced to lock out (Default to false)
prop {
prop_name: "vendor.face.virtual.lockout"
type: Boolean
@@ -176,3 +176,47 @@
api_name: "operation_authenticate_acquired"
}
+# whether support lockout based on the failed auth attempts (default: false)
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_enable"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_enable"
+}
+
+# whether support timed_lockout based on the failed auth attempts (default: false)
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_timed_enable"
+ type: Boolean
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_timed_enable"
+}
+
+# temperory lockout threshold in number of consecutive failed auth attempts
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_timed_threshold"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_timed_threshold"
+}
+
+# temporary lockout duration in ms (default: 10000ms)
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_timed_duration"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_timed_duration"
+}
+
+# permanently lockout threshold in number of consecutive failed auth attempts
+prop {
+ prop_name: "persist.vendor.face.virtual.lockout_permanent_threshold"
+ type: Integer
+ scope: Internal
+ access: ReadWrite
+ api_name: "lockout_permanent_threshold"
+}
diff --git a/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
index 6897dc4..69c9bf4 100644
--- a/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
+++ b/biometrics/face/aidl/default/tests/FakeFaceEngineTest.cpp
@@ -45,6 +45,7 @@
};
::ndk::ScopedAStatus onEnrollmentProgress(int32_t enrollmentId, int32_t remaining) override {
if (remaining == 0) mLastEnrolled = enrollmentId;
+ mRemaining = remaining;
return ndk::ScopedAStatus::ok();
};
@@ -128,6 +129,7 @@
bool mAuthenticatorIdInvalidated = false;
bool mLockoutPermanent = false;
int mInteractionDetectedCount = 0;
+ int mRemaining = -1;
};
class FakeFaceEngineTest : public ::testing::Test {
@@ -193,7 +195,7 @@
}
TEST_F(FakeFaceEngineTest, Enroll) {
- FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:true");
+ FaceHalProperties::next_enrollment("1,0:1000-[21,5,6,7,1],1100-[1118,1108,1]:true");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
mCancel.get_future());
@@ -201,10 +203,11 @@
ASSERT_EQ(1, FaceHalProperties::enrollments().size());
ASSERT_EQ(1, FaceHalProperties::enrollments()[0].value());
ASSERT_EQ(1, mCallback->mLastEnrolled);
+ ASSERT_EQ(0, mCallback->mRemaining);
}
TEST_F(FakeFaceEngineTest, EnrollFails) {
- FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+ FaceHalProperties::next_enrollment("1,0:1000-[21,5,6,7,1],1100-[1118,1108,1]:false");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
mCancel.get_future());
@@ -213,7 +216,7 @@
}
TEST_F(FakeFaceEngineTest, EnrollCancel) {
- FaceHalProperties::next_enrollment("1,0:30:true,1:0:true,2:0:true,3:0:true,4:0:false");
+ FaceHalProperties::next_enrollment("1:2000-[21,8,9],300:false");
keymaster::HardwareAuthToken hat{.mac = {2, 4}};
mCancel.set_value();
mEngine.enrollImpl(mCallback.get(), hat, {} /*enrollmentType*/, {} /*features*/,
@@ -221,7 +224,7 @@
ASSERT_EQ(Error::CANCELED, mCallback->mError);
ASSERT_EQ(-1, mCallback->mLastEnrolled);
ASSERT_EQ(0, FaceHalProperties::enrollments().size());
- ASSERT_FALSE(FaceHalProperties::next_enrollment().has_value());
+ ASSERT_TRUE(FaceHalProperties::next_enrollment().has_value());
}
TEST_F(FakeFaceEngineTest, Authenticate) {
diff --git a/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp b/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp
new file mode 100644
index 0000000..fa07d1d
--- /dev/null
+++ b/biometrics/face/aidl/default/tests/FakeLockoutTrackerTest.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/biometrics/face/BnSessionCallback.h>
+#include <android/binder_process.h>
+#include <face.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "FakeLockoutTracker.h"
+#include "util/Util.h"
+
+using namespace ::android::face::virt;
+using namespace ::aidl::android::hardware::biometrics::face;
+
+namespace aidl::android::hardware::biometrics::face {
+
+class TestSessionCallback : public BnSessionCallback {
+ public:
+ ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onError(face::Error, int32_t /*vendorCode*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
+ int32_t /*remaining*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
+ const keymaster::HardwareAuthToken&) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); };
+ ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); };
+ ::ndk::ScopedAStatus onEnrollmentsEnumerated(const std::vector<int32_t>&) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentsRemoved(
+ const std::vector<int32_t>& /*enrollmentIds*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onEnrollmentFrame(const EnrollmentFrame&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onFeaturesRetrieved(const std::vector<Feature>&) {
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onFeatureSet(Feature) override { return ndk::ScopedAStatus::ok(); }
+ ::ndk::ScopedAStatus onSessionClosed() override { return ndk::ScopedAStatus::ok(); }
+ ::ndk::ScopedAStatus onAuthenticationFrame(const AuthenticationFrame&) override {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus onLockoutTimed(int64_t timeLeft) override {
+ mLockoutTimed++;
+ mTimeLeft = timeLeft;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutPermanent() override {
+ mLockoutPermanent++;
+ return ndk::ScopedAStatus::ok();
+ };
+ ::ndk::ScopedAStatus onLockoutCleared() override {
+ mTimeLeft = 0;
+ mLockoutTimed = 0;
+ mLockoutPermanent = 0;
+ return ndk::ScopedAStatus::ok();
+ };
+
+ int64_t mTimeLeft = 0;
+ int mLockoutTimed = 0;
+ int mLockoutPermanent = 0;
+};
+
+class FakeLockoutTrackerTest : public ::testing::Test {
+ protected:
+ static constexpr int32_t LOCKOUT_TIMED_THRESHOLD = 3;
+ static constexpr int32_t LOCKOUT_PERMANENT_THRESHOLD = 5;
+ static constexpr int32_t LOCKOUT_TIMED_DURATION = 100;
+
+ void SetUp() override {
+ FaceHalProperties::lockout_timed_threshold(LOCKOUT_TIMED_THRESHOLD);
+ FaceHalProperties::lockout_timed_duration(LOCKOUT_TIMED_DURATION);
+ FaceHalProperties::lockout_permanent_threshold(LOCKOUT_PERMANENT_THRESHOLD);
+ mCallback = ndk::SharedRefBase::make<TestSessionCallback>();
+ }
+
+ void TearDown() override {
+ // reset to default
+ FaceHalProperties::lockout_timed_threshold(5);
+ FaceHalProperties::lockout_timed_duration(20);
+ FaceHalProperties::lockout_permanent_threshold(10000);
+ FaceHalProperties::lockout_enable(false);
+ FaceHalProperties::lockout(false);
+ }
+
+ FakeLockoutTracker mLockoutTracker;
+ std::shared_ptr<TestSessionCallback> mCallback;
+};
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptDisable) {
+ FaceHalProperties::lockout_enable(false);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD + 1; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ ASSERT_EQ(0, mCallback->mLockoutTimed);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptPermanent) {
+ FaceHalProperties::lockout_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - 1; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_NE(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ ASSERT_EQ(0, mCallback->mLockoutPermanent);
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ ASSERT_EQ(1, mCallback->mLockoutPermanent);
+ ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ ASSERT_EQ(2, mCallback->mLockoutPermanent);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimed) {
+ FaceHalProperties::lockout_enable(true);
+ FaceHalProperties::lockout_timed_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+ ASSERT_EQ(1, mCallback->mLockoutTimed);
+ ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ ASSERT_EQ(2, mCallback->mLockoutTimed);
+ // time left
+ int N = 5;
+ int64_t prevTimeLeft = INT_MAX;
+ for (int i = 0; i < N; i++) {
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / N + 1);
+ int64_t currTimeLeft = mLockoutTracker.getLockoutTimeLeft();
+ ASSERT_TRUE(currTimeLeft < prevTimeLeft);
+ prevTimeLeft = currTimeLeft;
+ }
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / N);
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockout_TimedThenPermanent) {
+ FaceHalProperties::lockout_enable(true);
+ FaceHalProperties::lockout_timed_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kTimed);
+ SLEEP_MS(LOCKOUT_TIMED_DURATION + 20);
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD - LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+}
+
+TEST_F(FakeLockoutTrackerTest, addFailedAttemptLockoutTimedTwice) {
+ FaceHalProperties::lockout_enable(true);
+ FaceHalProperties::lockout_timed_enable(true);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ ASSERT_EQ(0, mCallback->mLockoutTimed);
+ for (int i = 0; i < LOCKOUT_TIMED_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ SLEEP_MS(LOCKOUT_TIMED_DURATION / 2);
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ SLEEP_MS(LOCKOUT_TIMED_DURATION);
+ ASSERT_EQ(2, mCallback->mLockoutTimed);
+ ASSERT_TRUE(mLockoutTracker.checkIfLockout(mCallback.get()));
+ SLEEP_MS(LOCKOUT_TIMED_DURATION);
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+}
+
+TEST_F(FakeLockoutTrackerTest, resetLockout) {
+ FaceHalProperties::lockout_enable(true);
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kNone);
+ for (int i = 0; i < LOCKOUT_PERMANENT_THRESHOLD; i++)
+ mLockoutTracker.addFailedAttempt(mCallback.get());
+ ASSERT_EQ(mLockoutTracker.getMode(), FakeLockoutTracker::LockoutMode::kPermanent);
+ mLockoutTracker.reset();
+ ASSERT_FALSE(mLockoutTracker.checkIfLockout(mCallback.get()));
+}
+
+} // namespace aidl::android::hardware::biometrics::face
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ return RUN_ALL_TESTS();
+}
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index c543a93..1a099a5 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -14,7 +14,7 @@
"android/hardware/biometrics/fingerprint/**/*.aidl",
],
imports: [
- "android.hardware.biometrics.common-V3",
+ "android.hardware.biometrics.common-V4",
"android.hardware.keymaster-V4",
],
stability: "vintf",
@@ -50,5 +50,5 @@
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index a173a00..c3ec4d0 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -30,8 +30,8 @@
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
"libbase",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.biometrics.common.thread",
"android.hardware.biometrics.common.util",
"android.hardware.keymaster-V4-ndk",
@@ -54,8 +54,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -80,8 +80,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -104,8 +104,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
@@ -130,8 +130,8 @@
],
static_libs: [
"libandroid.hardware.biometrics.fingerprint.VirtualProps",
- "android.hardware.biometrics.fingerprint-V3-ndk",
- "android.hardware.biometrics.common-V3-ndk",
+ "android.hardware.biometrics.fingerprint-V4-ndk",
+ "android.hardware.biometrics.common-V4-ndk",
"android.hardware.keymaster-V4-ndk",
"android.hardware.biometrics.common.util",
],
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
index e977b98..827813f 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.xml
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.biometrics.fingerprint</name>
- <version>3</version>
+ <version>4</version>
<fqname>IFingerprint/virtual</fqname>
</hal>
</manifest>
diff --git a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
index 937cd57..0699781 100644
--- a/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
+++ b/bluetooth/aidl/default/net_bluetooth_mgmt.cpp
@@ -162,9 +162,9 @@
(struct mgmt_ev_read_index_list*)ev.data;
for (int i = 0; i < data->num_controllers; i++) {
- if (data->index[i] == hci_interface) {
- ALOGI("hci interface %d found", hci_interface);
- ret = 0;
+ if (data->index[i] >= hci_interface) {
+ ALOGI("hci interface %d found", data->index[i]);
+ ret = data->index[i];
goto end;
}
}
@@ -253,8 +253,9 @@
rfkill(1);
// Wait for the HCI interface to complete initialization or to come online.
- if (waitHciDev(hci_interface)) {
- ALOGE("hci interface %d not found", hci_interface);
+ hci_interface = waitHciDev(hci_interface);
+ if (hci_interface < 0) {
+ ALOGE("hci interface not found");
return -1;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
new file mode 100644
index 0000000..9e67b15
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable A2dpConfiguration {
+ int remoteSeid;
+ android.hardware.bluetooth.audio.CodecId id;
+ android.hardware.bluetooth.audio.CodecParameters parameters;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
new file mode 100644
index 0000000..0a5b489
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable A2dpConfigurationHint {
+ byte[6] bdAddr;
+ android.hardware.bluetooth.audio.AudioContext audioContext;
+ @nullable android.hardware.bluetooth.audio.CodecId codecId;
+ @nullable android.hardware.bluetooth.audio.CodecParameters codecParameters;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
new file mode 100644
index 0000000..9c1e971
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable A2dpRemoteCapabilities {
+ int seid;
+ android.hardware.bluetooth.audio.CodecId id;
+ byte[] capabilities;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl
new file mode 100644
index 0000000..ac22e25
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStatus.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@Backing(type="byte") @VintfStability
+enum A2dpStatus {
+ OK = 0,
+ BAD_LENGTH = 0x11u8,
+ BAD_PAYLOAD_FORMAT = 0x18u8,
+ INVALID_CODEC_TYPE = 0xC1u8,
+ NOT_SUPPORTED_CODEC_TYPE = 0xC2u8,
+ INVALID_SAMPLING_FREQUENCY = 0xC3u8,
+ NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4u8,
+ INVALID_CHANNEL_MODE = 0xC5u8,
+ NOT_SUPPORTED_CHANNEL_MODE = 0xC6u8,
+ INVALID_SUBBANDS = 0xC7u8,
+ NOT_SUPPORTED_SUBBANDS = 0xC8u8,
+ INVALID_ALLOCATION_METHOD = 0xC9u8,
+ NOT_SUPPORTED_ALLOCATION_METHOD = 0xCAu8,
+ INVALID_MINIMUM_BITPOOL_VALUE = 0xCBu8,
+ NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCCu8,
+ INVALID_MAXIMUM_BITPOOL_VALUE = 0xCDu8,
+ NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCEu8,
+ NOT_SUPPORTED_VBR = 0xD3u8,
+ NOT_SUPPORTED_BIT_RATE = 0xD5u8,
+ INVALID_OBJECT_TYPE = 0xD6u8,
+ NOT_SUPPORTED_OBJECT_TYPE = 0xD7u8,
+ INVALID_CHANNELS = 0xD8u8,
+ NOT_SUPPORTED_CHANNELS = 0xD9u8,
+ INVALID_BLOCK_LENGTH = 0xDDu8,
+ INVALID_CODEC_PARAMETER = 0xE2u8,
+ NOT_SUPPORTED_CODEC_PARAMETER = 0xE3u8,
+ INVALID_DRC = 0xE4u8,
+ NOT_SUPPORTED_DRC = 0xE5u8,
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
new file mode 100644
index 0000000..ff5a1bc
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable A2dpStreamConfiguration {
+ int peerMtu;
+ @nullable byte[1] cpHeaderScmst;
+ android.hardware.bluetooth.audio.CodecId codecId;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
index 2148244..418dd7a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AacObjectType.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum AacObjectType {
- MPEG2_LC = 0,
- MPEG4_LC = 1,
- MPEG4_LTP = 2,
- MPEG4_SCALABLE = 3,
+ MPEG2_LC,
+ MPEG4_LC,
+ MPEG4_LTP,
+ MPEG4_SCALABLE,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
index 0499b70..675f9f2 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveChannelMode.aidl
@@ -38,5 +38,5 @@
MONO = 1,
DUAL_MONO = 2,
TWS_STEREO = 4,
- UNKNOWN = 255,
+ UNKNOWN = 0xFF,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
index f702939..a18303e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxAdaptiveInputMode.aidl
@@ -34,6 +34,6 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum AptxAdaptiveInputMode {
- STEREO = 0,
- DUAL_MONO = 1,
+ STEREO = 0x00,
+ DUAL_MONO = 0x01,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
index d5dd9d9..dd8cf08 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AptxMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum AptxMode {
- UNKNOWN = 0,
- HIGH_QUALITY = 4096,
- LOW_LATENCY = 8192,
- ULTRA_LOW_LATENCY = 16384,
+ UNKNOWN = 0x00,
+ HIGH_QUALITY = 0x1000,
+ LOW_LATENCY = 0x2000,
+ ULTRA_LOW_LATENCY = 0x4000,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index 3abfb31..2c40267 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -38,4 +38,6 @@
android.hardware.bluetooth.audio.CodecConfiguration a2dpConfig;
android.hardware.bluetooth.audio.LeAudioConfiguration leAudioConfig;
android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+ android.hardware.bluetooth.audio.HfpConfiguration hfpConfig;
+ android.hardware.bluetooth.audio.A2dpStreamConfiguration a2dp;
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl
new file mode 100644
index 0000000..5aafeb7
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioContext.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable AudioContext {
+ int bitmask;
+ const int UNSPECIFIED = 0x0001;
+ const int CONVERSATIONAL = 0x0002;
+ const int MEDIA = 0x0004;
+ const int GAME = 0x0008;
+ const int INSTRUCTIONAL = 0x0010;
+ const int VOICE_ASSISTANTS = 0x0020;
+ const int LIVE_AUDIO = 0x0040;
+ const int SOUND_EFFECTS = 0x0080;
+ const int NOTIFICATIONS = 0x0100;
+ const int RINGTONE_ALERTS = 0x0200;
+ const int ALERTS = 0x0400;
+ const int EMERGENCY_ALARM = 0x0800;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
index 319a5e2..941344c 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/AudioLocation.aidl
@@ -35,6 +35,6 @@
@Backing(type="int") @VintfStability
enum AudioLocation {
UNKNOWN = 1,
- FRONT_LEFT = 2,
- FRONT_RIGHT = 4,
+ FRONT_LEFT = (1 << 1) /* 2 */,
+ FRONT_RIGHT = (1 << 2) /* 4 */,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
index feacb80..2bb5cd8 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ChannelMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum ChannelMode {
- UNKNOWN = 0,
- MONO = 1,
- STEREO = 2,
- DUALMONO = 3,
+ UNKNOWN,
+ MONO,
+ STEREO,
+ DUALMONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl
new file mode 100644
index 0000000..f3b4102
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecId.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+union CodecId {
+ android.hardware.bluetooth.audio.CodecId.A2dp a2dp = android.hardware.bluetooth.audio.CodecId.A2dp.SBC;
+ android.hardware.bluetooth.audio.CodecId.Core core;
+ android.hardware.bluetooth.audio.CodecId.Vendor vendor;
+ enum A2dp {
+ SBC = 0,
+ AAC = 2,
+ }
+ enum Core {
+ CVSD = 2,
+ MSBC = 5,
+ LC3 = 6,
+ }
+ parcelable Vendor {
+ int id;
+ int codecId;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
new file mode 100644
index 0000000..2ca9d96
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable CodecInfo {
+ android.hardware.bluetooth.audio.CodecId id;
+ String name;
+ android.hardware.bluetooth.audio.CodecInfo.Transport transport;
+ parcelable A2dp {
+ byte[] capabilities;
+ android.hardware.bluetooth.audio.ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] bitdepth;
+ boolean lossless;
+ }
+ parcelable Hfp {
+ int inputDataPath = 1;
+ int outputDataPath = 1;
+ boolean useControllerCodec = true;
+ }
+ union Transport {
+ android.hardware.bluetooth.audio.CodecInfo.A2dp a2dp;
+ android.hardware.bluetooth.audio.CodecInfo.Hfp hfp;
+ }
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl
new file mode 100644
index 0000000..60cf82a
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecParameters.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable CodecParameters {
+ android.hardware.bluetooth.audio.ChannelMode channelMode;
+ int samplingFrequencyHz;
+ int bitdepth;
+ int minBitrate;
+ int maxBitrate;
+ boolean lowLatency;
+ boolean lossless;
+ byte[] vendorSpecificParameters;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
index 3e204f9..d4f205e 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecType.aidl
@@ -34,16 +34,16 @@
package android.hardware.bluetooth.audio;
@Backing(type="int") @VintfStability
enum CodecType {
- UNKNOWN = 0,
- SBC = 1,
- AAC = 2,
- APTX = 3,
- APTX_HD = 4,
- LDAC = 5,
- LC3 = 6,
- VENDOR = 7,
- APTX_ADAPTIVE = 8,
- OPUS = 9,
- APTX_ADAPTIVE_LE = 10,
- APTX_ADAPTIVE_LEX = 11,
+ UNKNOWN,
+ SBC,
+ AAC,
+ APTX,
+ APTX_HD,
+ LDAC,
+ LC3,
+ VENDOR,
+ APTX_ADAPTIVE,
+ OPUS,
+ APTX_ADAPTIVE_LE,
+ APTX_ADAPTIVE_LEX,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl
new file mode 100644
index 0000000..490a05d
--- /dev/null
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/HfpConfiguration.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.audio;
+@VintfStability
+parcelable HfpConfiguration {
+ android.hardware.bluetooth.audio.CodecId codecId;
+ int connectionHandle;
+ boolean nrec;
+ boolean controllerCodec;
+}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 267af0f..ccf5524 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -40,4 +40,6 @@
void streamSuspended(in android.hardware.bluetooth.audio.BluetoothAudioStatus status);
void updateAudioConfiguration(in android.hardware.bluetooth.audio.AudioConfiguration audioConfig);
void setLowLatencyModeAllowed(in boolean allowed);
+ android.hardware.bluetooth.audio.A2dpStatus parseA2dpConfiguration(in android.hardware.bluetooth.audio.CodecId codecId, in byte[] configuration, out android.hardware.bluetooth.audio.CodecParameters codecParameters);
+ @nullable android.hardware.bluetooth.audio.A2dpConfiguration getA2dpConfiguration(in List<android.hardware.bluetooth.audio.A2dpRemoteCapabilities> remoteA2dpCapabilities, in android.hardware.bluetooth.audio.A2dpConfigurationHint hint);
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index 5e33deb..c806b0a 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -36,4 +36,10 @@
interface IBluetoothAudioProviderFactory {
android.hardware.bluetooth.audio.AudioCapabilities[] getProviderCapabilities(in android.hardware.bluetooth.audio.SessionType sessionType);
android.hardware.bluetooth.audio.IBluetoothAudioProvider openProvider(in android.hardware.bluetooth.audio.SessionType sessionType);
+ @nullable android.hardware.bluetooth.audio.IBluetoothAudioProviderFactory.ProviderInfo getProviderInfo(in android.hardware.bluetooth.audio.SessionType sessionType);
+ @VintfStability
+ parcelable ProviderInfo {
+ String name;
+ android.hardware.bluetooth.audio.CodecInfo[] codecInfos;
+ }
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
index 88d6faf..3d80c4b 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacChannelMode.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum LdacChannelMode {
- UNKNOWN = 0,
- STEREO = 1,
- DUAL = 2,
- MONO = 3,
+ UNKNOWN,
+ STEREO,
+ DUAL,
+ MONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
index 35e4358..a332dc5 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LdacQualityIndex.aidl
@@ -34,8 +34,8 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum LdacQualityIndex {
- HIGH = 0,
- MID = 1,
- LOW = 2,
- ABR = 3,
+ HIGH,
+ MID,
+ LOW,
+ ABR,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
index 091f6d7..9cf65d5 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcAllocMethod.aidl
@@ -34,6 +34,6 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SbcAllocMethod {
- ALLOC_MD_S = 0,
- ALLOC_MD_L = 1,
+ ALLOC_MD_S,
+ ALLOC_MD_L,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
index 6441a99..7779aa0 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SbcChannelMode.aidl
@@ -34,9 +34,9 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SbcChannelMode {
- UNKNOWN = 0,
- JOINT_STEREO = 1,
- STEREO = 2,
- DUAL = 3,
- MONO = 4,
+ UNKNOWN,
+ JOINT_STEREO,
+ STEREO,
+ DUAL,
+ MONO,
}
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
index 33a3187..71cca53 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/SessionType.aidl
@@ -34,16 +34,19 @@
package android.hardware.bluetooth.audio;
@Backing(type="byte") @VintfStability
enum SessionType {
- UNKNOWN = 0,
- A2DP_SOFTWARE_ENCODING_DATAPATH = 1,
- A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 2,
- HEARING_AID_SOFTWARE_ENCODING_DATAPATH = 3,
- LE_AUDIO_SOFTWARE_ENCODING_DATAPATH = 4,
- LE_AUDIO_SOFTWARE_DECODING_DATAPATH = 5,
- LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 6,
- LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH = 7,
- LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH = 8,
- LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH = 9,
- A2DP_SOFTWARE_DECODING_DATAPATH = 10,
- A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH = 11,
+ UNKNOWN,
+ A2DP_SOFTWARE_ENCODING_DATAPATH,
+ A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ A2DP_SOFTWARE_DECODING_DATAPATH,
+ A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ HFP_SOFTWARE_ENCODING_DATAPATH,
+ HFP_SOFTWARE_DECODING_DATAPATH,
+ HFP_HARDWARE_OFFLOAD_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
new file mode 100644
index 0000000..a7fd9ff
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+
+/**
+ * A2DP Service Configuration
+ */
+@VintfStability
+parcelable A2dpConfiguration {
+ /**
+ * Remote Stream Endpoint Identifier
+ */
+ int remoteSeid;
+
+ /**
+ * Codec Selection and configuration, in a generic way with `parameters`
+ * and as defined by A2DP for codec interoperability requirements, with
+ * `configuration`. Using `id.a2dp`, the format is given by the `Codec
+ * Specific Information Elements` [A2DP - 4.3-6.2], and using `id.vendor`,
+ * by `Vendor Specific Value` [A2DP - 4.7.2].
+ * In any case, this byte array is limited by the framework to 128 Bytes.
+ */
+ CodecId id;
+ CodecParameters parameters;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
new file mode 100644
index 0000000..f707a8a
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpConfigurationHint.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.AudioContext;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
+
+/**
+ * A2DP Configuration Hints
+ */
+@VintfStability
+parcelable A2dpConfigurationHint {
+ /**
+ * Bluetooth Device Address, intended to be used for interoperabilities.
+ */
+ byte[6] bdAddr;
+
+ /**
+ * Audio configuration hints:
+ * - The starting audio context of the session
+ * - An optional preference of codec and / or parameters
+ */
+
+ AudioContext audioContext;
+ @nullable CodecId codecId;
+ @nullable CodecParameters codecParameters;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
new file mode 100644
index 0000000..87277f1
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpRemoteCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+/**
+ * A2DP Remote Capabilites
+ */
+@VintfStability
+parcelable A2dpRemoteCapabilities {
+ /**
+ * Remote Stream Endpoint identifier
+ */
+ int seid;
+
+ /**
+ * Codec Identifier and `capabilities` as defined by A2DP for codec
+ * interoperability requirements. Using `id.a2dp`, the format is given
+ * by the `Codec Specific Information Elements` [A2DP - 4.3-6.2], and
+ * using `id.vendor`, by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ CodecId id;
+ byte[] capabilities;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl
new file mode 100644
index 0000000..8eba3c9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStatus.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+@Backing(type="byte")
+enum A2dpStatus {
+
+ OK = 0,
+
+ /**
+ * Error codes defined by AVDTP [AVDTP - 8.20.6.2]
+ */
+
+ BAD_LENGTH = 0x11u8,
+ BAD_PAYLOAD_FORMAT = 0x18u8,
+
+ /**
+ * Error codecs defined by A2DP for AVDTP Interoperability [A2DP - 5.1.3]
+ */
+
+ INVALID_CODEC_TYPE = 0xC1u8,
+ NOT_SUPPORTED_CODEC_TYPE = 0xC2u8,
+ INVALID_SAMPLING_FREQUENCY = 0xC3u8,
+ NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xC4u8,
+ INVALID_CHANNEL_MODE = 0xC5u8,
+ NOT_SUPPORTED_CHANNEL_MODE = 0xC6u8,
+ INVALID_SUBBANDS = 0xC7u8,
+ NOT_SUPPORTED_SUBBANDS = 0xC8u8,
+ INVALID_ALLOCATION_METHOD = 0xC9u8,
+ NOT_SUPPORTED_ALLOCATION_METHOD = 0xCAu8,
+ INVALID_MINIMUM_BITPOOL_VALUE = 0xCBu8,
+ NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xCCu8,
+ INVALID_MAXIMUM_BITPOOL_VALUE = 0xCDu8,
+ NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xCEu8,
+ NOT_SUPPORTED_VBR = 0xD3u8,
+ NOT_SUPPORTED_BIT_RATE = 0xD5u8,
+ INVALID_OBJECT_TYPE = 0xD6u8,
+ NOT_SUPPORTED_OBJECT_TYPE = 0xD7u8,
+ INVALID_CHANNELS = 0xD8u8,
+ NOT_SUPPORTED_CHANNELS = 0xD9u8,
+ INVALID_BLOCK_LENGTH = 0xDDu8,
+ INVALID_CODEC_PARAMETER = 0xE2u8,
+ NOT_SUPPORTED_CODEC_PARAMETER = 0xE3u8,
+ INVALID_DRC = 0xE4u8,
+ NOT_SUPPORTED_DRC = 0xE5u8,
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
new file mode 100644
index 0000000..2a0c4d8
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/A2dpStreamConfiguration.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+@VintfStability
+parcelable A2dpStreamConfiguration {
+ /**
+ * Peer MTU (16 bits)
+ */
+ int peerMtu;
+
+ /**
+ * Optional SCMS-T Content Protection header
+ * that precedes audio content when enabled [A2DP - 3.2.1-2].
+ * The content protection byte is defined by [Assigned Number - 6.3.2].
+ */
+ @nullable byte[1] cpHeaderScmst;
+
+ /**
+ * Codec Identifier and `configuration` as defined by A2DP for codec
+ * interoperability requirements. Using `codecId.a2dp`, the format is given
+ * by the `Codec Specific Information Elements` [A2DP - 4.3-6.2], and
+ * using `codecId.vendor`, by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ CodecId codecId;
+ byte[] configuration;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
index a06337e..5317dfb 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioConfiguration.aidl
@@ -16,7 +16,9 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.A2dpStreamConfiguration;
import android.hardware.bluetooth.audio.CodecConfiguration;
+import android.hardware.bluetooth.audio.HfpConfiguration;
import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration;
import android.hardware.bluetooth.audio.LeAudioConfiguration;
import android.hardware.bluetooth.audio.PcmConfiguration;
@@ -30,4 +32,6 @@
CodecConfiguration a2dpConfig;
LeAudioConfiguration leAudioConfig;
LeAudioBroadcastConfiguration leAudioBroadcastConfig;
+ HfpConfiguration hfpConfig;
+ A2dpStreamConfiguration a2dp;
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl
new file mode 100644
index 0000000..306e897
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/AudioContext.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+/**
+ * Context of the audio configuration.
+ * Defined by PACS (Le Audio) and used either by A2DP or LE Audio.
+ * The `bitmask` is any combination of BT Sig standardized values
+ * [Assigned Numbers - 6.12.3], defined in this scope.
+ */
+@VintfStability
+parcelable AudioContext {
+ const int UNSPECIFIED = 0x0001;
+ const int CONVERSATIONAL = 0x0002;
+ const int MEDIA = 0x0004;
+ const int GAME = 0x0008;
+ const int INSTRUCTIONAL = 0x0010;
+ const int VOICE_ASSISTANTS = 0x0020;
+ const int LIVE_AUDIO = 0x0040;
+ const int SOUND_EFFECTS = 0x0080;
+ const int NOTIFICATIONS = 0x0100;
+ const int RINGTONE_ALERTS = 0x0200;
+ const int ALERTS = 0x0400;
+ const int EMERGENCY_ALARM = 0x0800;
+
+ int bitmask;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl
new file mode 100644
index 0000000..896a712
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecId.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+@VintfStability
+union CodecId {
+ /**
+ * Codec Identifier defined for A2DP
+ * The values are assigned by BT Sig [Assigned Numbers - 6.5.1]
+ */
+ enum A2dp { SBC = 0, AAC = 2 }
+
+ /**
+ * Codec Identifier defined for the Bluetooth Core Specification
+ * The values are assigned by BT Sig [Assigned Numbers - 2.11]
+ */
+ enum Core { CVSD = 2, MSBC = 5, LC3 = 6 }
+
+ /**
+ * Vendor Codec:
+ * id 16 bits - Assigned by BT Sig
+ * codecId 16 bits - Assigned by the vendor
+ */
+ parcelable Vendor {
+ int id;
+ int codecId;
+ }
+
+ /**
+ * Standard (A2DP or Core numbering space) or vendor
+ */
+ A2dp a2dp = A2dp.SBC;
+ Core core;
+ Vendor vendor;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
new file mode 100644
index 0000000..127cd7c
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+import android.hardware.bluetooth.audio.CodecId;
+
+/**
+ * General information about a Codec
+ */
+@VintfStability
+parcelable CodecInfo {
+ /**
+ * Codec identifier and human readable name
+ */
+ CodecId id;
+ String name;
+
+ /**
+ * A2DP Context
+ */
+ parcelable A2dp {
+ /**
+ * The capabilities as defined by A2DP for codec interoperability
+ * requirements. With `id.a2dp`, the format is given by the `Codec
+ * Specific Information Elements` [A2DP - 4.3-6.2], and with `id.vendor`,
+ * by `Vendor Specific Value` [A2DP - 4.7.2].
+ */
+ byte[] capabilities;
+
+ /**
+ * PCM characteristics:
+ * - Mono, Dual-Mono or Stereo
+ * - Supported sampling frequencies, in Hz.
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation.
+ *
+ * When the bitdepth is not an encoding/decoding parameter (don't take part
+ * in the interoperability), the `bitdepth` list shall have a single element
+ * indicating the bitdepth selected for the platform.
+ */
+ ChannelMode[] channelMode;
+ int[] samplingFrequencyHz;
+ int[] bitdepth;
+
+ /**
+ * Lossless capable characteristic
+ */
+ boolean lossless;
+ }
+
+ /**
+ * HFP Context
+ */
+ parcelable Hfp {
+ /**
+ * Vendor-specific identifiers of stream data paths, set in the
+ * HCI Command Enhanced Setup Synchronous Connection [Core - 4.E.7.1.45],
+ * in the command parameters respectively `Input_Data_Path` and
+ * `Output_Data_Path`. The value range from 0x01 to 0xFE.
+ * The stack operates as a pass-through; the client SHALL NOT
+ * interpret the values.
+ */
+ int inputDataPath = 1;
+ int outputDataPath = 1;
+
+ /**
+ * Whether the audio stream is encoded and decoded in the controller or
+ * locally; enable the controller transparent mode when the audio
+ * stream is locally processed.
+ */
+ boolean useControllerCodec = true;
+ }
+
+ /**
+ * Specific informations,
+ * depending on transport.
+ */
+ union Transport {
+ A2dp a2dp;
+ Hfp hfp;
+ }
+
+ Transport transport;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl
new file mode 100644
index 0000000..b6f8a94
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecParameters.aidl
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.ChannelMode;
+
+/**
+ * Used to exchange generic codec parameters between the stack and the provider.
+ */
+@VintfStability
+parcelable CodecParameters {
+ /**
+ * PCM related parameters:
+ * - Mono, Dual-Mono or Stereo
+ * - Sampling frequencies, in Hz.
+ * - Fixed point resolution, basically 16, 24 or 32 bits by samples.
+ * The value 32 should be used for floating point representation..
+ */
+ ChannelMode channelMode;
+ int samplingFrequencyHz;
+ int bitdepth;
+
+ /**
+ * Encoding parameters:
+ *
+ * - Bitrate limits on a frame basis, defined in bits per second.
+ * The encoder bitrate mode can be encoded following this rule:
+ * . minBitrate equals to maxBitrate for constant bitrate
+ * . minBitrate set to 0, for VBR with peak bitrate at maxBitratre value.
+ * . minBitrate greater than 0, for ABR, the bitrate of the stream varies
+ * between minBitrate to maxBitrate according to link quality.
+ * The 0 value for both means "undefined" or "don't care".
+ *
+ * - Low-latency configuration privileged
+ * - Lossless effort indication. The 'False' value can be used as "don't care"
+ */
+ int minBitrate;
+ int maxBitrate;
+
+ boolean lowLatency;
+ boolean lossless;
+
+ /**
+ * Vendor specific parameters, inserted in the Vendor Specific HCI Command
+ * `Start A2DP Offload` as it is. The stack operates as a pass-through;
+ * the data SHALL NOT be inspected nor written by the client.
+ * The size is limited to 128 bytes by the client; a larger size is
+ * interpreted as a zero-sized buffer.
+ */
+ byte[] vendorSpecificParameters;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl
new file mode 100644
index 0000000..9494bb9
--- /dev/null
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/HfpConfiguration.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.audio;
+
+import android.hardware.bluetooth.audio.CodecId;
+
+@VintfStability
+parcelable HfpConfiguration {
+ /**
+ * Codec identifier.
+ */
+ CodecId codecId;
+
+ /**
+ * The connection handle used for SCO connection.
+ * Range: 0x0000 to 0x0EFF.
+ */
+ int connectionHandle;
+
+ /**
+ * Echo canceling and noise reduction functions resident in the AG.
+ */
+ boolean nrec;
+
+ /**
+ * Indicate whether the codec is encoded and decoded in the controller.
+ * If the codec is inside the DSP, then it would be transparent mode.
+ */
+ boolean controllerCodec;
+}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index d5c051e..b5c8a31 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -16,8 +16,14 @@
package android.hardware.bluetooth.audio;
+import android.hardware.bluetooth.audio.A2dpConfiguration;
+import android.hardware.bluetooth.audio.A2dpConfigurationHint;
+import android.hardware.bluetooth.audio.A2dpRemoteCapabilities;
+import android.hardware.bluetooth.audio.A2dpStatus;
import android.hardware.bluetooth.audio.AudioConfiguration;
import android.hardware.bluetooth.audio.BluetoothAudioStatus;
+import android.hardware.bluetooth.audio.CodecId;
+import android.hardware.bluetooth.audio.CodecParameters;
import android.hardware.bluetooth.audio.IBluetoothAudioPort;
import android.hardware.bluetooth.audio.LatencyMode;
import android.hardware.common.fmq.MQDescriptor;
@@ -59,9 +65,8 @@
* audioConfig.pcmConfig parameter. Invalid if streaming is offloaded
* from/to hardware or on failure
*/
- MQDescriptor<byte, SynchronizedReadWrite> startSession(
- in IBluetoothAudioPort hostIf, in AudioConfiguration audioConfig,
- in LatencyMode[] supportedLatencyModes);
+ MQDescriptor<byte, SynchronizedReadWrite> startSession(in IBluetoothAudioPort hostIf,
+ in AudioConfiguration audioConfig, in LatencyMode[] supportedLatencyModes);
/**
* Callback for IBluetoothAudioPort.startStream()
*
@@ -93,4 +98,30 @@
* mode, the API will be called with supported is false.
*/
void setLowLatencyModeAllowed(in boolean allowed);
+
+ /**
+ * Validate and parse an A2DP Configuration,
+ * shall be used with A2DP session types
+ *
+ * @param codecId Identify the codec
+ * @param The configuration as defined by the A2DP's `Codec Specific
+ * Information Elements`, or `Vendor Specific Value` when CodecId
+ * format is set to `VENDOR`.
+ * @param codecParameters result of parsing, when the validation succeeded.
+ * @return A2DP Status of the parsing
+ */
+ A2dpStatus parseA2dpConfiguration(
+ in CodecId codecId, in byte[] configuration, out CodecParameters codecParameters);
+
+ /**
+ * Return a configuration, from a list of remote Capabilites,
+ * shall be used with A2DP session types
+ *
+ * @param remoteCapabilities The capabilities of the remote device
+ * @param hint Hint on selection (audio context and/or codec)
+ * @return The requested configuration. A null value value is returned
+ * when no suitable configuration has been found.
+ */
+ @nullable A2dpConfiguration getA2dpConfiguration(
+ in List<A2dpRemoteCapabilities> remoteA2dpCapabilities, in A2dpConfigurationHint hint);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
index 3cde22c..b9cec2d 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl
@@ -17,8 +17,10 @@
package android.hardware.bluetooth.audio;
import android.hardware.bluetooth.audio.AudioCapabilities;
+import android.hardware.bluetooth.audio.CodecInfo;
import android.hardware.bluetooth.audio.IBluetoothAudioProvider;
import android.hardware.bluetooth.audio.SessionType;
+
/**
* This factory allows a HAL implementation to be split into multiple
* independent providers.
@@ -62,4 +64,24 @@
* @return provider The provider of the specified session type
*/
IBluetoothAudioProvider openProvider(in SessionType sessionType);
+
+ /**
+ * General information relative to a provider
+ * - An optional name
+ * - A list of codec information
+ */
+ @VintfStability
+ parcelable ProviderInfo {
+ String name;
+ CodecInfo[] codecInfos;
+ }
+
+ /**
+ * Get general information relative to a provider.
+ *
+ * @param sessionType Hardware Offload provider (*_HARDWARE_OFFLOAD_*)
+ * @return General information relative to the provider.
+ * The `null` value can be returned when the provider is not available
+ */
+ @nullable ProviderInfo getProviderInfo(in SessionType sessionType);
}
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
index 7acb5c6..35292a1 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/SessionType.aidl
@@ -70,4 +70,17 @@
* The decoding of AVDTP media is done by HW and there is control only
*/
A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ /**
+ * Used when audio is encoded by Bluetooth Stack and is streaming to HFP device.
+ */
+ HFP_SOFTWARE_ENCODING_DATAPATH,
+ /**
+ * Used when audio is decoded by Bluetooth Stack and is streaming to HFP device.
+ */
+ HFP_SOFTWARE_DECODING_DATAPATH,
+ /**
+ * Used when encoded and decoded by hardware offload and is streamed to HFP device.
+ * This is a control path only.
+ */
+ HFP_HARDWARE_OFFLOAD_DATAPATH,
}
diff --git a/bluetooth/audio/aidl/default/A2dpBits.h b/bluetooth/audio/aidl/default/A2dpBits.h
new file mode 100644
index 0000000..f467c95
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpBits.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpBits {
+ const uint8_t* cdata_;
+ uint8_t* data_;
+
+ public:
+ A2dpBits(const std::vector<uint8_t>& vector) : cdata_(vector.data()) {}
+
+ A2dpBits(std::vector<uint8_t>& vector)
+ : cdata_(vector.data()), data_(vector.data()) {}
+
+ struct Range {
+ const int first, len;
+ constexpr Range(int first, int last)
+ : first(first), len(last - first + 1) {}
+ constexpr Range(int index) : first(index), len(1) {}
+ };
+
+ constexpr bool get(int bit) const {
+ return (cdata_[bit >> 3] >> (7 - (bit & 7))) & 1;
+ }
+
+ constexpr unsigned get(const Range& range) const {
+ unsigned v(0);
+ for (int i = 0; i < range.len; i++)
+ v |= get(range.first + i) << ((range.len - 1) - i);
+ return v;
+ }
+
+ constexpr void set(int bit, int value = 1) {
+ uint8_t m = 1 << (7 - (bit & 7));
+ if (value)
+ data_[bit >> 3] |= m;
+ else
+ data_[bit >> 3] &= ~m;
+ }
+
+ constexpr void set(const Range& range, int value) {
+ for (int i = 0; i < range.len; i++)
+ set(range.first + i, (value >> ((range.len - 1) - i)) & 1);
+ }
+
+ constexpr int find_active_bit(const Range& range) const {
+ unsigned v = get(range);
+ int i = 0;
+ for (; i < range.len && ((v >> i) & 1) == 0; i++)
+ ;
+ return i < range.len && (v ^ (1 << i)) == 0
+ ? range.first + (range.len - 1) - i
+ : -1;
+ }
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
index 2d0d8c9..ba7a89d 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.cpp
@@ -22,6 +22,10 @@
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
+#include "A2dpOffloadCodecAac.h"
+#include "A2dpOffloadCodecFactory.h"
+#include "A2dpOffloadCodecSbc.h"
+
namespace aidl {
namespace android {
namespace hardware {
@@ -48,19 +52,44 @@
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
- if (audio_config.getTag() != AudioConfiguration::a2dpConfig) {
+ if (audio_config.getTag() == AudioConfiguration::Tag::a2dp) {
+ auto a2dp_config = audio_config.get<AudioConfiguration::Tag::a2dp>();
+ A2dpStatus a2dp_status = A2dpStatus::NOT_SUPPORTED_CODEC_TYPE;
+
+ if (a2dp_config.codecId ==
+ A2dpOffloadCodecSbc::GetInstance()->GetCodecId()) {
+ SbcParameters sbc_parameters;
+ a2dp_status = A2dpOffloadCodecSbc::GetInstance()->ParseConfiguration(
+ a2dp_config.configuration, &sbc_parameters);
+
+ } else if (a2dp_config.codecId ==
+ A2dpOffloadCodecAac::GetInstance()->GetCodecId()) {
+ AacParameters aac_parameters;
+ a2dp_status = A2dpOffloadCodecAac::GetInstance()->ParseConfiguration(
+ a2dp_config.configuration, &aac_parameters);
+ }
+ if (a2dp_status != A2dpStatus::OK) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else if (audio_config.getTag() == AudioConfiguration::Tag::a2dpConfig) {
+ if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
+ session_type_,
+ audio_config.get<AudioConfiguration::a2dpConfig>())) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ } else {
LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
<< audio_config.toString();
*_aidl_return = DataMQDesc();
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
- if (!BluetoothAudioCodecs::IsOffloadCodecConfigurationValid(
- session_type_, audio_config.get<AudioConfiguration::a2dpConfig>())) {
- LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
- << audio_config.toString();
- *_aidl_return = DataMQDesc();
- return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
- }
+
return BluetoothAudioProvider::startSession(
host_if, audio_config, latency_modes, _aidl_return);
}
@@ -73,6 +102,36 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus A2dpOffloadAudioProvider::parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return) {
+ auto codec = A2dpOffloadCodecFactory::GetInstance()->GetCodec(codec_id);
+ if (!codec) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " - CodecId=" << codec_id.toString() << " is not found";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ *_aidl_return = codec->ParseConfiguration(configuration, codec_parameters);
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus A2dpOffloadAudioProvider::getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return) {
+ *_aidl_return = std::nullopt;
+ A2dpConfiguration avdtp_configuration;
+
+ if (A2dpOffloadCodecFactory::GetInstance()->GetConfiguration(
+ remote_a2dp_capabilities, hint, &avdtp_configuration))
+ *_aidl_return =
+ std::make_optional<A2dpConfiguration>(std::move(avdtp_configuration));
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
index e6f188b..7cc6dee 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/A2dpOffloadAudioProvider.h
@@ -34,7 +34,16 @@
const std::shared_ptr<IBluetoothAudioPort>& host_if,
const AudioConfiguration& audio_config,
const std::vector<LatencyMode>& latency_modes,
- DataMQDesc* _aidl_return);
+ DataMQDesc* _aidl_return) override;
+
+ ndk::ScopedAStatus parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return) override;
+
+ ndk::ScopedAStatus getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return) override;
private:
ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodec.h b/bluetooth/audio/aidl/default/A2dpOffloadCodec.h
new file mode 100644
index 0000000..7ed5872
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodec.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/bluetooth/audio/A2dpStatus.h>
+#include <aidl/android/hardware/bluetooth/audio/ChannelMode.h>
+#include <aidl/android/hardware/bluetooth/audio/CodecParameters.h>
+
+#include "BluetoothAudioProviderFactory.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpOffloadCodec {
+ protected:
+ A2dpOffloadCodec(const CodecInfo& info) : info(info) {}
+ virtual ~A2dpOffloadCodec() {}
+
+ public:
+ const CodecInfo& info;
+
+ const CodecId& GetCodecId() const { return info.id; }
+
+ virtual A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const = 0;
+
+ virtual bool BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const = 0;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp
new file mode 100644
index 0000000..0f5533a
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.cpp
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecAac.h"
+
+#include "A2dpBits.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * AAC Local Capabilities
+ */
+
+enum : bool {
+ kEnableObjectTypeMpeg2AacLc = true,
+ kEnableObjectTypeMpeg4AacLc = true,
+};
+
+enum : bool {
+ kEnableSamplingFrequency44100 = true,
+ kEnableSamplingFrequency48000 = true,
+ kEnableSamplingFrequency88200 = false,
+ kEnableSamplingFrequency96000 = false,
+};
+
+enum : bool {
+ kEnableChannels1 = true,
+ kEnableChannels2 = true,
+};
+
+enum : bool {
+ kEnableVbrSupported = true,
+};
+
+enum : int {
+ kBitdepth = 24,
+};
+
+/**
+ * AAC Signaling format [A2DP - 4.5]
+ */
+
+// clang-format off
+
+constexpr A2dpBits::Range kObjectType ( 0, 6 );
+constexpr A2dpBits::Range kDrcEnable ( 7 );
+constexpr A2dpBits::Range kSamplingFrequency ( 8, 19 );
+constexpr A2dpBits::Range kChannels ( 20, 23 );
+constexpr A2dpBits::Range kVbrSupported ( 24 );
+constexpr A2dpBits::Range kBitrate ( 25, 47 );
+constexpr size_t kCapabilitiesSize = 48/8;
+
+// clang-format on
+
+enum {
+ kObjectTypeMpeg2AacLc = kObjectType.first,
+ kObjectTypeMpeg4AacLc,
+ kObjectTypeMpeg4AacLtp,
+ kObjectTypeMpeg4AacScalable,
+ kObjectTypeMpeg4AacHeV1,
+ kObjectTypeMpeg4AacHeV2,
+ kObjectTypeMpeg4AacEldV2
+};
+
+enum {
+ kSamplingFrequency8000 = kSamplingFrequency.first,
+ kSamplingFrequency11025,
+ kSamplingFrequency12000,
+ kSamplingFrequency16000,
+ kSamplingFrequency22050,
+ kSamplingFrequency24000,
+ kSamplingFrequency32000,
+ kSamplingFrequency44100,
+ kSamplingFrequency48000,
+ kSamplingFrequency64000,
+ kSamplingFrequency88200,
+ kSamplingFrequency96000
+};
+
+enum { kChannels1 = kChannels.first, kChannels2, kChannels51, kChannels71 };
+
+/**
+ * AAC Conversion functions
+ */
+
+static AacParameters::ObjectType GetObjectTypeEnum(int object_type) {
+ switch (object_type) {
+ case kObjectTypeMpeg2AacLc:
+ return AacParameters::ObjectType::MPEG2_AAC_LC;
+ case kObjectTypeMpeg4AacLc:
+ default:
+ return AacParameters::ObjectType::MPEG4_AAC_LC;
+ }
+}
+
+static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
+ switch (sampling_frequency) {
+ case 8000:
+ return kSamplingFrequency8000;
+ case 11025:
+ return kSamplingFrequency11025;
+ case 12000:
+ return kSamplingFrequency12000;
+ case 16000:
+ return kSamplingFrequency16000;
+ case 22050:
+ return kSamplingFrequency22050;
+ case 24000:
+ return kSamplingFrequency24000;
+ case 32000:
+ return kSamplingFrequency32000;
+ case 44100:
+ return kSamplingFrequency44100;
+ case 48000:
+ return kSamplingFrequency48000;
+ case 64000:
+ return kSamplingFrequency64000;
+ case 88200:
+ return kSamplingFrequency88200;
+ case 96000:
+ return kSamplingFrequency96000;
+ default:
+ return -1;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
+ switch (sampling_frequency) {
+ case kSamplingFrequency8000:
+ return 8000;
+ case kSamplingFrequency11025:
+ return 11025;
+ case kSamplingFrequency12000:
+ return 12000;
+ case kSamplingFrequency16000:
+ return 16000;
+ case kSamplingFrequency22050:
+ return 22050;
+ case kSamplingFrequency24000:
+ return 24000;
+ case kSamplingFrequency32000:
+ return 32000;
+ case kSamplingFrequency44100:
+ return 44100;
+ case kSamplingFrequency48000:
+ return 48000;
+ case kSamplingFrequency64000:
+ return 64000;
+ case kSamplingFrequency88200:
+ return 88200;
+ case kSamplingFrequency96000:
+ return 96000;
+ default:
+ return 0;
+ }
+}
+
+static int GetChannelsBit(ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::MONO:
+ return kChannels1;
+ case ChannelMode::STEREO:
+ return kChannels2;
+ default:
+ return -1;
+ }
+}
+
+static ChannelMode GetChannelModeEnum(int channel_mode) {
+ switch (channel_mode) {
+ case kChannels1:
+ return ChannelMode::MONO;
+ case kChannels2:
+ return ChannelMode::STEREO;
+ default:
+ return ChannelMode::UNKNOWN;
+ }
+}
+
+/**
+ * AAC Class implementation
+ */
+
+const A2dpOffloadCodecAac* A2dpOffloadCodecAac::GetInstance() {
+ static A2dpOffloadCodecAac instance;
+ return &instance;
+}
+
+A2dpOffloadCodecAac::A2dpOffloadCodecAac()
+ : A2dpOffloadCodec(info_),
+ info_({.id = CodecId(CodecId::A2dp::AAC), .name = "AAC"}) {
+ info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ /* --- Setup Capabilities --- */
+
+ a2dp_info.capabilities.resize(kCapabilitiesSize);
+ std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
+
+ auto capabilities = A2dpBits(a2dp_info.capabilities);
+
+ capabilities.set(kObjectTypeMpeg2AacLc, kEnableObjectTypeMpeg2AacLc);
+ capabilities.set(kObjectTypeMpeg4AacLc, kEnableObjectTypeMpeg4AacLc);
+
+ capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
+ capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
+ capabilities.set(kSamplingFrequency88200, kEnableSamplingFrequency88200);
+ capabilities.set(kSamplingFrequency96000, kEnableSamplingFrequency96000);
+
+ capabilities.set(kChannels1, kEnableChannels1);
+ capabilities.set(kChannels2, kEnableChannels2);
+
+ capabilities.set(kVbrSupported, kEnableVbrSupported);
+
+ /* --- Setup Sampling Frequencies --- */
+
+ auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
+
+ for (auto v : {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
+ 64000, 88200, 96000})
+ if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
+ sampling_frequency.push_back(v);
+
+ /* --- Setup Channel Modes --- */
+
+ auto& channel_modes = a2dp_info.channelMode;
+
+ for (auto v : {ChannelMode::MONO, ChannelMode::STEREO})
+ if (capabilities.get(GetChannelsBit(v))) channel_modes.push_back(v);
+
+ /* --- Setup Bitdepth --- */
+
+ a2dp_info.bitdepth.push_back(kBitdepth);
+}
+
+A2dpStatus A2dpOffloadCodecAac::ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, AacParameters* aac_parameters) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (configuration.size() != a2dp_info.capabilities.size())
+ return A2dpStatus::BAD_LENGTH;
+
+ auto config = A2dpBits(configuration);
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+
+ /* --- Check Object Type --- */
+
+ int object_type = config.find_active_bit(kObjectType);
+ if (object_type < 0) return A2dpStatus::INVALID_OBJECT_TYPE;
+ if (!lcaps.get(object_type)) return A2dpStatus::NOT_SUPPORTED_OBJECT_TYPE;
+
+ /* --- Check Sampling Frequency --- */
+
+ int sampling_frequency = config.find_active_bit(kSamplingFrequency);
+ if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
+ if (!lcaps.get(sampling_frequency))
+ return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
+
+ /* --- Check Channels --- */
+
+ int channels = config.find_active_bit(kChannels);
+ if (channels < 0) return A2dpStatus::INVALID_CHANNELS;
+ if (!lcaps.get(channels)) return A2dpStatus::NOT_SUPPORTED_CHANNELS;
+
+ /* --- Check Bitrate --- */
+
+ bool vbr = config.get(kVbrSupported);
+ if (vbr && !lcaps.get(kVbrSupported)) return A2dpStatus::NOT_SUPPORTED_VBR;
+
+ int bitrate = config.get(kBitrate);
+ if (vbr && lcaps.get(kBitrate) && bitrate > lcaps.get(kBitrate))
+ return A2dpStatus::NOT_SUPPORTED_BIT_RATE;
+
+ /* --- Return --- */
+
+ codec_parameters->channelMode = GetChannelModeEnum(channels);
+ codec_parameters->samplingFrequencyHz =
+ GetSamplingFrequencyValue(sampling_frequency);
+ codec_parameters->bitdepth = kBitdepth;
+
+ codec_parameters->minBitrate = vbr ? 0 : bitrate;
+ codec_parameters->maxBitrate = bitrate;
+
+ if (aac_parameters)
+ aac_parameters->object_type = GetObjectTypeEnum(object_type);
+
+ return A2dpStatus::OK;
+}
+
+bool A2dpOffloadCodecAac::BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const {
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
+
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+ auto rcaps = A2dpBits(remote_capabilities);
+
+ configuration->resize(a2dp_info.capabilities.size());
+ std::fill(begin(*configuration), end(*configuration), 0);
+ auto config = A2dpBits(*configuration);
+
+ /* --- Select Object Type --- */
+
+ if (lcaps.get(kObjectTypeMpeg2AacLc) && rcaps.get(kObjectTypeMpeg2AacLc))
+ config.set(kObjectTypeMpeg2AacLc);
+ else if (lcaps.get(kObjectTypeMpeg4AacLc) && rcaps.get(kObjectTypeMpeg4AacLc))
+ config.set(kObjectTypeMpeg4AacLc);
+ else
+ return false;
+
+ /* --- Select Sampling Frequency --- */
+
+ auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
+
+ if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
+ config.set(sf_hint);
+ else if (lcaps.get(kSamplingFrequency96000) &&
+ rcaps.get(kSamplingFrequency96000))
+ config.set(kSamplingFrequency96000);
+ else if (lcaps.get(kSamplingFrequency88200) &&
+ rcaps.get(kSamplingFrequency88200))
+ config.set(kSamplingFrequency88200);
+ else if (lcaps.get(kSamplingFrequency48000) &&
+ rcaps.get(kSamplingFrequency48000))
+ config.set(kSamplingFrequency48000);
+ else if (lcaps.get(kSamplingFrequency44100) &&
+ rcaps.get(kSamplingFrequency44100))
+ config.set(kSamplingFrequency44100);
+ else
+ return false;
+
+ /* --- Select Channels --- */
+
+ auto ch_hint = hint ? GetChannelsBit(hint->channelMode) : -1;
+
+ if (ch_hint >= 0 && lcaps.get(ch_hint) && rcaps.get(ch_hint))
+ config.set(ch_hint);
+ else if (lcaps.get(kChannels2) && rcaps.get(kChannels2))
+ config.set(kChannels2);
+ else if (lcaps.get(kChannels1) && rcaps.get(kChannels1))
+ config.set(kChannels1);
+ else
+ return false;
+
+ /* --- Select Bitrate --- */
+
+ if (!hint || hint->minBitrate == 0)
+ config.set(kVbrSupported,
+ lcaps.get(kVbrSupported) && rcaps.get(kVbrSupported));
+
+ int32_t bitrate = lcaps.get(kBitrate);
+ if (hint && hint->maxBitrate > 0 && bitrate)
+ bitrate = std::min(hint->maxBitrate, bitrate);
+ else if (hint && hint->maxBitrate > 0)
+ bitrate = hint->maxBitrate;
+ config.set(kBitrate, bitrate);
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h
new file mode 100644
index 0000000..eefa89b
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecAac.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+struct AacParameters : public CodecParameters {
+ enum class ObjectType { MPEG2_AAC_LC, MPEG4_AAC_LC };
+
+ ObjectType object_type;
+};
+
+class A2dpOffloadCodecAac : public A2dpOffloadCodec {
+ CodecInfo info_;
+
+ A2dpOffloadCodecAac();
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters,
+ AacParameters* aac_parameters) const;
+
+ public:
+ static const A2dpOffloadCodecAac* GetInstance();
+
+ A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const override {
+ return ParseConfiguration(configuration, codec_parameters, nullptr);
+ }
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ AacParameters* aac_parameters) const {
+ return ParseConfiguration(configuration, aac_parameters, aac_parameters);
+ }
+
+ bool BuildConfiguration(const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp
new file mode 100644
index 0000000..73d8fb1
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecFactory.h"
+
+#include <algorithm>
+#include <cassert>
+
+#include "A2dpOffloadCodecAac.h"
+#include "A2dpOffloadCodecSbc.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * Local Capabilities Configuration
+ */
+
+enum : bool {
+ kEnableAac = true,
+ kEnableSbc = true,
+};
+
+/**
+ * Class implementation
+ */
+
+const A2dpOffloadCodecFactory* A2dpOffloadCodecFactory::GetInstance() {
+ static A2dpOffloadCodecFactory instance;
+ return &instance;
+}
+
+A2dpOffloadCodecFactory::A2dpOffloadCodecFactory()
+ : name("Offload"), codecs(ranked_codecs_) {
+ ranked_codecs_.reserve(kEnableAac + kEnableSbc);
+
+ if (kEnableAac) ranked_codecs_.push_back(A2dpOffloadCodecAac::GetInstance());
+ if (kEnableSbc) ranked_codecs_.push_back(A2dpOffloadCodecSbc::GetInstance());
+}
+
+const A2dpOffloadCodec* A2dpOffloadCodecFactory::GetCodec(CodecId id) const {
+ auto codec = std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
+ [&](auto c) { return id == c->info.id; });
+
+ return codec != end(ranked_codecs_) ? *codec : nullptr;
+}
+
+bool A2dpOffloadCodecFactory::GetConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_capabilities,
+ const A2dpConfigurationHint& hint, A2dpConfiguration* configuration) const {
+ decltype(ranked_codecs_) codecs;
+
+ codecs.reserve(ranked_codecs_.size());
+
+ auto hinted_codec =
+ std::find_if(begin(ranked_codecs_), end(ranked_codecs_),
+ [&](auto c) { return hint.codecId == c->info.id; });
+
+ if (hinted_codec != end(ranked_codecs_)) codecs.push_back(*hinted_codec);
+
+ std::copy_if(begin(ranked_codecs_), end(ranked_codecs_),
+ std::back_inserter(codecs),
+ [&](auto c) { return c != *hinted_codec; });
+
+ for (auto codec : codecs) {
+ auto rc =
+ std::find_if(begin(remote_capabilities), end(remote_capabilities),
+ [&](auto& rc__) { return codec->info.id == rc__.id; });
+
+ if ((rc == end(remote_capabilities)) ||
+ !codec->BuildConfiguration(rc->capabilities, hint.codecParameters,
+ &configuration->configuration))
+ continue;
+
+ configuration->id = codec->info.id;
+ A2dpStatus status = codec->ParseConfiguration(configuration->configuration,
+ &configuration->parameters);
+ assert(status == A2dpStatus::OK);
+
+ configuration->remoteSeid = rc->seid;
+
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h
new file mode 100644
index 0000000..3fb5b1d
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecFactory.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+class A2dpOffloadCodecFactory {
+ std::vector<const A2dpOffloadCodec*> ranked_codecs_;
+
+ A2dpOffloadCodecFactory();
+
+ public:
+ const std::string name;
+ const std::vector<const A2dpOffloadCodec*>& codecs;
+
+ static const A2dpOffloadCodecFactory* GetInstance();
+
+ const A2dpOffloadCodec* GetCodec(CodecId id) const;
+
+ bool GetConfiguration(const std::vector<A2dpRemoteCapabilities>&,
+ const A2dpConfigurationHint& hint,
+ A2dpConfiguration* configuration) const;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
new file mode 100644
index 0000000..36d8f72
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "A2dpOffloadCodecSbc.h"
+
+#include <algorithm>
+
+#include "A2dpBits.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+/**
+ * SBC Local Capabilities
+ */
+
+enum : bool {
+ kEnableSamplingFrequency44100 = true,
+ kEnableSamplingFrequency48000 = true,
+};
+
+enum : bool {
+ kEnableChannelModeMono = true,
+ kEnableChannelModeDualChannel = true,
+ kEnableChannelModeStereo = true,
+ kEnableChannelModeJointStereo = true,
+};
+
+enum : bool {
+ kEnableBlockLength4 = true,
+ kEnableBlockLength8 = true,
+ kEnableBlockLength12 = true,
+ kEnableBlockLength16 = true,
+};
+
+enum : bool {
+ kEnableSubbands4 = true,
+ kEnableSubbands8 = true,
+};
+
+enum : bool {
+ kEnableAllocationMethodSnr = true,
+ kEnableAllocationMethodLoudness = true,
+};
+
+enum : uint8_t {
+ kDefaultMinimumBitpool = 2,
+ kDefaultMaximumBitpool = 250,
+};
+
+enum : int {
+ kBitdepth = 16,
+};
+
+/**
+ * SBC Signaling format [A2DP - 4.3]
+ */
+
+// clang-format off
+
+constexpr A2dpBits::Range kSamplingFrequency ( 0, 3 );
+constexpr A2dpBits::Range kChannelMode ( 4, 7 );
+constexpr A2dpBits::Range kBlockLength ( 8, 11 );
+constexpr A2dpBits::Range kSubbands ( 12, 13 );
+constexpr A2dpBits::Range kAllocationMethod ( 14, 15 );
+constexpr A2dpBits::Range kMinimumBitpool ( 16, 23 );
+constexpr A2dpBits::Range kMaximumBitpool ( 24, 31 );
+constexpr size_t kCapabilitiesSize = 32/8;
+
+// clang-format on
+
+enum {
+ kSamplingFrequency16000 = kSamplingFrequency.first,
+ kSamplingFrequency32000,
+ kSamplingFrequency44100,
+ kSamplingFrequency48000
+};
+
+enum {
+ kChannelModeMono = kChannelMode.first,
+ kChannelModeDualChannel,
+ kChannelModeStereo,
+ kChannelModeJointStereo
+};
+
+enum {
+ kBlockLength4 = kBlockLength.first,
+ kBlockLength8,
+ kBlockLength12,
+ kBlockLength16
+};
+
+enum { kSubbands8 = kSubbands.first, kSubbands4 };
+
+enum {
+ kAllocationMethodSnr = kAllocationMethod.first,
+ kAllocationMethodLoudness
+};
+
+/**
+ * SBC Conversion functions
+ */
+
+static int GetSamplingFrequencyBit(int32_t sampling_frequency) {
+ switch (sampling_frequency) {
+ case 16000:
+ return kSamplingFrequency16000;
+ case 32000:
+ return kSamplingFrequency32000;
+ case 44100:
+ return kSamplingFrequency44100;
+ case 48000:
+ return kSamplingFrequency48000;
+ default:
+ return -1;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(int sampling_frequency) {
+ switch (sampling_frequency) {
+ case kSamplingFrequency16000:
+ return 16000;
+ case kSamplingFrequency32000:
+ return 32000;
+ case kSamplingFrequency44100:
+ return 44100;
+ case kSamplingFrequency48000:
+ return 48000;
+ default:
+ return 0;
+ }
+}
+
+static int GetChannelModeBit(ChannelMode channel_mode) {
+ switch (channel_mode) {
+ case ChannelMode::STEREO:
+ return kChannelModeJointStereo | kChannelModeStereo;
+ case ChannelMode::DUALMONO:
+ return kChannelModeDualChannel;
+ case ChannelMode::MONO:
+ return kChannelModeMono;
+ default:
+ return -1;
+ }
+}
+
+static ChannelMode GetChannelModeEnum(int channel_mode) {
+ switch (channel_mode) {
+ case kChannelModeMono:
+ return ChannelMode::MONO;
+ case kChannelModeDualChannel:
+ return ChannelMode::DUALMONO;
+ case kChannelModeStereo:
+ case kChannelModeJointStereo:
+ return ChannelMode::STEREO;
+ default:
+ return ChannelMode::UNKNOWN;
+ }
+}
+
+static int32_t GetBlockLengthValue(int block_length) {
+ switch (block_length) {
+ case kBlockLength4:
+ return 4;
+ case kBlockLength8:
+ return 8;
+ case kBlockLength12:
+ return 12;
+ case kBlockLength16:
+ return 16;
+ default:
+ return 0;
+ }
+}
+
+static int32_t GetSubbandsValue(int subbands) {
+ switch (subbands) {
+ case kSubbands4:
+ return 4;
+ case kSubbands8:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+static SbcParameters::AllocationMethod GetAllocationMethodEnum(
+ int allocation_method) {
+ switch (allocation_method) {
+ case kAllocationMethodSnr:
+ return SbcParameters::AllocationMethod::SNR;
+ case kAllocationMethodLoudness:
+ default:
+ return SbcParameters::AllocationMethod::LOUDNESS;
+ }
+}
+
+static int32_t GetSamplingFrequencyValue(const A2dpBits& configuration) {
+ return GetSamplingFrequencyValue(
+ configuration.find_active_bit(kSamplingFrequency));
+}
+
+static int32_t GetBlockLengthValue(const A2dpBits& configuration) {
+ return GetBlockLengthValue(configuration.find_active_bit(kBlockLength));
+}
+
+static int32_t GetSubbandsValue(const A2dpBits& configuration) {
+ return GetSubbandsValue(configuration.find_active_bit(kSubbands));
+}
+
+static int GetFrameSize(const A2dpBits& configuration, int bitpool) {
+ const int kSbcHeaderSize = 4;
+ int subbands = GetSubbandsValue(configuration);
+ int blocks = GetBlockLengthValue(configuration);
+
+ unsigned bits =
+ ((4 * subbands) << !configuration.get(kChannelModeMono)) +
+ ((blocks * bitpool) << configuration.get(kChannelModeDualChannel)) +
+ ((configuration.get(kChannelModeJointStereo) ? subbands : 0));
+
+ return kSbcHeaderSize + ((bits + 7) >> 3);
+}
+
+static int GetBitrate(const A2dpBits& configuration, int bitpool) {
+ int sampling_frequency = GetSamplingFrequencyValue(configuration);
+ int subbands = GetSubbandsValue(configuration);
+ int blocks = GetBlockLengthValue(configuration);
+ int bits = 8 * GetFrameSize(configuration, bitpool);
+
+ return (bits * sampling_frequency) / (blocks * subbands);
+}
+
+static uint8_t GetBitpool(const A2dpBits& configuration, int bitrate) {
+ int bitpool = 0;
+
+ for (int i = 128; i; i >>= 1)
+ if (bitrate > GetBitrate(configuration, bitpool + i)) {
+ bitpool += i;
+ }
+
+ return std::clamp(bitpool, 2, 250);
+}
+
+/**
+ * SBC Class implementation
+ */
+
+const A2dpOffloadCodecSbc* A2dpOffloadCodecSbc::GetInstance() {
+ static A2dpOffloadCodecSbc instance;
+ return &instance;
+}
+
+A2dpOffloadCodecSbc::A2dpOffloadCodecSbc()
+ : A2dpOffloadCodec(info_),
+ info_({.id = CodecId(CodecId::A2dp::SBC), .name = "SBC"}) {
+ info_.transport.set<CodecInfo::Transport::Tag::a2dp>();
+ auto& a2dp_info = info_.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ /* --- Setup Capabilities --- */
+
+ a2dp_info.capabilities.resize(kCapabilitiesSize);
+ std::fill(begin(a2dp_info.capabilities), end(a2dp_info.capabilities), 0);
+
+ auto capabilities = A2dpBits(a2dp_info.capabilities);
+
+ capabilities.set(kSamplingFrequency44100, kEnableSamplingFrequency44100);
+ capabilities.set(kSamplingFrequency48000, kEnableSamplingFrequency48000);
+
+ capabilities.set(kChannelModeMono, kEnableChannelModeMono);
+ capabilities.set(kChannelModeDualChannel, kEnableChannelModeDualChannel);
+ capabilities.set(kChannelModeStereo, kEnableChannelModeStereo);
+ capabilities.set(kChannelModeJointStereo, kEnableChannelModeJointStereo);
+
+ capabilities.set(kBlockLength4, kEnableBlockLength4);
+ capabilities.set(kBlockLength8, kEnableBlockLength8);
+ capabilities.set(kBlockLength12, kEnableBlockLength12);
+ capabilities.set(kBlockLength16, kEnableBlockLength16);
+
+ capabilities.set(kSubbands4, kEnableSubbands4);
+ capabilities.set(kSubbands8, kEnableSubbands8);
+
+ capabilities.set(kSubbands4, kEnableSubbands4);
+ capabilities.set(kSubbands8, kEnableSubbands8);
+
+ capabilities.set(kAllocationMethodSnr, kEnableAllocationMethodSnr);
+ capabilities.set(kAllocationMethodLoudness, kEnableAllocationMethodLoudness);
+
+ capabilities.set(kMinimumBitpool, kDefaultMinimumBitpool);
+ capabilities.set(kMaximumBitpool, kDefaultMaximumBitpool);
+
+ /* --- Setup Sampling Frequencies --- */
+
+ auto& sampling_frequency = a2dp_info.samplingFrequencyHz;
+
+ for (auto v : {16000, 32000, 44100, 48000})
+ if (capabilities.get(GetSamplingFrequencyBit(int32_t(v))))
+ sampling_frequency.push_back(v);
+
+ /* --- Setup Channel Modes --- */
+
+ auto& channel_modes = a2dp_info.channelMode;
+
+ for (auto v : {ChannelMode::MONO, ChannelMode::DUALMONO, ChannelMode::STEREO})
+ if (capabilities.get(GetChannelModeBit(v))) channel_modes.push_back(v);
+
+ /* --- Setup Bitdepth --- */
+
+ a2dp_info.bitdepth.push_back(kBitdepth);
+}
+
+A2dpStatus A2dpOffloadCodecSbc::ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, SbcParameters* sbc_parameters) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (configuration.size() != a2dp_info.capabilities.size())
+ return A2dpStatus::BAD_LENGTH;
+
+ auto config = A2dpBits(configuration);
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+
+ /* --- Check Sampling Frequency --- */
+
+ int sampling_frequency = config.find_active_bit(kSamplingFrequency);
+ if (sampling_frequency < 0) return A2dpStatus::INVALID_SAMPLING_FREQUENCY;
+ if (!lcaps.get(sampling_frequency))
+ return A2dpStatus::NOT_SUPPORTED_SAMPLING_FREQUENCY;
+
+ /* --- Check Channel Mode --- */
+
+ int channel_mode = config.find_active_bit(kChannelMode);
+ if (channel_mode < 0) return A2dpStatus::INVALID_CHANNEL_MODE;
+ if (!lcaps.get(channel_mode)) return A2dpStatus::NOT_SUPPORTED_CHANNEL_MODE;
+
+ /* --- Check Block Length --- */
+
+ int block_length = config.find_active_bit(kBlockLength);
+ if (block_length < 0) return A2dpStatus::INVALID_BLOCK_LENGTH;
+
+ /* --- Check Subbands --- */
+
+ int subbands = config.find_active_bit(kSubbands);
+ if (subbands < 0) return A2dpStatus::INVALID_SUBBANDS;
+ if (!lcaps.get(subbands)) return A2dpStatus::NOT_SUPPORTED_SUBBANDS;
+
+ /* --- Check Allocation Method --- */
+
+ int allocation_method = config.find_active_bit(kAllocationMethod);
+ if (allocation_method < 0) return A2dpStatus::INVALID_ALLOCATION_METHOD;
+ if (!lcaps.get(allocation_method))
+ return A2dpStatus::NOT_SUPPORTED_ALLOCATION_METHOD;
+
+ /* --- Check Bitpool --- */
+
+ uint8_t min_bitpool = config.get(kMinimumBitpool);
+ if (min_bitpool < 2 || min_bitpool > 250)
+ return A2dpStatus::INVALID_MINIMUM_BITPOOL_VALUE;
+ if (min_bitpool < lcaps.get(kMinimumBitpool))
+ return A2dpStatus::NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE;
+
+ uint8_t max_bitpool = config.get(kMaximumBitpool);
+ if (max_bitpool < 2 || max_bitpool > 250)
+ return A2dpStatus::INVALID_MAXIMUM_BITPOOL_VALUE;
+ if (max_bitpool > lcaps.get(kMaximumBitpool))
+ return A2dpStatus::NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE;
+
+ /* --- Return --- */
+
+ codec_parameters->channelMode = GetChannelModeEnum(channel_mode);
+ codec_parameters->samplingFrequencyHz =
+ GetSamplingFrequencyValue(sampling_frequency);
+ codec_parameters->bitdepth = kBitdepth;
+
+ codec_parameters->minBitrate = GetBitrate(config, min_bitpool);
+ codec_parameters->maxBitrate = GetBitrate(config, max_bitpool);
+
+ if (sbc_parameters) {
+ sbc_parameters->block_length = GetBlockLengthValue(block_length);
+ sbc_parameters->subbands = GetSubbandsValue(subbands);
+ sbc_parameters->allocation_method =
+ GetAllocationMethodEnum(allocation_method);
+ sbc_parameters->min_bitpool = min_bitpool;
+ sbc_parameters->max_bitpool = max_bitpool;
+ }
+
+ return A2dpStatus::OK;
+}
+
+bool A2dpOffloadCodecSbc::BuildConfiguration(
+ const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const {
+ auto& a2dp_info = info.transport.get<CodecInfo::Transport::Tag::a2dp>();
+
+ if (remote_capabilities.size() != a2dp_info.capabilities.size()) return false;
+
+ auto lcaps = A2dpBits(a2dp_info.capabilities);
+ auto rcaps = A2dpBits(remote_capabilities);
+
+ configuration->resize(a2dp_info.capabilities.size());
+ std::fill(begin(*configuration), end(*configuration), 0);
+ auto config = A2dpBits(*configuration);
+
+ /* --- Select Sampling Frequency --- */
+
+ auto sf_hint = hint ? GetSamplingFrequencyBit(hint->samplingFrequencyHz) : -1;
+
+ if (sf_hint >= 0 && lcaps.get(sf_hint) && rcaps.get(sf_hint))
+ config.set(sf_hint);
+ else if (lcaps.get(kSamplingFrequency44100) &&
+ rcaps.get(kSamplingFrequency44100))
+ config.set(kSamplingFrequency44100);
+ else if (lcaps.get(kSamplingFrequency48000) &&
+ rcaps.get(kSamplingFrequency48000))
+ config.set(kSamplingFrequency48000);
+ else
+ return false;
+
+ /* --- Select Channel Mode --- */
+
+ auto cm_hint = hint ? GetChannelModeBit(hint->channelMode) : -1;
+
+ if (cm_hint >= 0 && lcaps.get(cm_hint) && rcaps.get(cm_hint))
+ config.set(cm_hint);
+ else if (lcaps.get(kChannelModeJointStereo) &&
+ rcaps.get(kChannelModeJointStereo))
+ config.set(kChannelModeJointStereo);
+ else if (lcaps.get(kChannelModeStereo) && rcaps.get(kChannelModeStereo))
+ config.set(kChannelModeStereo);
+ else if (lcaps.get(kChannelModeDualChannel) &&
+ rcaps.get(kChannelModeDualChannel))
+ config.set(kChannelModeDualChannel);
+ else if (lcaps.get(kChannelModeMono) && rcaps.get(kChannelModeMono))
+ config.set(kChannelModeMono);
+ else
+ return false;
+
+ /* --- Select Block Length --- */
+
+ if (lcaps.get(kBlockLength16) && rcaps.get(kBlockLength16))
+ config.set(kBlockLength16);
+ else if (lcaps.get(kBlockLength12) && rcaps.get(kBlockLength12))
+ config.set(kBlockLength12);
+ else if (lcaps.get(kBlockLength8) && rcaps.get(kBlockLength8))
+ config.set(kBlockLength8);
+ else if (lcaps.get(kBlockLength4) && rcaps.get(kBlockLength4))
+ config.set(kBlockLength4);
+ else
+ return false;
+
+ /* --- Select Subbands --- */
+
+ if (lcaps.get(kSubbands8) && rcaps.get(kSubbands8))
+ config.set(kSubbands8);
+ else if (lcaps.get(kSubbands4) && rcaps.get(kSubbands4))
+ config.set(kSubbands4);
+ else
+ return false;
+
+ /* --- Select Allocation method --- */
+
+ if (lcaps.get(kAllocationMethodLoudness) &&
+ rcaps.get(kAllocationMethodLoudness))
+ config.set(kAllocationMethodLoudness);
+ else if (lcaps.get(kAllocationMethodSnr) && rcaps.get(kAllocationMethodSnr))
+ config.set(kAllocationMethodSnr);
+ else
+ return false;
+
+ /* --- Select Bitpool --- */
+
+ uint8_t min_bitpool = rcaps.get(kMinimumBitpool);
+ uint8_t max_bitpool = rcaps.get(kMaximumBitpool);
+
+ if (min_bitpool < 2 || min_bitpool > 250 || max_bitpool < 2 ||
+ max_bitpool > 250 || min_bitpool > max_bitpool) {
+ min_bitpool = 2;
+ max_bitpool = 250;
+ }
+
+ min_bitpool = std::max(min_bitpool, uint8_t(lcaps.get(kMinimumBitpool)));
+ max_bitpool = std::max(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
+
+ if (hint) {
+ min_bitpool =
+ std::max(min_bitpool, GetBitpool(*configuration, hint->minBitrate));
+ if (hint->maxBitrate && hint->maxBitrate >= hint->minBitrate)
+ max_bitpool =
+ std::min(max_bitpool, GetBitpool(*configuration, hint->maxBitrate));
+ }
+
+ config.set(kMinimumBitpool, min_bitpool);
+ config.set(kMaximumBitpool, max_bitpool);
+
+ return true;
+}
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h
new file mode 100644
index 0000000..c380850
--- /dev/null
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "A2dpOffloadCodec.h"
+
+namespace aidl::android::hardware::bluetooth::audio {
+
+struct SbcParameters : public CodecParameters {
+ enum class AllocationMethod { SNR, LOUDNESS };
+
+ AllocationMethod allocation_method;
+ int block_length;
+ int subbands;
+ int min_bitpool;
+ int max_bitpool;
+};
+
+class A2dpOffloadCodecSbc : public A2dpOffloadCodec {
+ CodecInfo info_;
+
+ A2dpOffloadCodecSbc();
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters,
+ SbcParameters* sbc_parameters) const;
+
+ public:
+ static const A2dpOffloadCodecSbc* GetInstance();
+
+ A2dpStatus ParseConfiguration(
+ const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters) const override {
+ return ParseConfiguration(configuration, codec_parameters, nullptr);
+ }
+
+ A2dpStatus ParseConfiguration(const std::vector<uint8_t>& configuration,
+ SbcParameters* sbc_parameters) const {
+ return ParseConfiguration(configuration, sbc_parameters, sbc_parameters);
+ }
+
+ bool BuildConfiguration(const std::vector<uint8_t>& remote_capabilities,
+ const std::optional<CodecParameters>& hint,
+ std::vector<uint8_t>* configuration) const override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::audio
diff --git a/bluetooth/audio/aidl/default/Android.bp b/bluetooth/audio/aidl/default/Android.bp
index 40aea32..69db1b3 100644
--- a/bluetooth/audio/aidl/default/Android.bp
+++ b/bluetooth/audio/aidl/default/Android.bp
@@ -18,8 +18,13 @@
"BluetoothAudioProvider.cpp",
"BluetoothAudioProviderFactory.cpp",
"A2dpOffloadAudioProvider.cpp",
+ "A2dpOffloadCodecAac.cpp",
+ "A2dpOffloadCodecFactory.cpp",
+ "A2dpOffloadCodecSbc.cpp",
"A2dpSoftwareAudioProvider.cpp",
"HearingAidAudioProvider.cpp",
+ "HfpOffloadAudioProvider.cpp",
+ "HfpSoftwareAudioProvider.cpp",
"LeAudioOffloadAudioProvider.cpp",
"LeAudioSoftwareAudioProvider.cpp",
"service.cpp",
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 9c72e19..b88e66a 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -21,6 +21,8 @@
#include <BluetoothAudioSessionReport.h>
#include <android-base/logging.h>
+#include "A2dpOffloadCodecFactory.h"
+
namespace aidl {
namespace android {
namespace hardware {
@@ -164,8 +166,29 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioProvider::parseA2dpConfiguration(
+ [[maybe_unused]] const CodecId& codec_id,
+ [[maybe_unused]] const std::vector<uint8_t>& configuration,
+ [[maybe_unused]] CodecParameters* codec_parameters,
+ [[maybe_unused]] A2dpStatus* _aidl_return) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " is illegal";
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
+ndk::ScopedAStatus BluetoothAudioProvider::getA2dpConfiguration(
+ [[maybe_unused]] const std::vector<A2dpRemoteCapabilities>&
+ remote_a2dp_capabilities,
+ [[maybe_unused]] const A2dpConfigurationHint& hint,
+ [[maybe_unused]] std::optional<audio::A2dpConfiguration>* _aidl_return) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " is illegal";
+
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index b6e07a1..27ab13f 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -50,6 +50,14 @@
const AudioConfiguration& audio_config);
ndk::ScopedAStatus setLowLatencyModeAllowed(bool allowed);
+ ndk::ScopedAStatus parseA2dpConfiguration(
+ const CodecId& codec_id, const std::vector<uint8_t>& configuration,
+ CodecParameters* codec_parameters, A2dpStatus* _aidl_return);
+ ndk::ScopedAStatus getA2dpConfiguration(
+ const std::vector<A2dpRemoteCapabilities>& remote_a2dp_capabilities,
+ const A2dpConfigurationHint& hint,
+ std::optional<audio::A2dpConfiguration>* _aidl_return);
+
virtual bool isValid(const SessionType& sessionType) = 0;
protected:
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
index 91731d4..3a64c4d 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp
@@ -22,9 +22,12 @@
#include <android-base/logging.h>
#include "A2dpOffloadAudioProvider.h"
+#include "A2dpOffloadCodecFactory.h"
#include "A2dpSoftwareAudioProvider.h"
#include "BluetoothAudioProvider.h"
#include "HearingAidAudioProvider.h"
+#include "HfpOffloadAudioProvider.h"
+#include "HfpSoftwareAudioProvider.h"
#include "LeAudioOffloadAudioProvider.h"
#include "LeAudioSoftwareAudioProvider.h"
@@ -78,6 +81,15 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
provider = ndk::SharedRefBase::make<A2dpOffloadDecodingAudioProvider>();
break;
+ case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpSoftwareOutputAudioProvider>();
+ break;
+ case SessionType::HFP_SOFTWARE_DECODING_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpSoftwareInputAudioProvider>();
+ break;
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ provider = ndk::SharedRefBase::make<HfpOffloadAudioProvider>();
+ break;
default:
provider = nullptr;
break;
@@ -135,8 +147,24 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo(
+ SessionType session_type, std::optional<ProviderInfo>* _aidl_return) {
+ *_aidl_return = std::nullopt;
+
+ if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ auto& provider_info = _aidl_return->emplace();
+
+ provider_info.name = A2dpOffloadCodecFactory::GetInstance()->name;
+ for (auto codec : A2dpOffloadCodecFactory::GetInstance()->codecs)
+ provider_info.codecInfos.push_back(codec->info);
+ }
+
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace hardware
} // namespace android
-} // namespace aidl
\ No newline at end of file
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
index b38cfd2..1afae64 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.h
@@ -35,6 +35,10 @@
ndk::ScopedAStatus getProviderCapabilities(
const SessionType session_type,
std::vector<AudioCapabilities>* _aidl_return) override;
+
+ ndk::ScopedAStatus getProviderInfo(
+ SessionType in_sessionType,
+ std::optional<ProviderInfo>* _aidl_return) override;
};
} // namespace audio
diff --git a/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp
new file mode 100644
index 0000000..7196bb6
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHfpHW"
+
+#include "HfpOffloadAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+HfpOffloadAudioProvider::HfpOffloadAudioProvider() {
+ session_type_ = SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
+}
+
+bool HfpOffloadAudioProvider::isValid(const SessionType& session_type) {
+ return (session_type == session_type_);
+}
+
+ndk::ScopedAStatus HfpOffloadAudioProvider::startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
+ if (audio_config.getTag() != AudioConfiguration::hfpConfig) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
+}
+
+ndk::ScopedAStatus HfpOffloadAudioProvider::onSessionReady(
+ DataMQDesc* _aidl_return) {
+ *_aidl_return = DataMQDesc();
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, nullptr, *audio_config_, latency_modes_);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h
new file mode 100644
index 0000000..5526b46
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpOffloadAudioProvider.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HfpOffloadAudioProvider : public BluetoothAudioProvider {
+ public:
+ HfpOffloadAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+
+ ndk::ScopedAStatus startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+
+ private:
+ ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp
new file mode 100644
index 0000000..0f96046
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BTAudioProviderHfpSW"
+
+#include "HfpSoftwareAudioProvider.h"
+
+#include <BluetoothAudioCodecs.h>
+#include <BluetoothAudioSessionReport.h>
+#include <android-base/logging.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+static constexpr uint32_t kBufferCount = 2; // two frame buffer
+
+HfpSoftwareOutputAudioProvider::HfpSoftwareOutputAudioProvider()
+ : HfpSoftwareAudioProvider() {
+ session_type_ = SessionType::HFP_SOFTWARE_ENCODING_DATAPATH;
+}
+
+HfpSoftwareInputAudioProvider::HfpSoftwareInputAudioProvider()
+ : HfpSoftwareAudioProvider() {
+ session_type_ = SessionType::HFP_SOFTWARE_DECODING_DATAPATH;
+}
+
+HfpSoftwareAudioProvider::HfpSoftwareAudioProvider()
+ : BluetoothAudioProvider(), data_mq_(nullptr) {
+}
+
+bool HfpSoftwareAudioProvider::isValid(const SessionType& sessionType) {
+ return (sessionType == session_type_);
+}
+
+ndk::ScopedAStatus HfpSoftwareAudioProvider::startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return) {
+ if (audio_config.getTag() != AudioConfiguration::pcmConfig) {
+ LOG(WARNING) << __func__ << " - Invalid Audio Configuration="
+ << audio_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ const PcmConfiguration& pcm_config =
+ audio_config.get<AudioConfiguration::pcmConfig>();
+ if (!BluetoothAudioCodecs::IsSoftwarePcmConfigurationValid(pcm_config)) {
+ LOG(WARNING) << __func__ << " - Unsupported PCM Configuration="
+ << pcm_config.toString();
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ bool isValidConfig = true;
+
+ if (pcm_config.bitsPerSample != 16) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.sampleRateHz != 8000 && pcm_config.sampleRateHz != 16000 &&
+ pcm_config.sampleRateHz != 32000) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.channelMode != ChannelMode::MONO) {
+ isValidConfig = false;
+ }
+
+ if (pcm_config.dataIntervalUs != 7500) {
+ isValidConfig = false;
+ }
+
+ int bytes_per_sample = pcm_config.bitsPerSample / 8;
+
+ uint32_t data_mq_size = kBufferCount * bytes_per_sample *
+ (pcm_config.sampleRateHz / 1000) *
+ pcm_config.dataIntervalUs / 1000;
+ if (!isValidConfig) {
+ LOG(ERROR) << __func__ << "Unexpected audio buffer size: " << data_mq_size
+ << ", SampleRateHz: " << pcm_config.sampleRateHz
+ << ", ChannelMode: " << toString(pcm_config.channelMode)
+ << ", BitsPerSample: "
+ << static_cast<int>(pcm_config.bitsPerSample)
+ << ", BytesPerSample: " << bytes_per_sample
+ << ", DataIntervalUs: " << pcm_config.dataIntervalUs
+ << ", SessionType: " << toString(session_type_);
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+
+ LOG(INFO) << __func__ << " - size of audio buffer " << data_mq_size
+ << " byte(s)";
+
+ std::unique_ptr<DataMQ> temp_data_mq(
+ new DataMQ(data_mq_size, /* EventFlag */ true));
+ if (temp_data_mq == nullptr || !temp_data_mq->isValid()) {
+ ALOGE_IF(!temp_data_mq, "failed to allocate data MQ");
+ ALOGE_IF(temp_data_mq && !temp_data_mq->isValid(), "data MQ is invalid");
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ data_mq_ = std::move(temp_data_mq);
+
+ return BluetoothAudioProvider::startSession(host_if, audio_config,
+ latency_modes, _aidl_return);
+}
+
+ndk::ScopedAStatus HfpSoftwareAudioProvider::onSessionReady(
+ DataMQDesc* _aidl_return) {
+ if (data_mq_ == nullptr || !data_mq_->isValid()) {
+ *_aidl_return = DataMQDesc();
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
+ *_aidl_return = data_mq_->dupeDesc();
+ auto desc = data_mq_->dupeDesc();
+ BluetoothAudioSessionReport::OnSessionStarted(
+ session_type_, stack_iface_, &desc, *audio_config_, latency_modes_);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h
new file mode 100644
index 0000000..ef51065
--- /dev/null
+++ b/bluetooth/audio/aidl/default/HfpSoftwareAudioProvider.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "BluetoothAudioProvider.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace audio {
+
+class HfpSoftwareAudioProvider : public BluetoothAudioProvider {
+ public:
+ HfpSoftwareAudioProvider();
+
+ bool isValid(const SessionType& sessionType) override;
+
+ ndk::ScopedAStatus startSession(
+ const std::shared_ptr<IBluetoothAudioPort>& host_if,
+ const AudioConfiguration& audio_config,
+ const std::vector<LatencyMode>& latency_modes, DataMQDesc* _aidl_return);
+
+ private:
+ // audio data queue for software encoding
+ std::unique_ptr<DataMQ> data_mq_;
+
+ ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override;
+};
+
+class HfpSoftwareOutputAudioProvider : public HfpSoftwareAudioProvider {
+ public:
+ HfpSoftwareOutputAudioProvider();
+};
+
+class HfpSoftwareInputAudioProvider : public HfpSoftwareAudioProvider {
+ public:
+ HfpSoftwareInputAudioProvider();
+};
+
+} // namespace audio
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+} // namespace aidl
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 858fa38..17be7be 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -33,6 +33,11 @@
using aidl::android::hardware::audio::common::SinkMetadata;
using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::A2dpConfiguration;
+using aidl::android::hardware::bluetooth::audio::A2dpConfigurationHint;
+using aidl::android::hardware::bluetooth::audio::A2dpRemoteCapabilities;
+using aidl::android::hardware::bluetooth::audio::A2dpStatus;
+using aidl::android::hardware::bluetooth::audio::A2dpStreamConfiguration;
using aidl::android::hardware::bluetooth::audio::AacCapabilities;
using aidl::android::hardware::bluetooth::audio::AacConfiguration;
using aidl::android::hardware::bluetooth::audio::AptxAdaptiveLeCapabilities;
@@ -46,7 +51,11 @@
using aidl::android::hardware::bluetooth::audio::ChannelMode;
using aidl::android::hardware::bluetooth::audio::CodecCapabilities;
using aidl::android::hardware::bluetooth::audio::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::CodecId;
+using aidl::android::hardware::bluetooth::audio::CodecInfo;
+using aidl::android::hardware::bluetooth::audio::CodecParameters;
using aidl::android::hardware::bluetooth::audio::CodecType;
+using aidl::android::hardware::bluetooth::audio::HfpConfiguration;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider;
using aidl::android::hardware::bluetooth::audio::IBluetoothAudioProviderFactory;
@@ -90,6 +99,13 @@
static constexpr ChannelMode a2dp_channel_modes[] = {
ChannelMode::UNKNOWN, ChannelMode::MONO, ChannelMode::STEREO};
static std::vector<LatencyMode> latency_modes = {LatencyMode::FREE};
+
+// Some valid configs for HFP PCM configuration (software sessions)
+static constexpr int32_t hfp_sample_rates_[] = {8000, 16000, 32000};
+static constexpr int8_t hfp_bits_per_samples_[] = {16};
+static constexpr ChannelMode hfp_channel_modes_[] = {ChannelMode::MONO};
+static constexpr int32_t hfp_data_interval_us_[] = {7500};
+
// Helpers
template <typename T>
@@ -195,7 +211,8 @@
case SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH:
- case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH: {
+ case SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH:
+ case SessionType::HFP_SOFTWARE_ENCODING_DATAPATH: {
// All software paths are mandatory and must have exact 1
// "PcmParameters"
ASSERT_EQ(temp_provider_capabilities_.size(), 1);
@@ -256,7 +273,8 @@
AudioCapabilities::leAudioCapabilities);
}
} break;
- case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH: {
+ case SessionType::A2DP_SOFTWARE_DECODING_DATAPATH:
+ case SessionType::HFP_SOFTWARE_DECODING_DATAPATH: {
if (!temp_provider_capabilities_.empty()) {
ASSERT_EQ(temp_provider_capabilities_.size(), 1);
ASSERT_EQ(temp_provider_capabilities_[0].getTag(),
@@ -296,7 +314,10 @@
LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type ==
SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
- session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH);
+ session_type == SessionType::A2DP_SOFTWARE_DECODING_DATAPATH ||
+ session_type == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
+ session_type == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
+ session_type == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
ASSERT_EQ(audio_provider_, nullptr);
}
}
@@ -573,6 +594,8 @@
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::HFP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HFP_SOFTWARE_DECODING_DATAPATH,
};
};
@@ -598,6 +621,794 @@
}
/**
+ * Test that getProviderInfo, when implemented,
+ * returns empty information for session types for
+ * software data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_invalidSessionTypes) {
+ static constexpr SessionType kInvalidSessionTypes[]{
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk()) {
+ continue;
+ }
+
+ // If getProviderInfo is supported, the provider info
+ // must be empty for software session types.
+ ASSERT_FALSE(provider_info.has_value());
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns valid information for session types for
+ * a2dp hardware data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_a2dpSessionTypes) {
+ static constexpr SessionType kA2dpSessionTypes[]{
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kA2dpSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk() || !provider_info.has_value()) {
+ continue;
+ }
+
+ for (auto const& codec_info : provider_info->codecInfos) {
+ // The codec id must not be core.
+ ASSERT_NE(codec_info.id.getTag(), CodecId::core);
+ // The codec info must contain the information
+ // for a2dp transport.
+ ASSERT_EQ(codec_info.transport.getTag(), CodecInfo::Transport::a2dp);
+ }
+ }
+}
+
+/**
+ * Test that getProviderInfo, when implemented,
+ * returns valid information for session types for
+ * le audio hardware data paths.
+ */
+TEST_P(BluetoothAudioProviderFactoryAidl, getProviderInfo_leAudioSessionTypes) {
+ static constexpr SessionType kLeAudioSessionTypes[]{
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ };
+
+ for (auto session_type : kLeAudioSessionTypes) {
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo> provider_info =
+ std::nullopt;
+ auto aidl_retval =
+ provider_factory_->getProviderInfo(session_type, &provider_info);
+ if (!aidl_retval.isOk() || !provider_info.has_value()) {
+ continue;
+ }
+
+ for (auto const& codec_info : provider_info->codecInfos) {
+ // The codec id must not be a2dp.
+ ASSERT_NE(codec_info.id.getTag(), CodecId::a2dp);
+ // The codec info must contain the information
+ // for le audio transport.
+ // ASSERT_EQ(codec_info.transport.getTag(),
+ // CodecInfo::Transport::le_audio);
+ }
+ }
+}
+
+class BluetoothAudioProviderAidl : public BluetoothAudioProviderFactoryAidl {
+ protected:
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ a2dp_encoding_provider_info_{};
+ std::optional<IBluetoothAudioProviderFactory::ProviderInfo>
+ a2dp_decoding_provider_info_{};
+ std::shared_ptr<IBluetoothAudioProvider> a2dp_encoding_provider_{nullptr};
+ std::shared_ptr<IBluetoothAudioProvider> a2dp_decoding_provider_{nullptr};
+
+ public:
+ void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ audio_port_ = ndk::SharedRefBase::make<BluetoothAudioPort>();
+
+ (void)provider_factory_->getProviderInfo(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ &a2dp_encoding_provider_info_);
+
+ (void)provider_factory_->getProviderInfo(
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ &a2dp_decoding_provider_info_);
+
+ (void)provider_factory_->openProvider(
+ SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ &a2dp_encoding_provider_);
+
+ (void)provider_factory_->openProvider(
+ SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ &a2dp_decoding_provider_);
+ }
+};
+
+/**
+ * Calling parseA2dpConfiguration on a session of a different type than
+ * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_invalidSessionType) {
+ static constexpr SessionType kInvalidSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ // Open a BluetoothAudioProvider instance of the selected session type.
+ // Skip validation if the provider cannot be opened.
+ std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
+ (void)provider_factory_->openProvider(session_type, &provider);
+ if (provider == nullptr) {
+ continue;
+ }
+
+ // parseA2dpConfiguration must fail without returning an A2dpStatus.
+ CodecId codec_id(CodecId::A2dp::SBC);
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ auto aidl_retval = provider->parseA2dpConfiguration(
+ codec_id, std::vector<uint8_t>{}, &codec_parameters, &a2dp_status);
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with an unknown codec must fail
+ * with the A2dpStatus code INVALID_CODEC_TYPE or NOT_SUPPORTED_CODEC_TYPE.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ parseA2dpConfiguration_unsupportedCodecType) {
+ CodecId unsupported_core_id(CodecId::Core::CVSD);
+ CodecId unsupported_vendor_id(
+ CodecId::Vendor(0xFCB1, 0x42)); // Google Codec #42
+
+ for (auto& provider : {a2dp_encoding_provider_, a2dp_decoding_provider_}) {
+ if (provider == nullptr) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with two invalid codec identifiers: vendor or core.
+ aidl_retval = provider->parseA2dpConfiguration(
+ unsupported_core_id, std::vector<uint8_t>{}, &codec_parameters,
+ &a2dp_status);
+ EXPECT_TRUE(!aidl_retval.isOk() ||
+ a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
+
+ aidl_retval = provider->parseA2dpConfiguration(
+ unsupported_vendor_id, std::vector<uint8_t>{}, &codec_parameters,
+ &a2dp_status);
+ EXPECT_TRUE(!aidl_retval.isOk() ||
+ a2dp_status == A2dpStatus::NOT_SUPPORTED_CODEC_TYPE);
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with a known codec and invalid configuration
+ * must fail with an A2dpStatus code different from INVALID_CODEC_TYPE or
+ * NOT_SUPPORTED_CODEC_TYPE.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ parseA2dpConfiguration_invalidConfiguration) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with the first available codec in the provider info for testing.
+ // The test runs with an empty parameters array, anything more specific
+ // would need understanding the codec.
+ aidl_retval = provider->parseA2dpConfiguration(
+ provider_info->codecInfos[0].id, std::vector<uint8_t>{},
+ &codec_parameters, &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status != A2dpStatus::OK &&
+ a2dp_status != A2dpStatus::NOT_SUPPORTED_CODEC_TYPE &&
+ a2dp_status != A2dpStatus::INVALID_CODEC_TYPE);
+ }
+}
+
+/**
+ * Calling parseA2dpConfiguration with a known codec and valid parameters
+ * must return with A2dpStatus OK.
+ */
+TEST_P(BluetoothAudioProviderAidl, parseA2dpConfiguration_valid) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ transport.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ aidl_retval = provider->parseA2dpConfiguration(
+ configuration->id, configuration->configuration, &codec_parameters,
+ &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
+ EXPECT_EQ(codec_parameters, configuration->parameters);
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration on a session of a different type than
+ * A2DP_HARDWARE_OFFLOAD_(ENCODING|DECODING)_DATAPATH must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_invalidSessionType) {
+ static constexpr SessionType kInvalidSessionTypes[] = {
+ SessionType::UNKNOWN,
+ SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_SOFTWARE_ENCODING_DATAPATH,
+ SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH,
+ SessionType::A2DP_SOFTWARE_DECODING_DATAPATH,
+ };
+
+ for (auto session_type : kInvalidSessionTypes) {
+ // Open a BluetoothAudioProvider instance of the selected session type.
+ // Skip validation if the provider cannot be opened.
+ std::shared_ptr<IBluetoothAudioProvider> provider{nullptr};
+ auto aidl_retval = provider_factory_->openProvider(session_type, &provider);
+ if (provider == nullptr) {
+ continue;
+ }
+
+ // getA2dpConfiguration must fail without returning a configuration.
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval =
+ provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
+ A2dpConfigurationHint(), &configuration);
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with empty or unknown remote capabilities
+ * must return an empty configuration.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_unknownRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ std::optional<A2dpConfiguration> configuration;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Test with empty remote capabilities.
+ aidl_retval =
+ provider->getA2dpConfiguration(std::vector<A2dpRemoteCapabilities>{},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+
+ // Test with unknown remote capabilities.
+ A2dpRemoteCapabilities unknown_core_remote_capabilities(
+ /*seid*/ 0, CodecId::Core::CVSD, std::vector<uint8_t>{1, 2, 3});
+ A2dpRemoteCapabilities unknown_vendor_remote_capabilities(
+ /*seid*/ 1,
+ /* Google Codec #42 */ CodecId::Vendor(0xFCB1, 0x42),
+ std::vector<uint8_t>{1, 2, 3});
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ unknown_core_remote_capabilities,
+ unknown_vendor_remote_capabilities,
+ },
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with invalid remote capabilities
+ * must return an empty configuration.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_invalidRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ std::optional<A2dpConfiguration> configuration;
+ ::ndk::ScopedAStatus aidl_retval;
+
+ // Use the first available codec in the provider info for testing.
+ // The capabilities are modified to make them invalid.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto transport = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::vector<uint8_t> invalid_capabilities = transport.capabilities;
+ invalid_capabilities.push_back(0x42); // adding bytes should be invalid.
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 0, codec_info.id,
+ std::vector<uint8_t>()),
+ A2dpRemoteCapabilities(/*seid*/ 1, codec_info.id,
+ invalid_capabilities),
+ },
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_FALSE(configuration.has_value());
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * must return a valid configuration. The selected parameters must
+ * be contained in the original capabilities. The returned configuration
+ * must match the returned parameters. The returned SEID must match the
+ * input SEID.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_validRemoteCapabilities) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ A2dpConfigurationHint(), &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Returned configuration must have the same codec id
+ // as the remote capability.
+ EXPECT_EQ(configuration->id, codec_info.id);
+
+ // Returned configuration must have the same SEID
+ // as the remote capability.
+ EXPECT_EQ(configuration->remoteSeid, 42);
+
+ // Returned codec parameters must be in the range of input
+ // parameters.
+ EXPECT_NE(
+ std::find(a2dp_info.channelMode.begin(), a2dp_info.channelMode.end(),
+ configuration->parameters.channelMode),
+ a2dp_info.channelMode.end());
+ EXPECT_NE(std::find(a2dp_info.samplingFrequencyHz.begin(),
+ a2dp_info.samplingFrequencyHz.end(),
+ configuration->parameters.samplingFrequencyHz),
+ a2dp_info.samplingFrequencyHz.end());
+ EXPECT_NE(std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
+ configuration->parameters.bitdepth),
+ a2dp_info.bitdepth.end());
+ EXPECT_EQ(a2dp_info.lossless, configuration->parameters.lossless);
+ EXPECT_TRUE(configuration->parameters.minBitrate <=
+ configuration->parameters.maxBitrate);
+
+ // Returned configuration must be parsable by parseA2dpParameters
+ // and match the codec parameters.
+ CodecParameters codec_parameters;
+ A2dpStatus a2dp_status = A2dpStatus::OK;
+ aidl_retval = provider->parseA2dpConfiguration(
+ configuration->id, configuration->configuration, &codec_parameters,
+ &a2dp_status);
+ ASSERT_TRUE(aidl_retval.isOk());
+ EXPECT_TRUE(a2dp_status == A2dpStatus::OK);
+ EXPECT_EQ(codec_parameters, configuration->parameters);
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted codec ids.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintCodecId) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Build the remote capabilities with all supported codecs.
+ std::vector<A2dpRemoteCapabilities> remote_capabilities;
+ for (size_t n = 0; n < provider_info->codecInfos.size(); n++) {
+ auto const& codec_info = provider_info->codecInfos[n];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ remote_capabilities.push_back(A2dpRemoteCapabilities(
+ /*seid*/ n, codec_info.id, a2dp_info.capabilities));
+ }
+
+ // Test with all supported codec identifiers,
+ for (auto const& codec_info : provider_info->codecInfos) {
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ A2dpConfigurationHint hint;
+ hint.codecId = codec_info.id;
+
+ aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
+ &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+ EXPECT_EQ(configuration->id, codec_info.id);
+ }
+
+ // Test with unknown codec identifiers: either core or vendor.
+ for (auto& codec_id :
+ {CodecId(CodecId::Core::CVSD),
+ CodecId(CodecId::Vendor(0xFCB1, 0x42)) /*Google Codec #42*/}) {
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ A2dpConfigurationHint hint;
+ hint.codecId = codec_id;
+
+ aidl_retval = provider->getA2dpConfiguration(remote_capabilities, hint,
+ &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+ EXPECT_NE(configuration->id, codec_id);
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted channel modes.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintChannelMode) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& channel_mode :
+ {ChannelMode::STEREO, ChannelMode::MONO, ChannelMode::DUALMONO}) {
+ // Add the hint for the channel mode.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.channelMode = channel_mode;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the channel mode is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(configuration->parameters.channelMode == channel_mode,
+ std::find(a2dp_info.channelMode.begin(),
+ a2dp_info.channelMode.end(),
+ channel_mode) != a2dp_info.channelMode.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted sampling frequencies.
+ */
+TEST_P(BluetoothAudioProviderAidl,
+ getA2dpConfiguration_hintSamplingFrequencyHz) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& sampling_frequency_hz : {
+ 0,
+ 1,
+ 8000,
+ 16000,
+ 24000,
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+ }) {
+ // Add the hint for the sampling frequency.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.samplingFrequencyHz = sampling_frequency_hz;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the sampling frequency is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(configuration->parameters.samplingFrequencyHz ==
+ sampling_frequency_hz,
+ std::find(a2dp_info.samplingFrequencyHz.begin(),
+ a2dp_info.samplingFrequencyHz.end(),
+ sampling_frequency_hz) !=
+ a2dp_info.samplingFrequencyHz.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling getA2dpConfiguration with valid remote capabilities
+ * with various hinted sampling bit-depths.
+ */
+TEST_P(BluetoothAudioProviderAidl, getA2dpConfiguration_hintBitdepth) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Test with all available codecs in the provider info.
+ for (auto const& codec_info : provider_info->codecInfos) {
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ std::optional<A2dpConfiguration> configuration{};
+ ::ndk::ScopedAStatus aidl_retval;
+
+ for (auto& bitdepth : {0, 1, 16, 24, 32}) {
+ // Add the hint for the bit depth.
+ A2dpConfigurationHint hint;
+ auto& codec_parameters = hint.codecParameters.emplace();
+ codec_parameters.bitdepth = bitdepth;
+
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{
+ A2dpRemoteCapabilities(/*seid*/ 42, codec_info.id,
+ a2dp_info.capabilities),
+ },
+ hint, &configuration);
+
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // The hint must be ignored if the bitdepth is not supported
+ // by the codec, and applied otherwise.
+ ASSERT_EQ(
+ configuration->parameters.bitdepth == bitdepth,
+ std::find(a2dp_info.bitdepth.begin(), a2dp_info.bitdepth.end(),
+ bitdepth) != a2dp_info.bitdepth.end());
+ }
+ }
+ }
+}
+
+/**
+ * Calling startSession with an unknown codec id must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_unknownCodecId) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ for (auto& codec_id :
+ {CodecId(CodecId::Core::CVSD),
+ CodecId(CodecId::Vendor(0xFCB1, 0x42) /*Google Codec #42*/)}) {
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_id;
+ a2dp_config.configuration = std::vector<uint8_t>{1, 2, 3};
+
+ auto aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+ }
+}
+
+/**
+ * Calling startSession with a known codec and a valid configuration
+ * must succeed.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_valid) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Use the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ ::ndk::ScopedAStatus aidl_retval;
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ a2dp_info.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Build the stream configuration.
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_info.id;
+ a2dp_config.configuration = configuration->configuration;
+
+ aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_TRUE(aidl_retval.isOk());
+ }
+}
+
+/**
+ * Calling startSession with a known codec but an invalid configuration
+ * must fail.
+ */
+TEST_P(BluetoothAudioProviderAidl, startSession_invalidConfiguration) {
+ for (auto& [provider, provider_info] :
+ {std::pair(a2dp_encoding_provider_, a2dp_encoding_provider_info_),
+ std::pair(a2dp_decoding_provider_, a2dp_decoding_provider_info_)}) {
+ if (provider == nullptr || !provider_info.has_value() ||
+ provider_info->codecInfos.empty()) {
+ continue;
+ }
+
+ // Use the first available codec in the provider info for testing.
+ // To get a valid configuration (the capabilities array in the provider
+ // info is not a selection), getA2dpConfiguration is used with the
+ // selected codec parameters as input.
+ ::ndk::ScopedAStatus aidl_retval;
+ auto const& codec_info = provider_info->codecInfos[0];
+ auto a2dp_info = codec_info.transport.get<CodecInfo::Transport::a2dp>();
+ A2dpRemoteCapabilities remote_capabilities(/*seid*/ 0, codec_info.id,
+ a2dp_info.capabilities);
+ std::optional<A2dpConfiguration> configuration;
+ aidl_retval = provider->getA2dpConfiguration(
+ std::vector<A2dpRemoteCapabilities>{remote_capabilities},
+ A2dpConfigurationHint(), &configuration);
+ ASSERT_TRUE(aidl_retval.isOk());
+ ASSERT_TRUE(configuration.has_value());
+
+ // Build the stream configuration but edit the configuration bytes
+ // to make it invalid.
+ A2dpStreamConfiguration a2dp_config;
+ DataMQDesc data_mq_desc;
+
+ a2dp_config.codecId = codec_info.id;
+ a2dp_config.configuration = configuration->configuration;
+ a2dp_config.configuration.push_back(42);
+
+ aidl_retval =
+ provider->startSession(audio_port_, AudioConfiguration(a2dp_config),
+ std::vector<LatencyMode>{}, &data_mq_desc);
+
+ EXPECT_FALSE(aidl_retval.isOk());
+ }
+}
+
+/**
* openProvider A2DP_SOFTWARE_ENCODING_DATAPATH
*/
class BluetoothAudioProviderA2dpEncodingSoftwareAidl
@@ -656,6 +1467,137 @@
}
/**
+ * openProvider HFP_SOFTWARE_ENCODING_DATAPATH
+ */
+class BluetoothAudioProviderHfpSoftwareEncodingAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
+ OpenProviderHelper(SessionType::HFP_SOFTWARE_ENCODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
+ ChannelMode channel_mode, int32_t data_interval_us) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample,
+ .dataIntervalUs = data_interval_us,
+ };
+ // Checking against provider capability from getProviderCapabilities
+ // For HFP software, it's
+ // BluetoothAudioCodecs::GetSoftwarePcmCapabilities();
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ if (!aidl_retval.isOk()) return false;
+ if (!data_mq.isValid()) return false;
+ return true;
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ OpenHfpSoftwareEncodingProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_ENCODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ StartAndEndHfpEncodingSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : hfp_sample_rates_) {
+ for (auto bits_per_sample : hfp_bits_per_samples_) {
+ for (auto channel_mode : hfp_channel_modes_) {
+ for (auto data_interval_us: hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
+ channel_mode, data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
+ * openProvider HFP_SOFTWARE_DECODING_DATAPATH
+ */
+class BluetoothAudioProviderHfpSoftwareDecodingAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ GetProviderCapabilitiesHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
+ OpenProviderHelper(SessionType::HFP_SOFTWARE_DECODING_DATAPATH);
+ ASSERT_NE(audio_provider_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(int32_t sample_rate, int8_t bits_per_sample,
+ ChannelMode channel_mode, int32_t data_interval_us) {
+ PcmConfiguration pcm_config{
+ .sampleRateHz = sample_rate,
+ .channelMode = channel_mode,
+ .bitsPerSample = bits_per_sample,
+ .dataIntervalUs = data_interval_us,
+ };
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(pcm_config), latency_modes, &mq_desc);
+ DataMQ data_mq(mq_desc);
+
+ if (!aidl_retval.isOk()) return false;
+ if (!data_mq.isValid()) return false;
+ return true;
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ OpenHfpSoftwareDecodingProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different PCM config
+ */
+TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ StartAndEndHfpDecodingSoftwareSessionWithPossiblePcmConfig) {
+ for (auto sample_rate : hfp_sample_rates_) {
+ for (auto bits_per_sample : hfp_bits_per_samples_) {
+ for (auto channel_mode : hfp_channel_modes_) {
+ for (auto data_interval_us: hfp_data_interval_us_) {
+ EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample,
+ channel_mode, data_interval_us));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+ }
+ }
+ }
+ }
+}
+
+/**
* openProvider A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH
*/
class BluetoothAudioProviderA2dpEncodingHardwareAidl
@@ -908,6 +1850,62 @@
}
/**
+ * openProvider HFP_HARDWARE_OFFLOAD_DATAPATH
+ */
+class BluetoothAudioProviderHfpHardwareAidl
+ : public BluetoothAudioProviderFactoryAidl {
+ public:
+ virtual void SetUp() override {
+ BluetoothAudioProviderFactoryAidl::SetUp();
+ OpenProviderHelper(SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH);
+ // Can open or empty capability
+ ASSERT_TRUE(temp_provider_capabilities_.empty() ||
+ audio_provider_ != nullptr);
+ }
+
+ virtual void TearDown() override {
+ audio_port_ = nullptr;
+ audio_provider_ = nullptr;
+ BluetoothAudioProviderFactoryAidl::TearDown();
+ }
+
+ bool OpenSession(CodecId codec_id, int connection_handle, bool nrec,
+ bool controller_codec) {
+ // Check if can open session with a Hfp configuration
+ HfpConfiguration hfp_configuration{
+ .codecId = codec_id,
+ .connectionHandle = connection_handle,
+ .nrec = nrec,
+ .controllerCodec = controller_codec,
+ };
+ DataMQDesc mq_desc;
+ auto aidl_retval = audio_provider_->startSession(
+ audio_port_, AudioConfiguration(hfp_configuration), latency_modes,
+ &mq_desc);
+
+ // Only check if aidl is ok to start session.
+ return aidl_retval.isOk();
+ }
+};
+
+/**
+ * Test whether we can open a provider of type
+ */
+TEST_P(BluetoothAudioProviderHfpHardwareAidl, OpenHfpHardwareProvider) {}
+
+/**
+ * Test whether each provider of type
+ * SessionType::HFP_SOFTWARE_DECODING_DATAPATH can be started and stopped with
+ * different HFP config
+ */
+TEST_P(BluetoothAudioProviderHfpHardwareAidl,
+ StartAndEndHfpHardwareSessionWithPossiblePcmConfig) {
+ // Try to open with a sample configuration
+ EXPECT_TRUE(OpenSession(CodecId::Core::CVSD, 6, false, true));
+ EXPECT_TRUE(audio_provider_->endSession().isOk());
+}
+
+/**
* openProvider HEARING_AID_SOFTWARE_ENCODING_DATAPATH
*/
class BluetoothAudioProviderHearingAidSoftwareAidl
@@ -2096,6 +3094,12 @@
IBluetoothAudioProviderFactory::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothAudioProviderAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
BluetoothAudioProviderA2dpEncodingSoftwareAidl);
INSTANTIATE_TEST_SUITE_P(PerInstance,
@@ -2184,6 +3188,29 @@
IBluetoothAudioProviderFactory::descriptor)),
android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpHardwareAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothAudioProviderHfpHardwareAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpSoftwareDecodingAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHfpSoftwareDecodingAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+ BluetoothAudioProviderHfpSoftwareEncodingAidl);
+INSTANTIATE_TEST_SUITE_P(PerInstance,
+ BluetoothAudioProviderHfpSoftwareEncodingAidl,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothAudioProviderFactory::descriptor)),
+ android::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
ABinderProcess_setThreadPoolMaxThreadCount(1);
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 75081d6..e7659a4 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -78,7 +78,7 @@
shared_libs: [
"libbase",
"libbinder_ndk",
- "android.hardware.bluetooth.audio-V3-ndk",
+ "android.hardware.bluetooth.audio-V4-ndk",
"libxml2",
],
test_suites: [
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index b4cba49..6e15b3b 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -41,7 +41,7 @@
namespace audio {
static const PcmCapabilities kDefaultSoftwarePcmCapabilities = {
- .sampleRateHz = {16000, 24000, 32000, 44100, 48000, 88200, 96000},
+ .sampleRateHz = {8000, 16000, 24000, 32000, 44100, 48000, 88200, 96000},
.channelMode = {ChannelMode::MONO, ChannelMode::STEREO},
.bitsPerSample = {16, 24, 32},
.dataIntervalUs = {},
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index c283148..3519ace 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -95,6 +95,8 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(CodecConfiguration{});
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ return AudioConfiguration(HfpConfiguration{});
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
@@ -154,6 +156,7 @@
session_type_ ==
SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH ||
+ session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH ||
(data_mq_ != nullptr && data_mq_->isValid()));
return stack_iface_ != nullptr && is_mq_valid && audio_config_ != nullptr;
}
@@ -275,6 +278,8 @@
bool is_software_session =
(session_type_ == SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH ||
session_type_ == SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_ENCODING_DATAPATH ||
+ session_type_ == SessionType::HFP_SOFTWARE_DECODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_DECODING_DATAPATH ||
session_type_ == SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
session_type_ ==
@@ -283,6 +288,8 @@
bool is_offload_a2dp_session =
(session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
session_type_ == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH);
+ bool is_offload_hfp_session =
+ session_type_ == SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH;
bool is_offload_le_audio_unicast_session =
(session_type_ ==
SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
@@ -297,7 +304,11 @@
audio_config_tag == AudioConfiguration::pcmConfig);
bool is_a2dp_offload_audio_config =
(is_offload_a2dp_session &&
- audio_config_tag == AudioConfiguration::a2dpConfig);
+ (audio_config_tag == AudioConfiguration::a2dp ||
+ audio_config_tag == AudioConfiguration::a2dpConfig));
+ bool is_hfp_offload_audio_config =
+ (is_offload_hfp_session &&
+ audio_config_tag == AudioConfiguration::hfpConfig);
bool is_le_audio_offload_unicast_audio_config =
(is_offload_le_audio_unicast_session &&
audio_config_tag == AudioConfiguration::leAudioConfig);
@@ -305,6 +316,7 @@
(is_offload_le_audio_broadcast_session &&
audio_config_tag == AudioConfiguration::leAudioBroadcastConfig);
if (!is_software_audio_config && !is_a2dp_offload_audio_config &&
+ !is_hfp_offload_audio_config &&
!is_le_audio_offload_unicast_audio_config &&
!is_le_audio_offload_broadcast_audio_config) {
return false;
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
index 7ae0353..5263222 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSessionControl.h
@@ -84,6 +84,8 @@
case SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(CodecConfiguration{});
+ case SessionType::HFP_HARDWARE_OFFLOAD_DATAPATH:
+ return AudioConfiguration(HfpConfiguration{});
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
return AudioConfiguration(LeAudioConfiguration{});
diff --git a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
index 3d92ee7..fd12a6e 100644
--- a/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
+++ b/bluetooth/audio/utils/aidl_session/HidlToAidlMiddleware.cpp
@@ -467,6 +467,8 @@
hidl_audio_config.codecConfig(to_hidl_codec_config_2_0(
audio_config.get<AudioConfiguration::a2dpConfig>()));
break;
+ case AudioConfiguration::a2dp:
+ break;
case AudioConfiguration::leAudioConfig:
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_config_2_1(
audio_config.get<AudioConfiguration::leAudioConfig>()));
@@ -475,6 +477,8 @@
hidl_audio_config.leAudioCodecConfig(to_hidl_leaudio_broadcast_config_2_1(
audio_config.get<AudioConfiguration::leAudioBroadcastConfig>()));
break;
+ default:
+ LOG(FATAL) << __func__ << ": unexpected AudioConfiguration";
}
return hidl_audio_config;
}
diff --git a/bluetooth/finder/aidl/Android.bp b/bluetooth/finder/aidl/Android.bp
new file mode 100644
index 0000000..e606d2d
--- /dev/null
+++ b/bluetooth/finder/aidl/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.finder",
+ vendor_available: true,
+ srcs: ["android/hardware/bluetooth/finder/*.aidl"],
+ stability: "vintf",
+
+ backend: {
+ ndk: {
+ enabled: true,
+ },
+ java: {
+ enabled: true,
+ platform_apis: true,
+ },
+ },
+}
diff --git a/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl
new file mode 100644
index 0000000..42461c5
--- /dev/null
+++ b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/Eid.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.finder;
+@VintfStability
+parcelable Eid {
+ byte[20] bytes;
+}
diff --git a/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
new file mode 100644
index 0000000..4bc9041
--- /dev/null
+++ b/bluetooth/finder/aidl/aidl_api/android.hardware.bluetooth.finder/current/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.finder;
+@VintfStability
+interface IBluetoothFinder {
+ void sendEids(in android.hardware.bluetooth.finder.Eid[] eids);
+ void setPoweredOffFinderMode(in boolean enable);
+ boolean getPoweredOffFinderMode();
+}
diff --git a/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
new file mode 100644
index 0000000..ae9b159
--- /dev/null
+++ b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/Eid.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.finder;
+
+/**
+ * Ephemeral Identifier
+ */
+@VintfStability
+parcelable Eid {
+ byte[20] bytes;
+}
diff --git a/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
new file mode 100644
index 0000000..615739b
--- /dev/null
+++ b/bluetooth/finder/aidl/android/hardware/bluetooth/finder/IBluetoothFinder.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.finder;
+
+import android.hardware.bluetooth.finder.Eid;
+
+@VintfStability
+interface IBluetoothFinder {
+ /**
+ * API to set the EIDs to the Bluetooth Controller
+ *
+ * @param eids array of 20 bytes EID to the Bluetooth
+ * controller
+ */
+ void sendEids(in Eid[] eids);
+
+ /**
+ * API to enable the powered-off finder feature, which allows the Bluetooth controller to send
+ * beacons after the device is powered off.
+ *
+ * @param enable true to enable; false to disable
+ */
+ void setPoweredOffFinderMode(in boolean enable);
+
+ /**
+ * API for retrieving feature enablement status
+ *
+ * @return the value last set by setPoweredOffFinderMode, false if setPoweredOffFinderMode was
+ * never been invoked since boot.
+ */
+ boolean getPoweredOffFinderMode();
+}
diff --git a/bluetooth/finder/aidl/default/Android.bp b/bluetooth/finder/aidl/default/Android.bp
new file mode 100644
index 0000000..b364ae1
--- /dev/null
+++ b/bluetooth/finder/aidl/default/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.bluetooth.finder-service.default",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-finder-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.finder-service.default.xml"],
+ vendor: true,
+ srcs: [
+ "BluetoothFinder.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.bluetooth.finder-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ ],
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.finder-service.default.xml",
+ srcs: ["bluetooth-finder-service-default.xml"],
+}
diff --git a/bluetooth/finder/aidl/default/BluetoothFinder.cpp b/bluetooth/finder/aidl/default/BluetoothFinder.cpp
new file mode 100644
index 0000000..236a1f8
--- /dev/null
+++ b/bluetooth/finder/aidl/default/BluetoothFinder.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BluetoothFinder.h"
+
+namespace aidl::android::hardware::bluetooth::finder::impl {
+
+::ndk::ScopedAStatus BluetoothFinder::sendEids(const ::std::vector<Eid>& keys) {
+ keys_.insert(keys_.end(), keys.begin(), keys.end());
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothFinder::setPoweredOffFinderMode(bool enable) {
+ pof_enabled_ = enable;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus BluetoothFinder::getPoweredOffFinderMode(
+ bool* _aidl_return) {
+ *_aidl_return = pof_enabled_;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::bluetooth::finder::impl
diff --git a/bluetooth/finder/aidl/default/BluetoothFinder.h b/bluetooth/finder/aidl/default/BluetoothFinder.h
new file mode 100644
index 0000000..16110f6
--- /dev/null
+++ b/bluetooth/finder/aidl/default/BluetoothFinder.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/finder/BnBluetoothFinder.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::finder::impl {
+
+using ::aidl::android::hardware::bluetooth::finder::BnBluetoothFinder;
+using ::aidl::android::hardware::bluetooth::finder::Eid;
+
+class BluetoothFinder : public BnBluetoothFinder {
+ public:
+ BluetoothFinder() = default;
+
+ ::ndk::ScopedAStatus sendEids(const ::std::vector<Eid>& keys) override;
+ ::ndk::ScopedAStatus setPoweredOffFinderMode(bool enable) override;
+ ::ndk::ScopedAStatus getPoweredOffFinderMode(bool* _aidl_return) override;
+
+ private:
+ bool pof_enabled_;
+ std::vector<Eid> keys_;
+};
+
+} // namespace aidl::android::hardware::bluetooth::finder::impl
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
new file mode 100644
index 0000000..64bbf09
--- /dev/null
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.finder-default /vendor/bin/hw/android.hardware.bluetooth.finder-service.default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ task_profiles ServicePerformance
diff --git a/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml
new file mode 100644
index 0000000..be7c00d
--- /dev/null
+++ b/bluetooth/finder/aidl/default/bluetooth-finder-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.finder</name>
+ <version>1</version>
+ <fqname>IBluetoothFinder/default</fqname>
+ </hal>
+</manifest>
diff --git a/bluetooth/finder/aidl/default/service.cpp b/bluetooth/finder/aidl/default/service.cpp
new file mode 100644
index 0000000..a117df8
--- /dev/null
+++ b/bluetooth/finder/aidl/default/service.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.finder.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothFinder.h"
+
+using ::aidl::android::hardware::bluetooth::finder::impl::BluetoothFinder;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth Finder HAL registering");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGE("failed to set thread pool max thread count");
+ return 1;
+ }
+
+ std::shared_ptr<BluetoothFinder> service =
+ ndk::SharedRefBase::make<BluetoothFinder>();
+ std::string instance =
+ std::string() + BluetoothFinder::descriptor + "/default";
+ auto result =
+ AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ if (result == STATUS_OK) {
+ ABinderProcess_joinThreadPool();
+ } else {
+ ALOGE("Could not register as a service!");
+ }
+ return 0;
+}
diff --git a/bluetooth/finder/aidl/vts/Android.bp b/bluetooth/finder/aidl/vts/Android.bp
new file mode 100644
index 0000000..6b0285e
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothFinderTargetTest",
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBluetoothFinderTargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libbinder_ndk",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.finder-V1-ndk",
+ "libbluetooth-types",
+ ],
+ test_config: "VtsHalBluetoothFinderTargetTest.xml",
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
new file mode 100644
index 0000000..be07a7d
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/finder/IBluetoothFinder.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <array>
+#include <vector>
+
+using ::aidl::android::hardware::bluetooth::finder::Eid;
+using ::aidl::android::hardware::bluetooth::finder::IBluetoothFinder;
+using ::ndk::ScopedAStatus;
+
+class BluetoothFinderTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("SetUp Finder Test");
+ bluetooth_finder = IBluetoothFinder::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(bluetooth_finder, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown Finder Test");
+ bluetooth_finder = nullptr;
+ ASSERT_EQ(bluetooth_finder, nullptr);
+ }
+
+ ScopedAStatus sendEids(uint8_t num);
+ ScopedAStatus setPoweredOffFinderMode(bool enable);
+ ScopedAStatus getPoweredOffFinderMode(bool* status);
+
+ private:
+ std::shared_ptr<IBluetoothFinder> bluetooth_finder;
+};
+
+ScopedAStatus BluetoothFinderTest::sendEids(uint8_t numKeys) {
+ std::vector<Eid> keys(numKeys);
+ for (uint_t i = 0; i < numKeys; i++) {
+ std::array<uint8_t, 20> key;
+ key.fill(i + 1);
+ keys[i].bytes = key;
+ }
+ return bluetooth_finder->sendEids(keys);
+}
+
+ScopedAStatus BluetoothFinderTest::setPoweredOffFinderMode(bool enable) {
+ return bluetooth_finder->setPoweredOffFinderMode(enable);
+}
+
+ScopedAStatus BluetoothFinderTest::getPoweredOffFinderMode(bool* status) {
+ return bluetooth_finder->getPoweredOffFinderMode(status);
+}
+
+TEST_P(BluetoothFinderTest, SendEidsSingle) {
+ ScopedAStatus status = sendEids(1);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothFinderTest, Send255Eids) {
+ ScopedAStatus status = sendEids(255);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothFinderTest, setAndGetPoweredOffFinderModeEnable) {
+ ScopedAStatus status = setPoweredOffFinderMode(true);
+ ASSERT_TRUE(status.isOk());
+ bool pof_status;
+ status = getPoweredOffFinderMode(&pof_status);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(pof_status);
+}
+
+TEST_P(BluetoothFinderTest, setAndGetPoweredOffFinderModeDisable) {
+ ScopedAStatus status = setPoweredOffFinderMode(false);
+ ASSERT_TRUE(status.isOk());
+ bool pof_status;
+ status = getPoweredOffFinderMode(&pof_status);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(!pof_status);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothFinderTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothFinderTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothFinder::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
diff --git a/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml
new file mode 100644
index 0000000..46053dd
--- /dev/null
+++ b/bluetooth/finder/aidl/vts/VtsHalBluetoothFinderTargetTest.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<configuration description="Runs VtsHalBluetoothFinderTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothFinderTargetTest->/data/local/tmp/VtsHalBluetoothFinderTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothFinderTargetTest" />
+ </test>
+</configuration>
diff --git a/bluetooth/ranging/OWNERS b/bluetooth/ranging/OWNERS
new file mode 100644
index 0000000..3d95624
--- /dev/null
+++ b/bluetooth/ranging/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 27441
+
+include platform/packages/modules/Bluetooth:/OWNERS
+
+chienyuanhuang@google.com
diff --git a/bluetooth/ranging/aidl/Android.bp b/bluetooth/ranging/aidl/Android.bp
new file mode 100644
index 0000000..9e53ef6
--- /dev/null
+++ b/bluetooth/ranging/aidl/Android.bp
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.ranging",
+ vendor_available: true,
+ host_supported: true,
+ srcs: ["android/hardware/bluetooth/ranging/*.aidl"],
+ stability: "vintf",
+ backend: {
+ ndk: {
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.btservices",
+ ],
+ min_sdk_version: "33",
+ },
+ },
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/AddressType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/AddressType.aidl
new file mode 100644
index 0000000..fc417f0
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/AddressType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum AddressType {
+ PUBLIC = 0x00,
+ RANDOM = 0x01,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
new file mode 100644
index 0000000..e8fefbe
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable BluetoothChannelSoundingParameters {
+ android.hardware.bluetooth.ranging.SessionType sessionType;
+ int aclHandle;
+ int l2capCid;
+ int realTimeProcedureDataAttHandle;
+ android.hardware.bluetooth.ranging.Role role;
+ boolean localSupportsSoundingPhaseBasedRanging;
+ boolean remoteSupportsSoundingPhaseBaseRanging;
+ android.hardware.bluetooth.ranging.Config config;
+ android.hardware.bluetooth.ranging.DeviceAddress address;
+ @nullable android.hardware.bluetooth.ranging.VendorSpecificData[] vendorSpecificData;
+ android.hardware.bluetooth.ranging.LocationType locationType;
+ android.hardware.bluetooth.ranging.SightType sightType;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
new file mode 100644
index 0000000..e7fad4d
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable ChannelSoudingRawData {
+ int procedureCounter;
+ boolean aborted;
+ android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData initiatorData;
+ android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData reflectorData;
+ byte[] stepChannels;
+ @nullable int[] toaTodInitiator;
+ @nullable int[] todToaReflector;
+ android.hardware.bluetooth.ranging.ModeType[] stepMode;
+ byte numAntennaPaths;
+ long timestampMs;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
new file mode 100644
index 0000000..9fe85da
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable ChannelSoundingSingleSideData {
+ @nullable List<android.hardware.bluetooth.ranging.StepTonePct> stepTonePcts;
+ @nullable byte[] packetQuality;
+ @nullable byte[] packetRssiDbm;
+ @nullable android.hardware.bluetooth.ranging.Nadm[] packetNadm;
+ @nullable List<android.hardware.bluetooth.ranging.ComplexNumber> packetPct1;
+ @nullable List<android.hardware.bluetooth.ranging.ComplexNumber> packetPct2;
+ byte referencePowerDbm;
+ @nullable byte[] vendorSpecificCsSingleSidedata;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ComplexNumber.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ComplexNumber.aidl
new file mode 100644
index 0000000..4d5ac21
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ComplexNumber.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable ComplexNumber {
+ double real;
+ double imaginary;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Config.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Config.aidl
new file mode 100644
index 0000000..c9ac991
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Config.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable Config {
+ android.hardware.bluetooth.ranging.ModeType modeType;
+ android.hardware.bluetooth.ranging.SubModeType subModeType;
+ android.hardware.bluetooth.ranging.RttType rttType;
+ byte[10] channelMap;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
new file mode 100644
index 0000000..6a31547
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum CsSecurityLevel {
+ NOT_SUPPORTED = 0x00,
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+ FOUR = 0x04,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/DeviceAddress.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/DeviceAddress.aidl
new file mode 100644
index 0000000..69cad5d
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/DeviceAddress.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable DeviceAddress {
+ android.hardware.bluetooth.ranging.AddressType addressType;
+ byte[6] address;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
new file mode 100644
index 0000000..004a482
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+interface IBluetoothChannelSounding {
+ @nullable android.hardware.bluetooth.ranging.VendorSpecificData[] getVendorSpecificData();
+ @nullable android.hardware.bluetooth.ranging.SessionType[] getSupportedSessionTypes();
+ android.hardware.bluetooth.ranging.CsSecurityLevel getMaxSupportedCsSecurityLevel();
+ @nullable android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSession openSession(in android.hardware.bluetooth.ranging.BluetoothChannelSoundingParameters params, in android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSessionCallback callback);
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
new file mode 100644
index 0000000..9f691b4
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+interface IBluetoothChannelSoundingSession {
+ @nullable android.hardware.bluetooth.ranging.VendorSpecificData[] getVendorSpecificReplies();
+ android.hardware.bluetooth.ranging.ResultType[] getSupportedResultTypes();
+ boolean isAbortedProcedureRequired();
+ void writeRawData(in android.hardware.bluetooth.ranging.ChannelSoudingRawData rawData);
+ void close(android.hardware.bluetooth.ranging.Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
new file mode 100644
index 0000000..d6622de
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+interface IBluetoothChannelSoundingSessionCallback {
+ void onOpened(android.hardware.bluetooth.ranging.Reason reason);
+ void onOpenFailed(android.hardware.bluetooth.ranging.Reason reason);
+ void onResult(in android.hardware.bluetooth.ranging.RangingResult result);
+ void onClose(android.hardware.bluetooth.ranging.Reason reason);
+ void onCloseFailed(android.hardware.bluetooth.ranging.Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/LocationType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/LocationType.aidl
new file mode 100644
index 0000000..d95af26
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/LocationType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum LocationType {
+ UNKNOWN = 0x00,
+ INDOOR = 0x01,
+ OUTDOOR = 0x02,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
new file mode 100644
index 0000000..75cdabc
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ModeType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum ModeType {
+ ZERO = 0x00,
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Nadm.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Nadm.aidl
new file mode 100644
index 0000000..a0aa47b
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Nadm.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum Nadm {
+ ATTACK_IS_EXTREMELY_UNLIKELY = 0x00,
+ ATTACK_IS_VERY_UNLIKELY = 0x01,
+ ATTACK_IS_UNLIKELY = 0x02,
+ ATTACK_IS_POSSIBLE = 0x03,
+ ATTACK_IS_LIKELY = 0x04,
+ ATTACK_IS_VERY_LIKELY = 0x05,
+ ATTACK_IS_EXTREMELY_LIKELY = 0x06,
+ UNKNOWN = 0xFFu8,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RangingResult.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RangingResult.aidl
new file mode 100644
index 0000000..d092b80
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RangingResult.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable RangingResult {
+ double resultMeters;
+ double errorMeters;
+ double azimuthDegrees;
+ double errorAzimuthDegrees;
+ double altitudeDegrees;
+ double errorAltitudeDegrees;
+ double delaySpreadMeters;
+ byte confidenceLevel;
+ android.hardware.bluetooth.ranging.Nadm detectedAttackLevel;
+ double velocityMetersPerSecond;
+ @nullable byte[] vendorSpecificCsRangingResultsData;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Reason.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Reason.aidl
new file mode 100644
index 0000000..ddd44fe
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Reason.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum Reason {
+ LOCAL_STACK_REQUEST,
+ HAL_INITIATED,
+ HARDWARE_INITIATED,
+ ERROR_INVALID_PARAMETER,
+ ERROR_UNKNOWN,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ResultType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ResultType.aidl
new file mode 100644
index 0000000..b3e098c
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/ResultType.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum ResultType {
+ RESULT_METERS = 0x00,
+ ERROR_METERS = 0x01,
+ AZIMUTH_DEGREES = 0x02,
+ ERROR_AZIMUTH_DEGREES = 0x03,
+ ALTITUDE_DEGREES = 0x04,
+ ERROR_ALTITUDE_DEGREES = 0x05,
+ DELAY_SPREAD_METERS = 0x06,
+ CONFIDENCE_LEVEL = 0x07,
+ SECURITY_LEVEL = 0x08,
+ VELOCITY = 0x09,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Role.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Role.aidl
new file mode 100644
index 0000000..61ee1aa
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/Role.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum Role {
+ INITIATOR = 0,
+ REFLECTOR = 1,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RttType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RttType.aidl
new file mode 100644
index 0000000..e662c07
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/RttType.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum RttType {
+ AA_COARSE = 0x00,
+ WITH_32_BIT_SOUNDING_SEQUENCE = 0x01,
+ WITH_96_BIT_SOUNDING_SEQUENCE = 0x02,
+ WITH_32_BIT_RANDOM_SEQUENCE = 0x03,
+ WITH_64_BIT_RANDOM_SEQUENCE = 0x04,
+ WITH_96_BIT_RANDOM_SEQUENCE = 0x05,
+ WITH_128_BIT_RANDOM_SEQUENCE = 0x06,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SessionType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SessionType.aidl
new file mode 100644
index 0000000..d43022f
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SessionType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum SessionType {
+ SOFTWARE_STACK_DATA_PARSING = 0,
+ HARDWARE_OFFLOAD_DATA_PARSING = 1,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SightType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SightType.aidl
new file mode 100644
index 0000000..6e96ba4
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SightType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="byte") @VintfStability
+enum SightType {
+ UNKNOWN = 0x00,
+ LINE_OF_SIGHT = 0x01,
+ NON_LINE_OF_SIGHT = 0x02,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
new file mode 100644
index 0000000..a51ba37
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/StepTonePct.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable StepTonePct {
+ List<android.hardware.bluetooth.ranging.ComplexNumber> tonePcts;
+ byte[] toneQualityIndicator;
+ const int TONE_QUALITY_GOOD = 0;
+ const int TONE_QUALITY_MEDIUM = 1;
+ const int TONE_QUALITY_LOW = 2;
+ const int TONE_QUALITY_UNAVAILABLE = 3;
+ const int EXTENSION_SLOT_NONE = 0;
+ const int EXTENSION_SLOT_TONE_NOT_EXPECTED_TO_BE_PRESENT = 1;
+ const int EXTENSION_SLOT_TONE_EXPECTED_TO_BE_PRESENT = 2;
+ const int EXTENSION_SLOT_SHIFT_AMOUNT = 4;
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
new file mode 100644
index 0000000..f660c91
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/SubModeType.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@Backing(type="int") @VintfStability
+enum SubModeType {
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+ UNUSED = 0xff,
+}
diff --git a/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/VendorSpecificData.aidl b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
new file mode 100644
index 0000000..13bf696
--- /dev/null
+++ b/bluetooth/ranging/aidl/aidl_api/android.hardware.bluetooth.ranging/current/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.ranging;
+@VintfStability
+parcelable VendorSpecificData {
+ byte[16] characteristicUuid;
+ byte[] opaqueValue;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
new file mode 100644
index 0000000..bd03213
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/AddressType.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum AddressType {
+ PUBLIC = 0x00,
+ RANDOM = 0x01,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
new file mode 100644
index 0000000..0cda847
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/BluetoothChannelSoundingParameters.aidl
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.Config;
+import android.hardware.bluetooth.ranging.DeviceAddress;
+import android.hardware.bluetooth.ranging.LocationType;
+import android.hardware.bluetooth.ranging.Role;
+import android.hardware.bluetooth.ranging.SessionType;
+import android.hardware.bluetooth.ranging.SightType;
+import android.hardware.bluetooth.ranging.VendorSpecificData;
+
+/**
+ * Parameters for IBluetoothChannelSoundingSession.openSession().
+ */
+@VintfStability
+parcelable BluetoothChannelSoundingParameters {
+ SessionType sessionType;
+ /**
+ * Acl handle of the connection.
+ */
+ int aclHandle;
+ /**
+ * L2CAP Cid, needed in case of EATT which may use dynamic channel for GATT.
+ */
+ int l2capCid;
+ /**
+ * ATT handle of the Real-time Procedure Data.
+ */
+ int realTimeProcedureDataAttHandle;
+ /**
+ * Role of the local device.
+ */
+ Role role;
+ /**
+ * If sounding phase-based ranging is supported by the local device.
+ */
+ boolean localSupportsSoundingPhaseBasedRanging;
+ /**
+ * If sounding phase-based ranging is supported by the remote device.
+ */
+ boolean remoteSupportsSoundingPhaseBaseRanging;
+ /**
+ * CS conifg used for procedure enable.
+ */
+ Config config;
+ /**
+ * Device address of the remote device.
+ */
+ DeviceAddress address;
+ /**
+ * Vendor-specific data get from remote GATT Server
+ */
+ @nullable VendorSpecificData[] vendorSpecificData;
+ /**
+ * Specifies the preferred location type of the use case (indoor, outdoor, unknown), this is
+ * used by the HAL to choose the corresponding ranging algorithm if it supports multiple
+ * algorithms
+ */
+ LocationType locationType;
+ /**
+ * Specifies the preferred sight type of the use case (line-of-sight, non-line-of-sight,
+ * unknown), this is used by the HAL to choose the corresponding ranging algorithm if it
+ * supports multiple algorithms
+ */
+ SightType sightType;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
new file mode 100644
index 0000000..3c8a62f
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoudingRawData.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ChannelSoundingSingleSideData;
+import android.hardware.bluetooth.ranging.ModeType;
+
+/**
+ * Raw ranging data of Channel Sounding.
+ */
+@VintfStability
+parcelable ChannelSoudingRawData {
+ /**
+ * Procedure counter of the CS procedure.
+ */
+ int procedureCounter;
+ /**
+ * Indicate if the procedure aborted.
+ */
+ boolean aborted;
+ /**
+ * Common data for both initator and reflector sided.
+ */
+ ChannelSoundingSingleSideData initiatorData;
+ ChannelSoundingSingleSideData reflectorData;
+ /**
+ * The channel indices of every step in a CS procedure (in time order).
+ */
+ byte[] stepChannels;
+ /**
+ * Toa_tod_initator from mode-1 or mode-3 steps in a CS procedure (in time order).
+ * Time of flight = 0.5 * (toa_tod_initiator - tod_toa_reflector).
+ */
+ @nullable int[] toaTodInitiator;
+ /**
+ * Tod_toa_reflector from mode-1 or mode-3 steps in a CS procedure (in time order).
+ * Time of flight = 0.5 * (toa_tod_initiator - tod_toa_reflector).
+ */
+ @nullable int[] todToaReflector;
+ /**
+ * CS mode (0, 1, 2, 3) of each CS step.
+ */
+ ModeType[] stepMode;
+ /**
+ * Number of antenna paths (1 to 4) reported in the CS procedure.
+ */
+ byte numAntennaPaths;
+ /**
+ * Timestamp when the procedure is created. Using epoch time in ms (e.g., 1697673127175).
+ */
+ long timestampMs;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
new file mode 100644
index 0000000..2c3f201
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ChannelSoundingSingleSideData.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ComplexNumber;
+import android.hardware.bluetooth.ranging.Nadm;
+import android.hardware.bluetooth.ranging.StepTonePct;
+
+/**
+ * Raw ranging data of Channel Sounding from either Initator or Reflector
+ */
+@VintfStability
+parcelable ChannelSoundingSingleSideData {
+ /**
+ * PCT (complex value) measured from mode-2 or mode-3 steps in a CS procedure (in time order).
+ */
+ @nullable List<StepTonePct> stepTonePcts;
+ /**
+ * Packet Quality from mode-1 or mode-3 steps in a CS procedures (in time order).
+ */
+ @nullable byte[] packetQuality;
+ /**
+ * Packet RSSI (-127 to 20) of mode-0, mode-1, or mode-3 step data, in dBm.
+ */
+ @nullable byte[] packetRssiDbm;
+ /**
+ * Packet NADM of mode-1 or mode-3 step data for attack detection.
+ */
+ @nullable Nadm[] packetNadm;
+ /**
+ * Packet_PCT1 or packet_PCT2 of mode-1 or mode-3, if sounding sequence is used and sounding
+ * phase-based ranging is supported.
+ */
+ @nullable List<ComplexNumber> packetPct1;
+ @nullable List<ComplexNumber> packetPct2;
+ /**
+ * Reference power level (-127 to 20) of the signal in the procedure, in dBm.
+ */
+ byte referencePowerDbm;
+ /**
+ * Parameter for vendors to place vendor-specific raw ranging data.
+ */
+ @nullable byte[] vendorSpecificCsSingleSidedata;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ComplexNumber.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ComplexNumber.aidl
new file mode 100644
index 0000000..5253d9f
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ComplexNumber.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+parcelable ComplexNumber {
+ double real;
+ double imaginary;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Config.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Config.aidl
new file mode 100644
index 0000000..85ae4c1
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Config.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ModeType;
+import android.hardware.bluetooth.ranging.RttType;
+import android.hardware.bluetooth.ranging.SubModeType;
+
+@VintfStability
+parcelable Config {
+ /**
+ * Main_Mode_Type of the CS conifg
+ */
+ ModeType modeType;
+ /**
+ * Sub_Mode_Type of the CS conifg
+ */
+ SubModeType subModeType;
+ /**
+ * RTT_Type of the CS conifg
+ */
+ RttType rttType;
+ /**
+ * Channel_Map of the CS conifg, this parameter contains 80 1-bit fields. The nth such field
+ * (in the range 0 to 78) contains the value for the CS channel index n.
+ *
+ * Channel n is enabled for CS procedure = 1
+ * Channel n is disabled for CS procedure = 0
+ */
+ byte[10] channelMap;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
new file mode 100644
index 0000000..3fd4424
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/CsSecurityLevel.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum CsSecurityLevel {
+ /**
+ * Ranging algorithm is not implemented.
+ */
+ NOT_SUPPORTED = 0x00,
+ /**
+ * Either CS tone or CS RTT.
+ */
+ ONE = 0x01,
+ /**
+ * 150 ns CS RTT accuracy and CS tones.
+ */
+ TWO = 0x02,
+ /**
+ * 10 ns CS RTT accuracy and CS tones.
+ */
+ THREE = 0x03,
+ /**
+ * Level 3 with the addition of CS RTT sounding sequence or random sequence
+ * payloads, and support of the Normalized Attack Detector Metric requirements.
+ */
+ FOUR = 0x04,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/DeviceAddress.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/DeviceAddress.aidl
new file mode 100644
index 0000000..c847c30
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/DeviceAddress.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.AddressType;
+
+/**
+ * Bluetooth address with address type
+ */
+@VintfStability
+parcelable DeviceAddress {
+ AddressType addressType;
+ byte[6] address;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
new file mode 100644
index 0000000..45ec79f
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.BluetoothChannelSoundingParameters;
+import android.hardware.bluetooth.ranging.CsSecurityLevel;
+import android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSession;
+import android.hardware.bluetooth.ranging.IBluetoothChannelSoundingSessionCallback;
+import android.hardware.bluetooth.ranging.Nadm;
+import android.hardware.bluetooth.ranging.SessionType;
+import android.hardware.bluetooth.ranging.VendorSpecificData;
+
+/**
+ * The interface for the Bluetooth stack to get vendor specifc data and open session
+ * for channel sounding.
+ */
+@VintfStability
+interface IBluetoothChannelSounding {
+ /**
+ * API to get vendor-specific data, the Bluetooth stack will provision the GATT server with
+ * these vendor-specific UUIDs and data.
+ *
+ * @return an array of vendor specifc data
+ */
+ @nullable VendorSpecificData[] getVendorSpecificData();
+
+ /**
+ * API to get supported session types of the HAL
+ *
+ * @return an array of supported session types
+ */
+ @nullable SessionType[] getSupportedSessionTypes();
+
+ /**
+ * API to get max supported security level (0 to 4) of CS for ranging algorithms.
+ *
+ * See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ *
+ * @return CsSecurityLevel that indicates max supported security level of CS for ranging
+ * algorithms.
+ */
+ CsSecurityLevel getMaxSupportedCsSecurityLevel();
+
+ /**
+ * API to open session for channel sounding and register the corresponeding callback
+ *
+ * @return an instance of IBluetoothChannelSoundingSession
+ */
+ @nullable IBluetoothChannelSoundingSession openSession(
+ in BluetoothChannelSoundingParameters params,
+ in IBluetoothChannelSoundingSessionCallback callback);
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
new file mode 100644
index 0000000..97b147e
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSession.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ChannelSoudingRawData;
+import android.hardware.bluetooth.ranging.Reason;
+import android.hardware.bluetooth.ranging.ResultType;
+import android.hardware.bluetooth.ranging.VendorSpecificData;
+
+/**
+ * Session of Channel Sounding get from IBluetoothChannelSounding.openSession().
+ * Used by the Bluetooth stack to get preferred config from HAL and provide raw ranging data to
+ * the HAL.
+ */
+@VintfStability
+interface IBluetoothChannelSoundingSession {
+ /**
+ * API to get vendor-specifc replies
+ *
+ * @return an array of vendor-specifc data
+ */
+ @nullable VendorSpecificData[] getVendorSpecificReplies();
+
+ /**
+ * API to obtain supported result types. The Bluetooth stack should use this function to check
+ * for supported result types and ignore unsupported types in the RangingResult.
+ *
+ * @return an array of vendor-specifc data
+ */
+ ResultType[] getSupportedResultTypes();
+
+ /**
+ * Indicate whether the HAL would like to receive raw data of abort procedures.
+ * If this function returns true, the Bluetooth stack should pass the data to the HAL using
+ * the writeRawData() function, even if the CS procedure is aborted.
+ *
+ * @return true if the HAL would like to receive raw data of abort procedures.
+ */
+ boolean isAbortedProcedureRequired();
+
+ /**
+ * API to provide raw ranging data to the HAL. The HAL converts this data into meaningful
+ * ranging results using a proprietary algorithm and then calls back to the Bluetooth stack via
+ * IBluetoothChannelSoundingSessionCallback.onResult().
+ */
+ void writeRawData(in ChannelSoudingRawData rawData);
+
+ /**
+ * Close the current session. Object is no longer useful after this method.
+ */
+ void close(Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
new file mode 100644
index 0000000..6901305
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.RangingResult;
+import android.hardware.bluetooth.ranging.Reason;
+
+/**
+ * The callback from the HAL to the stack.
+ * Register by IBluetoothChannelSoundingSession.openSession().
+ */
+@VintfStability
+interface IBluetoothChannelSoundingSessionCallback {
+ /**
+ * Invoked when IBluetoothChannelSounding.openSession() is successful.
+ */
+ void onOpened(Reason reason);
+ /**
+ * Invoked when IBluetoothChannelSounding.openSession() fails.
+ */
+ void onOpenFailed(Reason reason);
+ /**
+ * Invoked when HAL get raning result.
+ */
+ void onResult(in RangingResult result);
+ /**
+ * Invoked when IBluetoothChannelSoundingSession.close() is successful.
+ */
+ void onClose(Reason reason);
+ /**
+ * Invoked when IBluetoothChannelSoundingSession.close() fails.
+ */
+ void onCloseFailed(Reason reason);
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/LocationType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/LocationType.aidl
new file mode 100644
index 0000000..bccf291
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/LocationType.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="byte")
+enum LocationType {
+ UNKNOWN = 0x00,
+ INDOOR = 0x01,
+ OUTDOOR = 0x02,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
new file mode 100644
index 0000000..2058ae8
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ModeType.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum ModeType {
+ ZERO = 0x00,
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
new file mode 100644
index 0000000..3cfb22f
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Nadm.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="byte")
+enum Nadm {
+ ATTACK_IS_EXTREMELY_UNLIKELY = 0x00,
+ ATTACK_IS_VERY_UNLIKELY = 0x01,
+ ATTACK_IS_UNLIKELY = 0x02,
+ ATTACK_IS_POSSIBLE = 0x03,
+ ATTACK_IS_LIKELY = 0x04,
+ ATTACK_IS_VERY_LIKELY = 0x05,
+ ATTACK_IS_EXTREMELY_LIKELY = 0x06,
+ UNKNOWN = 0xFFu8,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RangingResult.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RangingResult.aidl
new file mode 100644
index 0000000..65907dd
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RangingResult.aidl
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.Nadm;
+
+/**
+ * Generic structure to return the ranging result
+ */
+@VintfStability
+parcelable RangingResult {
+ /**
+ * Estimated distance in meters.
+ */
+ double resultMeters;
+ /**
+ * Potential distance estimate error (plus or minus) in meters, always positive.
+ */
+ double errorMeters;
+ /**
+ * Azimuth Angle measurement in degrees.
+ *
+ * Azimuth of remote device in horizontal coordinate system, this measured from azimuth north
+ * and increasing eastward. When the remote device in azimuth north, this angle is 0, when the
+ * remote device in azimuth south, this angle is 180.
+ *
+ * See: <a href="https://en.wikipedia.org/wiki/Horizontal_coordinate_system">Horizontal
+ * coordinate system</a>for the details
+ *
+ * On an Android device, azimuth north is defined as the angle perpendicular away from the
+ * back of the device when holding it in portrait mode upright.
+ *
+ * The Azimuth north is defined as the direction in which the top edge of the device is
+ * facing when it is placed flat.
+ *
+ */
+ double azimuthDegrees;
+ /**
+ * Estimated error (plus or minus) of azimuth angle measurement in degrees, always positive.
+ */
+ double errorAzimuthDegrees;
+ /**
+ * Altitude Angle measurement in degrees.
+ *
+ * Altitude of remote device in horizontal coordinate system, this is the angle between the
+ * remote device and the top edge of local device. When local device is placed flat, the angle
+ * of the zenith is 90, the angle of the nadir is -90.
+ *
+ * See: https://en.wikipedia.org/wiki/Horizontal_coordinate_system
+ */
+ double altitudeDegrees;
+ /**
+ * Estimated error (plus or minus) of altitude angle measurement in degrees, always positive.
+ */
+ double errorAltitudeDegrees;
+ /**
+ * Estimated delay spread in meters of the measured channel. This is a measure of multipath
+ * richness of the channel.
+ */
+ double delaySpreadMeters;
+ /**
+ * A normalized value from 0 (low confidence) to 100 (high confidence) representing the
+ * confidence of estimated distance.
+ */
+ byte confidenceLevel;
+ /**
+ * A value representing the chance of being attacked for the measurement.
+ */
+ Nadm detectedAttackLevel;
+ /**
+ * Estimated velocity, in the direction of line between two devices, of the moving object in
+ * meters/sec.
+ */
+ double velocityMetersPerSecond;
+ /**
+ * Parameter for vendors to place vendor-specific ranging results data.
+ */
+ @nullable byte[] vendorSpecificCsRangingResultsData;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Reason.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Reason.aidl
new file mode 100644
index 0000000..4f587de
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Reason.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum Reason {
+ LOCAL_STACK_REQUEST,
+ HAL_INITIATED,
+ HARDWARE_INITIATED,
+ ERROR_INVALID_PARAMETER,
+ ERROR_UNKNOWN,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ResultType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ResultType.aidl
new file mode 100644
index 0000000..561b7dd
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/ResultType.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum ResultType {
+ RESULT_METERS = 0x00,
+ ERROR_METERS = 0x01,
+ AZIMUTH_DEGREES = 0x02,
+ ERROR_AZIMUTH_DEGREES = 0x03,
+ ALTITUDE_DEGREES = 0x04,
+ ERROR_ALTITUDE_DEGREES = 0x05,
+ DELAY_SPREAD_METERS = 0x06,
+ CONFIDENCE_LEVEL = 0x07,
+ SECURITY_LEVEL = 0x08,
+ VELOCITY = 0x09,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Role.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Role.aidl
new file mode 100644
index 0000000..b531935
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/Role.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum Role {
+ INITIATOR = 0,
+ REFLECTOR = 1,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RttType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RttType.aidl
new file mode 100644
index 0000000..6e163c9
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/RttType.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum RttType {
+ AA_COARSE = 0x00,
+ WITH_32_BIT_SOUNDING_SEQUENCE = 0x01,
+ WITH_96_BIT_SOUNDING_SEQUENCE = 0x02,
+ WITH_32_BIT_RANDOM_SEQUENCE = 0x03,
+ WITH_64_BIT_RANDOM_SEQUENCE = 0x04,
+ WITH_96_BIT_RANDOM_SEQUENCE = 0x05,
+ WITH_128_BIT_RANDOM_SEQUENCE = 0x06,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SessionType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SessionType.aidl
new file mode 100644
index 0000000..4f0d529
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SessionType.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum SessionType {
+ /**
+ * Stack parses raw data and passes it to the HAL
+ */
+ SOFTWARE_STACK_DATA_PARSING = 0,
+ /**
+ * Offloader parses raw data
+ */
+ HARDWARE_OFFLOAD_DATA_PARSING = 1
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SightType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SightType.aidl
new file mode 100644
index 0000000..14106e0
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SightType.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="byte")
+enum SightType {
+ UNKNOWN = 0x00,
+ LINE_OF_SIGHT = 0x01,
+ NON_LINE_OF_SIGHT = 0x02,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
new file mode 100644
index 0000000..99c6d65
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/StepTonePct.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+import android.hardware.bluetooth.ranging.ComplexNumber;
+
+/**
+ * Tone PCT data with quality indicator from a mode-2 or mode-3 step.
+ */
+@VintfStability
+parcelable StepTonePct {
+ List<ComplexNumber> tonePcts;
+ const int TONE_QUALITY_GOOD = 0;
+ const int TONE_QUALITY_MEDIUM = 1;
+ const int TONE_QUALITY_LOW = 2;
+ const int TONE_QUALITY_UNAVAILABLE = 3;
+ const int EXTENSION_SLOT_NONE = 0;
+ const int EXTENSION_SLOT_TONE_NOT_EXPECTED_TO_BE_PRESENT = 1;
+ const int EXTENSION_SLOT_TONE_EXPECTED_TO_BE_PRESENT = 2;
+ /**
+ * Shift amount for extension slot (bits 4 to 7).
+ */
+ const int EXTENSION_SLOT_SHIFT_AMOUNT = 4;
+ /**
+ * Tone_Quality_Indicator defined in the LE CS Subevent Result event
+ *
+ * Bits 0 to 3:
+ * 0x0 = Tone quality is good
+ * 0x1 = Tone quality is medium
+ * 0x2 = Tone quality is low
+ * 0x3 = Tone quality is unavailable
+ *
+ * Bits 4 to 7:
+ * 0x0 = Not tone extension slot
+ * 0x1 = Tone extension slot; tone not expected to be present
+ * 0x2 = Tone extension slot; tone expected to be present
+ *
+ * See: https://bluetooth.com/specifications/specs/channel-sounding-cr-pr/
+ */
+ byte[] toneQualityIndicator;
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
new file mode 100644
index 0000000..ca9bfcb
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/SubModeType.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+@VintfStability
+@Backing(type="int")
+enum SubModeType {
+ ONE = 0x01,
+ TWO = 0x02,
+ THREE = 0x03,
+ UNUSED = 0xff,
+}
diff --git a/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/VendorSpecificData.aidl b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
new file mode 100644
index 0000000..a8c9a2a
--- /dev/null
+++ b/bluetooth/ranging/aidl/android/hardware/bluetooth/ranging/VendorSpecificData.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.bluetooth.ranging;
+
+/**
+ * Vendor specific data for GATT.
+ */
+@VintfStability
+parcelable VendorSpecificData {
+ byte[16] characteristicUuid;
+ byte[] opaqueValue;
+}
diff --git a/bluetooth/ranging/aidl/default/Android.bp b/bluetooth/ranging/aidl/default/Android.bp
new file mode 100644
index 0000000..5072a43
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/Android.bp
@@ -0,0 +1,29 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.bluetooth.ranging-service.default",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-ranging-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.ranging-service.default.xml"],
+ vendor: true,
+ srcs: [
+ "BluetoothChannelSounding.cpp",
+ "BluetoothChannelSoundingSession.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.bluetooth.ranging-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ ],
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.ranging-service.default.xml",
+ srcs: ["bluetooth-ranging-service-default.xml"],
+}
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSounding.cpp b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.cpp
new file mode 100644
index 0000000..3807d4f
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BluetoothChannelSounding.h"
+
+#include "BluetoothChannelSoundingSession.h"
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+BluetoothChannelSounding::BluetoothChannelSounding() {}
+BluetoothChannelSounding::~BluetoothChannelSounding() {}
+
+ndk::ScopedAStatus BluetoothChannelSounding::getVendorSpecificData(
+ std::optional<
+ std::vector<std::optional<VendorSpecificData>>>* /*_aidl_return*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSounding::getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return) {
+ std::vector<SessionType> supported_session_types = {};
+ *_aidl_return = supported_session_types;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSounding::getMaxSupportedCsSecurityLevel(
+ CsSecurityLevel* _aidl_return) {
+ CsSecurityLevel security_level = CsSecurityLevel::NOT_SUPPORTED;
+ *_aidl_return = security_level;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSounding::openSession(
+ const BluetoothChannelSoundingParameters& /*in_params*/,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) {
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+ EX_ILLEGAL_ARGUMENT, "Invalid nullptr callback");
+ }
+ std::shared_ptr<BluetoothChannelSoundingSession> session = nullptr;
+ session = ndk::SharedRefBase::make<BluetoothChannelSoundingSession>(
+ in_callback, Reason::LOCAL_STACK_REQUEST);
+ *_aidl_return = session;
+ return ::ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSounding.h b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.h
new file mode 100644
index 0000000..d6b5c03
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSounding.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSounding.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+using ::aidl::android::hardware::bluetooth::ranging::
+ BluetoothChannelSoundingParameters;
+using ::aidl::android::hardware::bluetooth::ranging::BnBluetoothChannelSounding;
+using ::aidl::android::hardware::bluetooth::ranging::CsSecurityLevel;
+using ::aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSession;
+using ::aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSessionCallback;
+using ::aidl::android::hardware::bluetooth::ranging::SessionType;
+using ::aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+
+class BluetoothChannelSounding : public BnBluetoothChannelSounding {
+ public:
+ BluetoothChannelSounding();
+ ~BluetoothChannelSounding(); // Add the destructor declaration
+ ndk::ScopedAStatus getVendorSpecificData(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return) override;
+ ndk::ScopedAStatus getMaxSupportedCsSecurityLevel(
+ CsSecurityLevel* _aidl_return) override;
+ ndk::ScopedAStatus openSession(
+ const BluetoothChannelSoundingParameters& in_params,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) override;
+};
+
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.cpp b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.cpp
new file mode 100644
index 0000000..6c58a07
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BluetoothChannelSoundingSession.h"
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+BluetoothChannelSoundingSession::BluetoothChannelSoundingSession(
+ std::shared_ptr<IBluetoothChannelSoundingSessionCallback> callback,
+ Reason reason) {
+ callback_ = callback;
+ callback_->onOpened(reason);
+}
+
+ndk::ScopedAStatus BluetoothChannelSoundingSession::getVendorSpecificReplies(
+ std::optional<
+ std::vector<std::optional<VendorSpecificData>>>* /*_aidl_return*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::getSupportedResultTypes(
+ std::vector<ResultType>* _aidl_return) {
+ std::vector<ResultType> supported_result_types = {ResultType::RESULT_METERS};
+ *_aidl_return = supported_result_types;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::isAbortedProcedureRequired(
+ bool* _aidl_return) {
+ *_aidl_return = false;
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::writeRawData(
+ const ChannelSoudingRawData& /*in_rawData*/) {
+ RangingResult ranging_result;
+ ranging_result.resultMeters = 0.0;
+ callback_->onResult(ranging_result);
+ return ::ndk::ScopedAStatus::ok();
+}
+ndk::ScopedAStatus BluetoothChannelSoundingSession::close(Reason in_reason) {
+ callback_->onClose(in_reason);
+ return ::ndk::ScopedAStatus::ok();
+}
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.h b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.h
new file mode 100644
index 0000000..6703f7f
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/BluetoothChannelSoundingSession.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSession.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.h>
+
+#include <vector>
+
+namespace aidl::android::hardware::bluetooth::ranging::impl {
+
+using ::aidl::android::hardware::bluetooth::ranging::ChannelSoudingRawData;
+using ::aidl::android::hardware::bluetooth::ranging::Reason;
+using ::aidl::android::hardware::bluetooth::ranging::ResultType;
+using ::aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+
+class BluetoothChannelSoundingSession
+ : public BnBluetoothChannelSoundingSession {
+ public:
+ BluetoothChannelSoundingSession(
+ std::shared_ptr<IBluetoothChannelSoundingSessionCallback> callback,
+ Reason reason);
+
+ ndk::ScopedAStatus getVendorSpecificReplies(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return) override;
+ ndk::ScopedAStatus getSupportedResultTypes(
+ std::vector<ResultType>* _aidl_return) override;
+ ndk::ScopedAStatus isAbortedProcedureRequired(bool* _aidl_return) override;
+ ndk::ScopedAStatus writeRawData(
+ const ChannelSoudingRawData& in_rawData) override;
+ ndk::ScopedAStatus close(Reason in_reason) override;
+
+ private:
+ std::shared_ptr<IBluetoothChannelSoundingSessionCallback> callback_;
+};
+
+} // namespace aidl::android::hardware::bluetooth::ranging::impl
diff --git a/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.rc b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.rc
new file mode 100644
index 0000000..fabb409
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.ranging-default /vendor/bin/hw/android.hardware.bluetooth.ranging-service.default
+ class hal
+ capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+ user bluetooth
+ group bluetooth
+ task_profiles HighPerformance
diff --git a/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.xml b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.xml
new file mode 100644
index 0000000..fe3613d
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/bluetooth-ranging-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.ranging</name>
+ <version>1</version>
+ <fqname>IBluetoothChannelSounding/default</fqname>
+ </hal>
+</manifest>
diff --git a/bluetooth/ranging/aidl/default/service.cpp b/bluetooth/ranging/aidl/default/service.cpp
new file mode 100644
index 0000000..83e539e
--- /dev/null
+++ b/bluetooth/ranging/aidl/default/service.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.ranging.service.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothChannelSounding.h"
+#include "BluetoothChannelSoundingSession.h"
+
+using ::aidl::android::hardware::bluetooth::ranging::impl::
+ BluetoothChannelSounding;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth Ranging HAL registering");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGE("Failed to set thread pool max thread count");
+ return 1;
+ }
+
+ std::shared_ptr<BluetoothChannelSounding> service =
+ ndk::SharedRefBase::make<BluetoothChannelSounding>();
+ std::string instance =
+ std::string() + BluetoothChannelSounding::descriptor + "/default";
+ auto result =
+ AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ if (result == STATUS_OK) {
+ ABinderProcess_joinThreadPool();
+ } else {
+ ALOGE("Could not register as a service!");
+ }
+ return 0;
+}
diff --git a/bluetooth/ranging/aidl/vts/Android.bp b/bluetooth/ranging/aidl/vts/Android.bp
new file mode 100644
index 0000000..ead9992
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/Android.bp
@@ -0,0 +1,27 @@
+package {
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothRangingTargetTest",
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBluetoothRangingTargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.ranging-V1-ndk",
+ "libbluetooth-types",
+ ],
+ test_config: "VtsHalBluetoothRangingTargetTest.xml",
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp
new file mode 100644
index 0000000..702df95
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSessionCallback.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.h>
+#include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSoundingSessionCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+using aidl::android::hardware::bluetooth::ranging::
+ BluetoothChannelSoundingParameters;
+using aidl::android::hardware::bluetooth::ranging::
+ BnBluetoothChannelSoundingSessionCallback;
+using aidl::android::hardware::bluetooth::ranging::ChannelSoudingRawData;
+using aidl::android::hardware::bluetooth::ranging::CsSecurityLevel;
+using aidl::android::hardware::bluetooth::ranging::IBluetoothChannelSounding;
+using aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSession;
+using aidl::android::hardware::bluetooth::ranging::
+ IBluetoothChannelSoundingSessionCallback;
+using aidl::android::hardware::bluetooth::ranging::RangingResult;
+using aidl::android::hardware::bluetooth::ranging::Reason;
+using aidl::android::hardware::bluetooth::ranging::ResultType;
+using aidl::android::hardware::bluetooth::ranging::SessionType;
+using aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
+using ndk::ScopedAStatus;
+
+class BluetoothChannelSoundingSessionCallback
+ : public BnBluetoothChannelSoundingSessionCallback {
+ public:
+ ScopedAStatus onOpened(Reason reason) override;
+ ScopedAStatus onOpenFailed(Reason reason) override;
+ ScopedAStatus onResult(const RangingResult& in_result) override;
+ ScopedAStatus onClose(Reason reason) override;
+ ScopedAStatus onCloseFailed(Reason reason) override;
+};
+
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onOpened(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onOpenFailed(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onResult(
+ const RangingResult& /*in_result*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onClose(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+ScopedAStatus BluetoothChannelSoundingSessionCallback::onCloseFailed(
+ Reason /*reason*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+
+class BluetoothRangingTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("SetUp Ranging Test");
+ bluetooth_channel_sounding_ = IBluetoothChannelSounding::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(bluetooth_channel_sounding_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown Ranging Test");
+ bluetooth_channel_sounding_ = nullptr;
+ ASSERT_EQ(bluetooth_channel_sounding_, nullptr);
+ }
+
+ ScopedAStatus getVendorSpecificData(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return);
+ ScopedAStatus getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return);
+ ScopedAStatus getMaxSupportedCsSecurityLevel(CsSecurityLevel* _aidl_return);
+ ScopedAStatus openSession(
+ const BluetoothChannelSoundingParameters& in_params,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return);
+
+ ScopedAStatus initBluetoothChannelSoundingSession(
+ std::shared_ptr<IBluetoothChannelSoundingSession>* session) {
+ BluetoothChannelSoundingParameters params;
+ std::shared_ptr<BluetoothChannelSoundingSessionCallback> callback = nullptr;
+ callback =
+ ndk::SharedRefBase::make<BluetoothChannelSoundingSessionCallback>();
+ ScopedAStatus status = openSession(params, callback, session);
+ return status;
+ }
+
+ private:
+ std::shared_ptr<IBluetoothChannelSounding> bluetooth_channel_sounding_;
+};
+
+ScopedAStatus BluetoothRangingTest::getVendorSpecificData(
+ std::optional<std::vector<std::optional<VendorSpecificData>>>*
+ _aidl_return) {
+ return bluetooth_channel_sounding_->getVendorSpecificData(_aidl_return);
+}
+ScopedAStatus BluetoothRangingTest::getSupportedSessionTypes(
+ std::optional<std::vector<SessionType>>* _aidl_return) {
+ return bluetooth_channel_sounding_->getSupportedSessionTypes(_aidl_return);
+}
+
+ScopedAStatus BluetoothRangingTest::getMaxSupportedCsSecurityLevel(
+ CsSecurityLevel* _aidl_return) {
+ return bluetooth_channel_sounding_->getMaxSupportedCsSecurityLevel(
+ _aidl_return);
+}
+ScopedAStatus BluetoothRangingTest::openSession(
+ const BluetoothChannelSoundingParameters& in_params,
+ const std::shared_ptr<IBluetoothChannelSoundingSessionCallback>&
+ in_callback,
+ std::shared_ptr<IBluetoothChannelSoundingSession>* _aidl_return) {
+ return bluetooth_channel_sounding_->openSession(in_params, in_callback,
+ _aidl_return);
+}
+
+TEST_P(BluetoothRangingTest, SetupAndTearDown) {}
+
+TEST_P(BluetoothRangingTest, GetVendorSpecificData) {
+ std::optional<std::vector<std::optional<VendorSpecificData>>>
+ vendor_specific_data;
+ ScopedAStatus status = getVendorSpecificData(&vendor_specific_data);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetSupportedSessionTypes) {
+ std::optional<std::vector<SessionType>> supported_session_types;
+ ScopedAStatus status = getSupportedSessionTypes(&supported_session_types);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetMaxSupportedCsSecurityLevel) {
+ CsSecurityLevel security_level;
+ ScopedAStatus status = getMaxSupportedCsSecurityLevel(&security_level);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, OpenSession) {
+ BluetoothChannelSoundingParameters params;
+ std::shared_ptr<BluetoothChannelSoundingSessionCallback> callback = nullptr;
+ callback =
+ ndk::SharedRefBase::make<BluetoothChannelSoundingSessionCallback>();
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ ScopedAStatus status = openSession(params, callback, &session);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothRangingTest, GetVendorSpecificReplies) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ std::optional<std::vector<std::optional<VendorSpecificData>>>
+ vendor_specific_data;
+ status = session->getVendorSpecificReplies(&vendor_specific_data);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, GetSupportedResultTypes) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ std::vector<ResultType> supported_result_types;
+ status = session->getSupportedResultTypes(&supported_result_types);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, IsAbortedProcedureRequired) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ bool is_abort_procedure_required = true;
+ status = session->isAbortedProcedureRequired(&is_abort_procedure_required);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, WriteRawData) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ ChannelSoudingRawData raw_data;
+ status = session->writeRawData(raw_data);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+TEST_P(BluetoothRangingTest, CloseSession) {
+ std::shared_ptr<IBluetoothChannelSoundingSession> session;
+ auto status = initBluetoothChannelSoundingSession(&session);
+ ASSERT_TRUE(status.isOk());
+ if (session != nullptr) {
+ status = session->close(Reason::LOCAL_STACK_REQUEST);
+ ASSERT_TRUE(status.isOk());
+ }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothRangingTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothRangingTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothChannelSounding::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
\ No newline at end of file
diff --git a/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml
new file mode 100644
index 0000000..624b77e
--- /dev/null
+++ b/bluetooth/ranging/aidl/vts/VtsHalBluetoothRangingTargetTest.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<configuration description="Runs VtsHalBluetoothRangingTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalBluetoothRangingTargetTest->/data/local/tmp/VtsHalBluetoothRangingTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalBluetoothRangingTargetTest" />
+ </test>
+</configuration>
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index f82e767..4d6d81d 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -66,12 +66,7 @@
prop.maker = "Android";
prop.product = virtualRadio.getName();
- prop.supportedIdentifierTypes = vector<IdentifierType>({
- IdentifierType::AMFM_FREQUENCY_KHZ,
- IdentifierType::RDS_PI,
- IdentifierType::HD_STATION_ID_EXT,
- IdentifierType::DAB_SID_EXT,
- });
+ prop.supportedIdentifierTypes = virtualRadio.getSupportedIdentifierTypes();
prop.vendorInfo = vector<VendorKeyValue>({
{"com.android.sample", "sample"},
});
@@ -245,7 +240,10 @@
}
programInfo = makeSampleProgramInfo(sel);
}
- mIsTuneCompleted = true;
+ programInfo.infoFlags |= ProgramInfo::FLAG_SIGNAL_ACQUISITION;
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ mIsTuneCompleted = true;
+ }
if (adjustAmFmRangeLocked()) {
startProgramListUpdatesLocked({});
}
@@ -276,6 +274,32 @@
return ScopedAStatus::ok();
}
+void BroadcastRadio::handleProgramInfoUpdateRadioCallback(
+ ProgramInfo programInfo, const std::shared_ptr<ITunerCallback>& callback) {
+ callback->onCurrentProgramInfoChanged(programInfo);
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ return;
+ }
+ ProgramSelector sel = programInfo.selector;
+ auto cancelTask = [sel, callback]() { callback->onTuneFailed(Result::CANCELED, sel); };
+ programInfo.infoFlags |= ProgramInfo::FLAG_HD_SIS_ACQUISITION;
+ auto sisAcquiredTask = [this, callback, programInfo, cancelTask]() {
+ callback->onCurrentProgramInfoChanged(programInfo);
+ auto audioAcquiredTask = [this, callback, programInfo]() {
+ ProgramInfo hdProgramInfoWithAudio = programInfo;
+ hdProgramInfoWithAudio.infoFlags |= ProgramInfo::FLAG_HD_AUDIO_ACQUISITION;
+ callback->onCurrentProgramInfoChanged(hdProgramInfoWithAudio);
+ lock_guard<mutex> lk(mMutex);
+ mIsTuneCompleted = true;
+ };
+ lock_guard<mutex> lk(mMutex);
+ mTuningThread->schedule(audioAcquiredTask, cancelTask, kTuneDelayTimeMs);
+ };
+
+ lock_guard<mutex> lk(mMutex);
+ mTuningThread->schedule(sisAcquiredTask, cancelTask, kTuneDelayTimeMs);
+}
+
ScopedAStatus BroadcastRadio::tune(const ProgramSelector& program) {
LOG(DEBUG) << __func__ << ": tune to " << program.toString() << "...";
@@ -308,7 +332,7 @@
lock_guard<mutex> lk(mMutex);
programInfo = tuneInternalLocked(program);
}
- callback->onCurrentProgramInfoChanged(programInfo);
+ handleProgramInfoUpdateRadioCallback(programInfo, callback);
};
auto cancelTask = [program, callback]() { callback->onTuneFailed(Result::CANCELED, program); };
mTuningThread->schedule(task, cancelTask, kTuneDelayTimeMs);
@@ -323,7 +347,9 @@
}
// The list is not sorted here since it has already stored in VirtualRadio.
bool hasAmFmFrequency = utils::hasAmFmFrequency(current);
- uint32_t currentFreq = hasAmFmFrequency ? utils::getAmFmFrequency(current) : 0;
+ bool hasDabSId = utils::hasId(current, IdentifierType::DAB_SID_EXT);
+ uint32_t currentChannel =
+ hasAmFmFrequency ? utils::getAmFmFrequency(current) : utils::getDabSId(current);
auto found =
std::lower_bound(mProgramList.begin(), mProgramList.end(), VirtualProgram({current}));
if (directionUp) {
@@ -335,18 +361,22 @@
// jump to the first selector which is greater than and of the same band as the current
// program selector.
if (utils::tunesTo(current, found->selector)) found++;
- if (skipSubChannel && hasAmFmFrequency) {
- auto firstFound = found;
- while (utils::getAmFmFrequency(found->selector) == currentFreq) {
- if (found < mProgramList.end() - 1) {
- found++;
- } else {
- found = mProgramList.begin();
- }
- if (found == firstFound) {
- // Only one main channel exists in the program list, the tuner cannot skip
- // sub-channel to the next program selector.
- return false;
+ if (skipSubChannel) {
+ if (hasAmFmFrequency || hasDabSId) {
+ auto firstFound = found;
+ while ((hasAmFmFrequency &&
+ utils::getAmFmFrequency(found->selector) == currentChannel) ||
+ (hasDabSId && utils::getDabSId(found->selector) == currentChannel)) {
+ if (found < mProgramList.end() - 1) {
+ found++;
+ } else {
+ found = mProgramList.begin();
+ }
+ if (found == firstFound) {
+ // Only one main channel exists in the program list, the tuner cannot
+ // skip sub-channel to the next program selector.
+ return false;
+ }
}
}
}
@@ -365,9 +395,11 @@
// Otherwise, the tuner will jump to the first selector less than and of the same band
// as the current program selector.
found--;
- if (hasAmFmFrequency && utils::hasAmFmFrequency(found->selector)) {
- uint32_t nextFreq = utils::getAmFmFrequency(found->selector);
- if (nextFreq != currentFreq) {
+ if ((hasAmFmFrequency && utils::hasAmFmFrequency(found->selector)) ||
+ (hasDabSId && utils::hasId(found->selector, IdentifierType::DAB_SID_EXT))) {
+ uint32_t nextChannel = hasAmFmFrequency ? utils::getAmFmFrequency(found->selector)
+ : utils::getDabSId(found->selector);
+ if (nextChannel != currentChannel) {
jumpToFirstSubChannelLocked(found);
} else if (skipSubChannel) {
jumpToFirstSubChannelLocked(found);
@@ -400,16 +432,28 @@
}
void BroadcastRadio::jumpToFirstSubChannelLocked(vector<VirtualProgram>::const_iterator& it) const {
- if (!utils::hasAmFmFrequency(it->selector) || it == mProgramList.begin()) {
+ if (it == mProgramList.begin()) {
return;
}
- uint32_t currentFrequency = utils::getAmFmFrequency(it->selector);
- it--;
- while (it != mProgramList.begin() && utils::hasAmFmFrequency(it->selector) &&
- utils::getAmFmFrequency(it->selector) == currentFrequency) {
+ bool hasAmFmFrequency = utils::hasAmFmFrequency(it->selector);
+ bool hasDabSId = utils::hasId(it->selector, IdentifierType::DAB_SID_EXT);
+ if (hasAmFmFrequency || hasDabSId) {
+ uint32_t currentChannel = hasAmFmFrequency ? utils::getAmFmFrequency(it->selector)
+ : utils::getDabSId(it->selector);
it--;
+ while (it != mProgramList.begin()) {
+ if (hasAmFmFrequency && utils::hasAmFmFrequency(it->selector) &&
+ utils::getAmFmFrequency(it->selector) == currentChannel) {
+ it--;
+ } else if (hasDabSId && utils::hasId(it->selector, IdentifierType::DAB_SID_EXT) &&
+ utils::getDabSId(it->selector) == currentChannel) {
+ it--;
+ } else {
+ break;
+ }
+ }
+ it++;
}
- it++;
}
ScopedAStatus BroadcastRadio::seek(bool directionUp, bool skipSubChannel) {
@@ -456,7 +500,7 @@
lock_guard<mutex> lk(mMutex);
programInfo = tuneInternalLocked(nextProgram.selector);
}
- callback->onCurrentProgramInfoChanged(programInfo);
+ handleProgramInfoUpdateRadioCallback(programInfo, callback);
};
mTuningThread->schedule(task, cancelTask, kSeekDelayTimeMs);
@@ -512,7 +556,7 @@
lock_guard<mutex> lk(mMutex);
programInfo = tuneInternalLocked(utils::makeSelectorAmfm(stepTo));
}
- callback->onCurrentProgramInfoChanged(programInfo);
+ handleProgramInfoUpdateRadioCallback(programInfo, callback);
};
auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
mTuningThread->schedule(task, cancelTask, kStepDelayTimeMs);
diff --git a/broadcastradio/aidl/default/BroadcastRadio.h b/broadcastradio/aidl/default/BroadcastRadio.h
index e43d7c5..60ea907 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.h
+++ b/broadcastradio/aidl/default/BroadcastRadio.h
@@ -91,6 +91,9 @@
ProgramInfo tuneInternalLocked(const ProgramSelector& sel) REQUIRES(mMutex);
void startProgramListUpdatesLocked(const ProgramFilter& filter) REQUIRES(mMutex);
void cancelProgramListUpdateLocked() REQUIRES(mMutex);
+ void handleProgramInfoUpdateRadioCallback(ProgramInfo programInfo,
+ const std::shared_ptr<ITunerCallback>& callback)
+ EXCLUDES(mMutex);
bool findNextLocked(const ProgramSelector& current, bool directionUp, bool skipSubChannel,
VirtualProgram* nextProgram) const REQUIRES(mMutex);
void jumpToFirstSubChannelLocked(std::vector<VirtualProgram>::const_iterator& it) const
diff --git a/broadcastradio/aidl/default/VirtualProgram.cpp b/broadcastradio/aidl/default/VirtualProgram.cpp
index 19c1dcf..fab4a49 100644
--- a/broadcastradio/aidl/default/VirtualProgram.cpp
+++ b/broadcastradio/aidl/default/VirtualProgram.cpp
@@ -93,38 +93,7 @@
}
bool operator<(const VirtualProgram& lhs, const VirtualProgram& rhs) {
- auto& l = lhs.selector;
- auto& r = rhs.selector;
-
- if ((utils::hasId(l, IdentifierType::AMFM_FREQUENCY_KHZ) ||
- l.primaryId.type == IdentifierType::HD_STATION_ID_EXT) &&
- (utils::hasId(r, IdentifierType::AMFM_FREQUENCY_KHZ) ||
- r.primaryId.type == IdentifierType::HD_STATION_ID_EXT)) {
- uint32_t freq1 = utils::getAmFmFrequency(l);
- int subChannel1 = l.primaryId.type == IdentifierType::HD_STATION_ID_EXT
- ? utils::getHdSubchannel(l)
- : 0;
- uint32_t freq2 = utils::getAmFmFrequency(r);
- int subChannel2 = r.primaryId.type == IdentifierType::HD_STATION_ID_EXT
- ? utils::getHdSubchannel(r)
- : 0;
- return freq1 < freq2 || (freq1 == freq2 && (l.primaryId.type < r.primaryId.type ||
- subChannel1 < subChannel2));
- } else if (l.primaryId.type == IdentifierType::DAB_SID_EXT &&
- l.primaryId.type == IdentifierType::DAB_SID_EXT) {
- uint64_t dabFreq1 = utils::getId(l, IdentifierType::DAB_FREQUENCY_KHZ);
- uint64_t dabFreq2 = utils::getId(r, IdentifierType::DAB_FREQUENCY_KHZ);
- if (dabFreq1 != dabFreq2) {
- return dabFreq1 < dabFreq2;
- }
- return utils::getId(l, IdentifierType::DAB_ENSEMBLE) <
- utils::getId(r, IdentifierType::DAB_ENSEMBLE);
- }
-
- if (l.primaryId.type != r.primaryId.type) {
- return l.primaryId.type < r.primaryId.type;
- }
- return l.primaryId.value < r.primaryId.value;
+ return utils::ProgramSelectorComparator()(lhs.selector, rhs.selector);
}
} // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/VirtualRadio.cpp b/broadcastradio/aidl/default/VirtualRadio.cpp
index ba43d8a..d6e58cd 100644
--- a/broadcastradio/aidl/default/VirtualRadio.cpp
+++ b/broadcastradio/aidl/default/VirtualRadio.cpp
@@ -16,6 +16,7 @@
#include "VirtualRadio.h"
#include <broadcastradio-utils-aidl/Utils.h>
+#include <unordered_set>
namespace aidl::android::hardware::broadcastradio {
@@ -23,6 +24,7 @@
using ::aidl::android::hardware::broadcastradio::utils::makeSelectorDab;
using ::aidl::android::hardware::broadcastradio::utils::makeSelectorHd;
using ::std::string;
+using ::std::unordered_set;
using ::std::vector;
VirtualRadio::VirtualRadio(const string& name, const vector<VirtualProgram>& initialList)
@@ -62,6 +64,20 @@
return false;
}
+vector<IdentifierType> VirtualRadio::getSupportedIdentifierTypes() const {
+ unordered_set<IdentifierType> supportedIdentifierTypeSet;
+ for (const auto& program : mPrograms) {
+ IdentifierType type = program.selector.primaryId.type;
+ if (supportedIdentifierTypeSet.count(type)) {
+ continue;
+ }
+ supportedIdentifierTypeSet.insert(type);
+ }
+ vector<IdentifierType> supportedIdentifierTypes(supportedIdentifierTypeSet.begin(),
+ supportedIdentifierTypeSet.end());
+ return supportedIdentifierTypes;
+}
+
// get singleton of AMFM Virtual Radio
const VirtualRadio& VirtualRadio::getAmFmRadio() {
// clang-format off
@@ -103,14 +119,24 @@
static VirtualRadio dabRadioMock(
"DAB radio mock",
{
- {makeSelectorDab(/* sidExt= */ 0xA000000001u, /* ensemble= */ 0x0001u,
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C221u, /* ensemble= */ 0xCE15u,
/* freq= */ 225648u), "BBC Radio 1", "Khalid", "Talk"},
- {makeSelectorDab(/* sidExt= */ 0xB000000001u, /* ensemble= */ 0x1001u,
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C222u, /* ensemble= */ 0xCE15u,
+ /* freq= */ 225648u), "BBC Radio 2", "Khalid", "Talk"},
+ {makeSelectorDab(/* sidExt= */ 0xE10000C224u, /* ensemble= */ 0xCE15u,
+ /* freq= */ 225648u), "BBC Radio 4", "ArtistBBC1", "TitleCountry1"},
+ {makeSelectorDab(/* sidExt= */ 0x1E10000C224u, /* ensemble= */ 0xCE15u,
+ /* freq= */ 225648u), "BBC Radio 4 LW", "ArtistBBC2", "TitleCountry2"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C21Au, /* ensemble= */ 0xC181u,
/* freq= */ 222064u), "Classic FM", "Jean Sibelius", "Andante Festivo"},
- {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
- /* freq= */ 227360u), "Absolute Radio", "Coldplay", "Clocks"},
- {makeSelectorDab(/* sidExt= */ 0xB000000002u, /* ensemble= */ 0x1002u,
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C1C0u, /* ensemble= */ 0xC181u,
+ /* freq= */ 223936u), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000C1C0u, /* ensemble= */ 0xC181u,
/* freq= */ 222064u), "Absolute Radio", "Coldplay", "Clocks"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000CCE7u, /* ensemble= */ 0xC19Du,
+ /* freq= */ 218640u), "Absolute Radio Country", "ArtistCountry1", "TitleCountry1"},
+ {makeSelectorDab(/* sidExt= */ 0x0E10000CCE7u, /* ensemble= */ 0xC1A0u,
+ /* freq= */ 218640u), "Absolute Radio Country", "ArtistCountry2", "TitleCountry2"},
});
// clang-format on
return dabRadioMock;
diff --git a/broadcastradio/aidl/default/VirtualRadio.h b/broadcastradio/aidl/default/VirtualRadio.h
index ae039c4..0d70aef 100644
--- a/broadcastradio/aidl/default/VirtualRadio.h
+++ b/broadcastradio/aidl/default/VirtualRadio.h
@@ -36,6 +36,7 @@
std::string getName() const;
const std::vector<VirtualProgram>& getProgramList() const;
bool getProgram(const ProgramSelector& selector, VirtualProgram* program) const;
+ std::vector<IdentifierType> getSupportedIdentifierTypes() const;
static const VirtualRadio& getAmFmRadio();
static const VirtualRadio& getDabRadio();
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 72869cc..79d3e60 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -702,6 +702,59 @@
}
/**
+ * Test tuning with HD selector.
+ *
+ * Verifies that:
+ * - if AM/FM HD selector is not supported, the method returns NOT_SUPPORTED;
+ * - if it is supported, the method succeeds;
+ * - after a successful tune call, onCurrentProgramInfoChanged callback is
+ * invoked carrying a proper selector;
+ * - program changes to a program info with the program selector requested.
+ */
+TEST_P(BroadcastRadioHalTest, HdTune) {
+ LOG(DEBUG) << "HdTune Test";
+ auto programList = getProgramList();
+ if (!programList) {
+ printSkipped("Empty station list, tune cannot be performed");
+ return;
+ }
+ ProgramSelector hdSel = {};
+ ProgramIdentifier physicallyTunedToExpected = {};
+ bool hdStationPresent = false;
+ for (auto&& programInfo : *programList) {
+ if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
+ continue;
+ }
+ hdSel = programInfo.selector;
+ hdStationPresent = true;
+ physicallyTunedToExpected = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ,
+ bcutils::getAmFmFrequency(hdSel));
+ break;
+ }
+ if (!hdStationPresent) {
+ printSkipped("No HD stations in the list, tune cannot be performed");
+ return;
+ }
+
+ // try tuning
+ auto result = mModule->tune(hdSel);
+
+ // expect a failure if it's not supported
+ if (!bcutils::isSupported(mProperties, hdSel)) {
+ EXPECT_EQ(result.getServiceSpecificError(), resultToInt(Result::NOT_SUPPORTED));
+ return;
+ }
+ // expect a callback if it succeeds
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
+ ProgramInfo infoCb = mCallback->getCurrentProgramInfo();
+ LOG(DEBUG) << "Current program info: " << infoCb.toString();
+ // it should tune exactly to what was requested
+ EXPECT_EQ(infoCb.selector, hdSel);
+ EXPECT_EQ(infoCb.physicallyTunedTo, physicallyTunedToExpected);
+}
+
+/**
* Test tuning with DAB selector.
*
* Verifies that:
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index a139e00..3ced685 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -143,6 +143,14 @@
bool satisfies(const ProgramFilter& filter, const ProgramSelector& sel);
+struct ProgramSelectorComparator {
+ bool operator()(const ProgramSelector& lhs, const ProgramSelector& rhs) const;
+};
+
+struct ProgramInfoComparator {
+ bool operator()(const ProgramInfo& lhs, const ProgramInfo& rhs) const;
+};
+
struct ProgramInfoHasher {
size_t operator()(const ProgramInfo& info) const;
};
@@ -163,6 +171,12 @@
int getHdSubchannel(const ProgramSelector& sel);
+uint32_t getDabSId(const ProgramSelector& sel);
+
+int getDabEccCode(const ProgramSelector& sel);
+
+int getDabSCIdS(const ProgramSelector& sel);
+
bool hasAmFmFrequency(const ProgramSelector& sel);
uint32_t getAmFmFrequency(const ProgramSelector& sel);
diff --git a/broadcastradio/common/utilsaidl/src/Utils.cpp b/broadcastradio/common/utilsaidl/src/Utils.cpp
index 4c99514..b647442 100644
--- a/broadcastradio/common/utilsaidl/src/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/src/Utils.cpp
@@ -355,6 +355,55 @@
return true;
}
+bool ProgramSelectorComparator::operator()(const ProgramSelector& lhs,
+ const ProgramSelector& rhs) const {
+ if ((utils::hasId(lhs, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+ lhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT) &&
+ (utils::hasId(rhs, IdentifierType::AMFM_FREQUENCY_KHZ) ||
+ rhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT)) {
+ uint32_t freq1 = utils::getAmFmFrequency(lhs);
+ int subChannel1 = lhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT
+ ? utils::getHdSubchannel(lhs)
+ : 0;
+ uint32_t freq2 = utils::getAmFmFrequency(rhs);
+ int subChannel2 = rhs.primaryId.type == IdentifierType::HD_STATION_ID_EXT
+ ? utils::getHdSubchannel(rhs)
+ : 0;
+ return freq1 < freq2 || (freq1 == freq2 && (lhs.primaryId.type < rhs.primaryId.type ||
+ subChannel1 < subChannel2));
+ }
+ if (lhs.primaryId.type == IdentifierType::DAB_SID_EXT &&
+ rhs.primaryId.type == IdentifierType::DAB_SID_EXT) {
+ uint64_t dabFreq1 = utils::getId(lhs, IdentifierType::DAB_FREQUENCY_KHZ);
+ uint64_t dabFreq2 = utils::getId(rhs, IdentifierType::DAB_FREQUENCY_KHZ);
+ if (dabFreq1 != dabFreq2) {
+ return dabFreq1 < dabFreq2;
+ }
+ uint32_t ecc1 = utils::getDabEccCode(lhs);
+ uint32_t ecc2 = utils::getDabEccCode(rhs);
+ if (ecc1 != ecc2) {
+ return ecc1 < ecc2;
+ }
+ uint64_t dabEnsemble1 = utils::getId(lhs, IdentifierType::DAB_ENSEMBLE);
+ uint64_t dabEnsemble2 = utils::getId(rhs, IdentifierType::DAB_ENSEMBLE);
+ if (dabEnsemble1 != dabEnsemble2) {
+ return dabEnsemble1 < dabEnsemble2;
+ }
+ uint32_t sId1 = utils::getDabSId(lhs);
+ uint32_t sId2 = utils::getDabSId(rhs);
+ return sId1 < sId2 || (sId1 == sId2 && utils::getDabSCIdS(lhs) < utils::getDabSCIdS(rhs));
+ }
+
+ if (lhs.primaryId.type != rhs.primaryId.type) {
+ return lhs.primaryId.type < rhs.primaryId.type;
+ }
+ return lhs.primaryId.value < rhs.primaryId.value;
+}
+
+bool ProgramInfoComparator::operator()(const ProgramInfo& lhs, const ProgramInfo& rhs) const {
+ return ProgramSelectorComparator()(lhs.selector, rhs.selector);
+}
+
size_t ProgramInfoHasher::operator()(const ProgramInfo& info) const {
const ProgramIdentifier& id = info.selector.primaryId;
@@ -489,6 +538,21 @@
return static_cast<IdentifierType>(typeAsInt);
}
+uint32_t getDabSId(const ProgramSelector& sel) {
+ int64_t dabSidExt = getId(sel, IdentifierType::DAB_SID_EXT, /* defaultValue */ 0);
+ return static_cast<uint32_t>(dabSidExt & 0xFFFFFFFF);
+}
+
+int getDabEccCode(const ProgramSelector& sel) {
+ int64_t dabSidExt = getId(sel, IdentifierType::DAB_SID_EXT, /* defaultValue */ 0);
+ return static_cast<uint32_t>((dabSidExt >> 32) & 0xFF);
+}
+
+int getDabSCIdS(const ProgramSelector& sel) {
+ int64_t dabSidExt = getId(sel, IdentifierType::DAB_SID_EXT, /* defaultValue */ 0);
+ return static_cast<uint32_t>((dabSidExt >> 40) & 0xF);
+}
+
int getHdSubchannel(const ProgramSelector& sel) {
int64_t hdSidExt = getId(sel, IdentifierType::HD_STATION_ID_EXT, kValueForNotFoundIdentifier);
hdSidExt >>= 32; // Station ID number
diff --git a/camera/device/aidl/Android.bp b/camera/device/aidl/Android.bp
index 1a665fb..4115c65 100644
--- a/camera/device/aidl/Android.bp
+++ b/camera/device/aidl/Android.bp
@@ -11,7 +11,7 @@
name: "android.hardware.camera.device",
vendor_available: true,
srcs: ["android/hardware/camera/device/*.aidl"],
- frozen: true,
+ frozen: false,
stability: "vintf",
imports: [
"android.hardware.common-V2",
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ConfigureStreamsRet.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ConfigureStreamsRet.aidl
new file mode 100644
index 0000000..5535a30
--- /dev/null
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ConfigureStreamsRet.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.device;
+@VintfStability
+parcelable ConfigureStreamsRet {
+ android.hardware.camera.device.HalStream[] halStreams;
+ boolean enableHalBufferManager = false;
+}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
index 51c6067..f73483a 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDevice.aidl
@@ -43,4 +43,7 @@
void setTorchMode(boolean on);
void turnOnTorchWithStrengthLevel(int torchStrength);
int getTorchStrengthLevel();
+ android.hardware.camera.device.CameraMetadata constructDefaultRequestSettings(in android.hardware.camera.device.RequestTemplate type);
+ boolean isStreamCombinationWithSettingsSupported(in android.hardware.camera.device.StreamConfiguration streams);
+ android.hardware.camera.device.CameraMetadata getSessionCharacteristics(in android.hardware.camera.device.StreamConfiguration sessionConfig);
}
diff --git a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl
index 2196d37..b6ae734 100644
--- a/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl
+++ b/camera/device/aidl/aidl_api/android.hardware.camera.device/current/android/hardware/camera/device/ICameraDeviceSession.aidl
@@ -45,4 +45,5 @@
oneway void signalStreamFlush(in int[] streamIds, in int streamConfigCounter);
android.hardware.camera.device.ICameraOfflineSession switchToOffline(in int[] streamsToKeep, out android.hardware.camera.device.CameraOfflineSessionInfo offlineSessionInfo);
void repeatingRequestEnd(in int frameNumber, in int[] streamIds);
+ android.hardware.camera.device.ConfigureStreamsRet configureStreamsV2(in android.hardware.camera.device.StreamConfiguration requestedConfiguration);
}
diff --git a/camera/device/aidl/android/hardware/camera/device/ConfigureStreamsRet.aidl b/camera/device/aidl/android/hardware/camera/device/ConfigureStreamsRet.aidl
new file mode 100644
index 0000000..8f462ec
--- /dev/null
+++ b/camera/device/aidl/android/hardware/camera/device/ConfigureStreamsRet.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.camera.device;
+
+import android.hardware.camera.device.HalStream;
+
+/**
+ * ConfigureStreamsRet.
+ *
+ * Parcelable returned by the 'configureStreamsV2' call.
+ * This contains information which informs the camera framework
+ * about properties of each stream configured and also whether the
+ * the hal buffer manager must be used for the session configured.
+ */
+@VintfStability
+parcelable ConfigureStreamsRet {
+ /**
+ * A vector of HalStream Parcelables, which contain information
+ * about the stream parameters desired by the HAL such as usage flags,
+ * overridden format, maximum buffers etc.
+ */
+ HalStream[] halStreams;
+ /**
+ * A boolean informing the camera framework whether the HAL buffer manager
+ * must be used for the session configured.
+ */
+ boolean enableHalBufferManager = false;
+}
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index f940000..3a1d762 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -21,6 +21,7 @@
import android.hardware.camera.device.ICameraDeviceCallback;
import android.hardware.camera.device.ICameraDeviceSession;
import android.hardware.camera.device.ICameraInjectionSession;
+import android.hardware.camera.device.RequestTemplate;
import android.hardware.camera.device.StreamConfiguration;
import android.os.ParcelFileDescriptor;
@@ -346,4 +347,122 @@
*
*/
int getTorchStrengthLevel();
+
+ /**
+ * constructDefaultRequestSettings:
+ *
+ * This is the same as ICameraDeviceSession.constructDefaultRequestSettings, with
+ * the exception that it can be called before the ICameraDevice.open call.
+ *
+ * @param type The requested template CaptureRequest type to create the default settings for.
+ *
+ * @return capture settings for the requested use case.
+ *
+ */
+ CameraMetadata constructDefaultRequestSettings(in RequestTemplate type);
+
+ /**
+ * isStreamCombinationWithSettingsSupported:
+ *
+ * This is the same as isStreamCombinationSupported with below exceptions:
+ *
+ * 1. The input StreamConfiguration parameter may contain session parameters
+ * supported by this camera device. When checking if the particular StreamConfiguration
+ * is supported, the camera HAL must take the session parameters into consideration.
+ *
+ * 2. For version 3 of this interface, the camera compliance test will verify that
+ * isStreamCombinationWithSettingsSupported behaves properly for all combinations of
+ * below features. This function must return true for all supported combinations,
+ * and return false for non-supported feature combinations. The list of features
+ * required may grow in future versions.
+ *
+ * - Stream Combinations (a subset of LEGACY device mandatory stream combinations):
+ * {
+ * // 4:3 16:9
+ * // S1440P: 1920 x 1440 2560 x 1440
+ * // S1080P: 1440 x 1080 1920 x 1080
+ * // S720P: 960 x 720 1280 x 720
+ *
+ * // Simple preview, GPU video processing, or no-preview video recording
+ * {PRIV, MAXIMUM},
+ * {PRIV, PREVIEW},
+ * {PRIV, S1440P},
+ * {PRIV, S1080P},
+ * {PRIV, S720P},
+ * // In-application video/image processing
+ * {YUV, MAXIMUM},
+ * {YUV, PREVIEW},
+ * {YUV, S1440P},
+ * {YUV, S1080P},
+ * {YUV, S720P},
+ * // Standard still imaging.
+ * {PRIV, PREVIEW, JPEG, MAXIMUM},
+ * {PRIV, S1440P, JPEG, MAXIMUM},
+ * {PRIV, S1080P, JPEG, MAXIMUM},
+ * {PRIV, S720P, JPEG, MAXIMUM},
+ * {PRIV, S1440P, JPEG, S1440P},
+ * {PRIV, S1080P, JPEG, S1080P},
+ * {PRIV, S720P, JPEG, S1080P},
+ * // In-app processing plus still capture.
+ * {YUV, PREVIEW, JPEG, MAXIMUM},
+ * {YUV, S1440P, JPEG, MAXIMUM},
+ * {YUV, S1080P, JPEG, MAXIMUM},
+ * {YUV, S720P, JPEG, MAXIMUM},
+ * // Standard recording.
+ * {PRIV, PREVIEW, PRIV, PREVIEW},
+ * {PRIV, S1440P, PRIV, S1440P},
+ * {PRIV, S1080P, PRIV, S1080P},
+ * {PRIV, S720P, PRIV, S720P},
+ * // Preview plus in-app processing.
+ * {PRIV, PREVIEW, YUV, PREVIEW},
+ * {PRIV, S1440P, YUV, S1440P},
+ * {PRIV, S1080P, YUV, S1080P},
+ * {PRIV, S720P, YUV, S720P},
+ * }
+ * - VIDEO_STABILIZATION_MODES: {OFF, PREVIEW}
+ * - AE_TARGET_FPS_RANGE: {{*, 30}, {*, 60}}
+ * - DYNAMIC_RANGE_PROFILE: {STANDARD, HLG10}
+ *
+ * Note: If a combination contains a S1440P, S1080P, or S720P stream,
+ * both 4:3 and 16:9 aspect ratio will be considered. For example, for the
+ * stream combination of {PRIV, S1440P, JPEG, MAXIMUM}, and if MAXIMUM ==
+ * 4032 x 3024, the camera compliance test will verify both
+ * {PRIV, 1920 x 1440, JPEG, 4032 x 3024} and {PRIV, 2560 x 1440, JPEG, 4032 x 2268}.
+ *
+ * @param streams The StreamConfiguration to be tested, with optional session parameters.
+ *
+ * @return true in case the stream combination is supported, false otherwise.
+ *
+ */
+ boolean isStreamCombinationWithSettingsSupported(in StreamConfiguration streams);
+
+ /**
+ * getSessionCharacteristics
+ *
+ * Gets the session characteristics associated with a particular session
+ * configuration by the CameraDevice.
+ *
+ * For Android 15, the characteristics which need to be set are:
+ * - ANDROID_CONTROL_ZOOM_RATIO_RANGE
+ *
+ * A service specific error will be returned on the following conditions
+ * INTERNAL_ERROR:
+ * The camera device cannot be opened due to an internal
+ * error.
+ * CAMERA_DISCONNECTED:
+ * An external camera device has been disconnected, and is no longer
+ * available. This camera device interface is now stale, and a new
+ * instance must be acquired if the device is reconnected. All
+ * subsequent calls on this interface must return
+ * CAMERA_DISCONNECTED.
+ * ILLEGAL_ARGUMENT:
+ * If the given session configuration is not supported.
+ *
+ * @param sessionConfig: The session configuration for which the
+ * characteristics are being fetched.
+ *
+ * @return The static metadata for this particular session config, or an
+ * empty metadata structure if a service specific error is returned.
+ */
+ CameraMetadata getSessionCharacteristics(in StreamConfiguration sessionConfig);
}
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
index 885c71a..ffc1a11 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDeviceSession.aidl
@@ -20,6 +20,7 @@
import android.hardware.camera.device.CameraMetadata;
import android.hardware.camera.device.CameraOfflineSessionInfo;
import android.hardware.camera.device.CaptureRequest;
+import android.hardware.camera.device.ConfigureStreamsRet;
import android.hardware.camera.device.HalStream;
import android.hardware.camera.device.ICameraOfflineSession;
import android.hardware.camera.device.RequestTemplate;
@@ -88,6 +89,13 @@
* with processCaptureResult (and its respective releaseFence has been
* signaled) the framework may free or reuse it at any time.
*
+ * This method wil only be called by the framework if
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is either not advertised or is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL. If the value of
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE, configureStreamsV2
+ * will be called instead.
+ *
* ------------------------------------------------------------------------
*
* Preconditions:
@@ -386,8 +394,8 @@
* error.
* @return true in case the stream reconfiguration is required, false otherwise.
*/
- boolean isReconfigurationRequired(in CameraMetadata oldSessionParams,
- in CameraMetadata newSessionParams);
+ boolean isReconfigurationRequired(
+ in CameraMetadata oldSessionParams, in CameraMetadata newSessionParams);
/**
* processCaptureRequest:
@@ -576,4 +584,29 @@
*/
void repeatingRequestEnd(in int frameNumber, in int[] streamIds);
+ /**
+ *
+ * configureStreamsV2:
+ *
+ * Performs the same function as 'configureStreams'. This function returns a
+ * 'ConfigureStreamsRet' Parcelable. This tells the framework about the desired stream
+ * parameters such as usage flags, maximum buffers, overridden format etc. It also informs
+ * camera framework whether the HAL will use the HAL buffer manager APIs 'requestStreamBuffers'
+ * and 'returnStreamBuffers' to request and return buffers to the framework.
+ *
+ * This method is only supported if
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION is
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE. It must not be
+ * called by the camera framework if it isn't supported. That is, the framework will only
+ * ever call one of 'configureStreams' or 'configureStreamsV2' depending on the value of
+ * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION.
+ *
+ * @param requestedConfiguration The stream configuration requested by the camera framework to
+ * be configured by the camera HAL.
+ * @return A ConfigureStreamsRet Parcelable containing a vector of HalStreams and a boolean
+ * specifying whether the HAL buffer manager must be used for this session
+ * configuration.
+ *
+ */
+ ConfigureStreamsRet configureStreamsV2(in StreamConfiguration requestedConfiguration);
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 0290aef..542b296 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -98,6 +98,8 @@
ANDROID_CONTROL_AUTOFRAMING,
ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
ANDROID_CONTROL_AUTOFRAMING_STATE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
ANDROID_EDGE_STRENGTH,
@@ -283,6 +285,8 @@
ANDROID_STATISTICS_OIS_TIMESTAMPS,
ANDROID_STATISTICS_OIS_X_SHIFTS,
ANDROID_STATISTICS_OIS_Y_SHIFTS,
+ ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS,
+ ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES,
ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_STATISTICS_INFO_START /* 1179648 */,
ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT,
ANDROID_STATISTICS_INFO_MAX_FACE_COUNT,
@@ -329,6 +333,7 @@
ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_LOGICAL_MULTI_CAMERA_START /* 1703936 */,
ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE,
ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
+ ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION,
ANDROID_DISTORTION_CORRECTION_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DISTORTION_CORRECTION_START /* 1769472 */,
ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES,
ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_START /* 1835008 */,
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
index 5e1b871..c1423aa 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -44,4 +44,5 @@
ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,
}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
new file mode 100644
index 0000000..f8ae013
--- /dev/null
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlLowLightBoostState {
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE,
+}
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
index 7303ff5..2c31cff 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
@@ -39,4 +39,5 @@
@Backing(type="int") @VintfStability
enum InfoSupportedBufferManagementVersion {
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index cfc9907..03cfba1 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -490,6 +490,18 @@
*/
ANDROID_CONTROL_AUTOFRAMING_STATE,
/**
+ * android.control.lowLightBoostInfoLuminanceRange [static, float[], public]
+ *
+ * <p>The operating luminance range of low light boost measured in lux (lx).</p>
+ */
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
+ /**
+ * android.control.lowLightBoostState [dynamic, enum, public]
+ *
+ * <p>Current state of the low light boost AE mode.</p>
+ */
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
+ /**
* android.demosaic.mode [controls, enum, system]
*
* <p>Controls the quality of the demosaicing
@@ -1868,6 +1880,18 @@
*/
ANDROID_STATISTICS_OIS_Y_SHIFTS,
/**
+ * android.statistics.lensIntrinsicTimestamps [dynamic, int64[], ndk_public]
+ *
+ * <p>An array of timestamps of lens intrinsics samples, in nanoseconds.</p>
+ */
+ ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS,
+ /**
+ * android.statistics.lensIntrinsicSamples [dynamic, float[], ndk_public]
+ *
+ * <p>An array of intra-frame lens intrinsics.</p>
+ */
+ ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES,
+ /**
* android.statistics.info.availableFaceDetectModes [static, byte[], public]
*
* <p>List of face detection modes for ANDROID_STATISTICS_FACE_DETECT_MODE that are
@@ -2241,6 +2265,13 @@
*/
ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID,
/**
+ * android.logicalMultiCamera.activePhysicalSensorCropRegion [dynamic, int32[], public]
+ *
+ * <p>The current region of the active physical sensor that will be read out for this
+ * capture.</p>
+ */
+ ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION,
+ /**
* android.distortionCorrection.mode [dynamic, enum, public]
*
* <p>Mode of operation for the lens distortion correction block.</p>
@@ -2312,7 +2343,8 @@
*
* <p>Whether this camera device can support identical set of stream combinations
* involving HEIC image format, compared to the
- * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice.html#legacy-level-guaranteed-configurations">table of combinations</a> involving JPEG image format required for the device's hardware
+ * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraDevice#legacy-level-guaranteed-configurations">table of combinations</a>
+ * involving JPEG image format required for the device's hardware
* level and capabilities.</p>
*/
ANDROID_HEIC_INFO_SUPPORTED = CameraMetadataSectionStart.ANDROID_HEIC_INFO_START,
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
index e2f5553..70174be 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAeMode.aidl
@@ -35,4 +35,5 @@
ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH,
ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE,
ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH,
+ ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY,
}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
new file mode 100644
index 0000000..67591c8
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlLowLightBoostState.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.lowLightBoostState enumeration values
+ * @see ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlLowLightBoostState {
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE,
+ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
index 9522377..964d079 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/InfoSupportedBufferManagementVersion.aidl
@@ -30,4 +30,5 @@
@Backing(type="int")
enum InfoSupportedBufferManagementVersion {
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_AIDL_DEVICE,
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE,
}
diff --git a/camera/provider/aidl/Android.bp b/camera/provider/aidl/Android.bp
index 35ec976..f6b00a1 100644
--- a/camera/provider/aidl/Android.bp
+++ b/camera/provider/aidl/Android.bp
@@ -14,10 +14,10 @@
"android/hardware/camera/provider/*.aidl",
],
imports: [
- "android.hardware.camera.device-V2",
+ "android.hardware.camera.device-V3",
"android.hardware.camera.common-V1",
],
- frozen: true,
+ frozen: false,
stability: "vintf",
backend: {
java: {
diff --git a/camera/provider/aidl/vts/Android.bp b/camera/provider/aidl/vts/Android.bp
index cfcaec5..f9305bb 100644
--- a/camera/provider/aidl/vts/Android.bp
+++ b/camera/provider/aidl/vts/Android.bp
@@ -60,9 +60,9 @@
static_libs: [
"android.hardware.camera.common@1.0-helper",
"android.hardware.camera.common-V1-ndk",
- "android.hardware.camera.device-V2-ndk",
+ "android.hardware.camera.device-V3-ndk",
"android.hardware.camera.metadata-V2-ndk",
- "android.hardware.camera.provider-V2-ndk",
+ "android.hardware.camera.provider-V3-ndk",
"android.hidl.allocator@1.0",
"libgrallocusage",
"libhidlmemory",
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index def6233..e335853 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -500,6 +500,12 @@
ASSERT_TRUE(ret.isOk());
ASSERT_NE(device, nullptr);
+ int32_t interfaceVersion;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportFeatureCombinationQuery =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+
std::shared_ptr<EmptyDeviceCb> cb = ndk::SharedRefBase::make<EmptyDeviceCb>();
ret = device->open(cb, &mSession);
ALOGI("device::open returns status:%d:%d", ret.getExceptionCode(),
@@ -533,6 +539,34 @@
} else {
ASSERT_EQ(0u, rawMetadata.metadata.size());
}
+
+ if (flags::feature_combination_query()) {
+ if (supportFeatureCombinationQuery) {
+ CameraMetadata rawMetadata2;
+ ndk::ScopedAStatus ret2 =
+ device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
+
+ // TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
+ // implementation is in place.
+ if (static_cast<Status>(ret2.getServiceSpecificError()) !=
+ Status::OPERATION_NOT_SUPPORTED) {
+ ASSERT_EQ(ret.isOk(), ret2.isOk());
+ ASSERT_EQ(ret.getStatus(), ret2.getStatus());
+
+ ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
+ if (ret2.isOk()) {
+ const camera_metadata_t* metadata =
+ (camera_metadata_t*)rawMetadata2.metadata.data();
+ size_t expectedSize = rawMetadata2.metadata.size();
+ int result =
+ validate_camera_metadata_structure(metadata, &expectedSize);
+ ASSERT_TRUE((result == 0) ||
+ (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+ verifyRequestTemplate(metadata, reqTemplate);
+ }
+ }
+ }
+ }
}
ret = mSession->close();
mSession = nullptr;
@@ -588,8 +622,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
- verifyStreamCombination(device, config, /*expectedStatus*/ true, expectStreamCombQuery);
+ verifyStreamCombination(device, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -687,11 +720,7 @@
// Test the stream can actually be configured
for (auto& cti : cameraTestInfos) {
if (cti.session != nullptr) {
- camera_metadata_t* staticMeta =
- reinterpret_cast<camera_metadata_t*>(cti.staticMeta.metadata.data());
- bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
- verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true,
- expectStreamCombQuery);
+ verifyStreamCombination(cti.cameraDevice, cti.config, /*expectedStatus*/ true);
}
if (cti.session != nullptr) {
@@ -752,8 +781,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ false);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -972,8 +1000,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1191,8 +1218,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
config.streamConfigCounter = streamConfigCounter++;
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
std::vector<HalStream> halConfigs;
ndk::ScopedAStatus ret = mSession->configureStreams(config, &halConfigs);
@@ -1256,8 +1282,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE,
&config);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
@@ -1429,8 +1454,7 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config,
jpegBufferSize);
- verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true,
- /*expectStreamCombQuery*/ false);
+ verifyStreamCombination(cameraDevice, config, /*expectedStatus*/ true);
config.streamConfigCounter = streamConfigCounter++;
std::vector<HalStream> halConfigs;
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index e5bf637..8e72b3f 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -30,6 +30,7 @@
#include <aidlcommonsupport/NativeHandle.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include <com_android_internal_camera_flags.h>
#include <device_cb.h>
#include <empty_device_cb.h>
#include <grallocusage/GrallocUsageConversion.h>
@@ -39,6 +40,7 @@
#include <ui/GraphicBufferAllocator.h>
#include <regex>
#include <typeinfo>
+#include "utils/Errors.h"
using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
using ::aidl::android::hardware::camera::common::TorchModeStatus;
@@ -56,6 +58,8 @@
using ::ndk::SpAIBinder;
namespace {
+namespace flags = com::android::internal::camera::flags;
+
bool parseProviderName(const std::string& serviceDescriptor, std::string* type /*out*/,
uint32_t* id /*out*/) {
if (!type || !id) {
@@ -101,6 +105,8 @@
return true;
}
+namespace flags = com::android::internal::camera::flags;
+
const std::vector<int64_t> kMandatoryUseCases = {
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT,
ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW,
@@ -478,6 +484,38 @@
} else {
ADD_FAILURE() << "Get LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID failed!";
}
+
+ if (flags::concert_mode()) {
+ auto ret = find_camera_metadata_ro_entry(
+ metadata, ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION, &entry);
+ if ((ret == android::OK) && (entry.count > 0)) {
+ ASSERT_TRUE(entry.count == 4);
+ ASSERT_GE(entry.data.i32[0], 0); // Top must be non-negative
+ ASSERT_GE(entry.data.i32[1], 0); // Left must be non-negative
+ ASSERT_GT(entry.data.i32[2], 0); // Width must be positive
+ ASSERT_GT(entry.data.i32[3], 0); // Height must be positive
+ }
+ }
+}
+
+void CameraAidlTest::verifyLensIntrinsicsResult(const std::vector<uint8_t>& resultMetadata) {
+ if (flags::concert_mode()) {
+ camera_metadata_t* metadata = (camera_metadata_t*)resultMetadata.data();
+
+ camera_metadata_ro_entry timestampsEntry, intrinsicsEntry;
+ auto tsRet = find_camera_metadata_ro_entry(
+ metadata, ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS, ×tampsEntry);
+ auto inRet = find_camera_metadata_ro_entry(
+ metadata, ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES, &intrinsicsEntry);
+ ASSERT_EQ(tsRet, inRet);
+ ASSERT_TRUE((intrinsicsEntry.count % 5) == 0);
+ ASSERT_EQ(timestampsEntry.count, intrinsicsEntry.count / 5);
+ if (timestampsEntry.count > 0) {
+ for (size_t i = 0; i < timestampsEntry.count - 1; i++) {
+ ASSERT_GE(timestampsEntry.data.i64[i + 1], timestampsEntry.data.i64[i]);
+ }
+ }
+ }
}
Status CameraAidlTest::getPhysicalCameraIds(const camera_metadata_t* staticMeta,
@@ -1350,13 +1388,17 @@
bool hasHalBufferManager =
(0 == retcode && 1 == entry.count &&
entry.data.i32[0] == ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ bool sessionHalBufferManager =
+ (0 == retcode && 1 == entry.count &&
+ entry.data.i32[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
retcode = find_camera_metadata_ro_entry(
metadata, ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED, &entry);
bool multiResolutionStreamSupported =
(0 == retcode && 1 == entry.count &&
entry.data.u8[0] == ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE);
if (multiResolutionStreamSupported) {
- ASSERT_TRUE(hasHalBufferManager);
+ ASSERT_TRUE(hasHalBufferManager || sessionHalBufferManager);
}
std::string version, cameraId;
@@ -1859,17 +1901,32 @@
}
void CameraAidlTest::verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
- const StreamConfiguration& config, bool expectedStatus,
- bool expectStreamCombQuery) {
+ const StreamConfiguration& config,
+ bool expectedStatus) {
if (device != nullptr) {
bool streamCombinationSupported;
ScopedAStatus ret =
device->isStreamCombinationSupported(config, &streamCombinationSupported);
- // TODO: Check is unsupported operation is correct.
- ASSERT_TRUE(ret.isOk() ||
- (expectStreamCombQuery && ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION));
- if (ret.isOk()) {
- ASSERT_EQ(expectedStatus, streamCombinationSupported);
+ ASSERT_TRUE(ret.isOk());
+ ASSERT_EQ(expectedStatus, streamCombinationSupported);
+
+ if (flags::feature_combination_query()) {
+ int32_t interfaceVersion;
+ ret = device->getInterfaceVersion(&interfaceVersion);
+ ASSERT_TRUE(ret.isOk());
+ bool supportFeatureCombinationQuery =
+ (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+ if (supportFeatureCombinationQuery) {
+ ret = device->isStreamCombinationWithSettingsSupported(config,
+ &streamCombinationSupported);
+ // TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
+ // implementation is in place.
+ ASSERT_TRUE(ret.isOk() || static_cast<Status>(ret.getServiceSpecificError()) ==
+ Status::OPERATION_NOT_SUPPORTED);
+ if (ret.isOk()) {
+ ASSERT_EQ(expectedStatus, streamCombinationSupported);
+ }
+ }
}
}
}
@@ -2440,6 +2497,28 @@
}
+ndk::ScopedAStatus CameraAidlTest::configureStreams(std::shared_ptr<ICameraDeviceSession>& session,
+ const StreamConfiguration& config,
+ bool sessionHalBufferManager,
+ bool* useHalBufManager,
+ std::vector<HalStream>* halStreams) {
+ auto ret = ndk::ScopedAStatus::ok();
+ ConfigureStreamsRet aidl_return;
+ if (sessionHalBufferManager) {
+ ret = session->configureStreamsV2(config, &aidl_return);
+ } else {
+ ret = session->configureStreams(config, halStreams);
+ }
+ if (!ret.isOk()) {
+ return ret;
+ }
+ if (sessionHalBufferManager) {
+ *useHalBufManager = aidl_return.enableHalBufferManager;
+ *halStreams = std::move(aidl_return.halStreams);
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
void CameraAidlTest::configureSingleStream(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
const AvailableStream* previewThreshold, uint64_t bufferUsage, RequestTemplate reqTemplate,
@@ -2494,11 +2573,15 @@
ASSERT_NE(*session, nullptr);
*useHalBufManager = false;
+ bool sessionHalBufferManager = false;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
*useHalBufManager = (entry.data.u8[0] ==
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ sessionHalBufferManager =
+ (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
}
outputPreviewStreams.clear();
@@ -2557,7 +2640,8 @@
ASSERT_EQ(supported, true);
std::vector<HalStream> halConfigs;
- ret = (*session)->configureStreams(config, &halConfigs);
+ ret = configureStreams(*session, config, sessionHalBufferManager, useHalBufManager,
+ &halConfigs);
ALOGI("configureStreams returns status: %d:%d", ret.getExceptionCode(),
ret.getServiceSpecificError());
ASSERT_TRUE(ret.isOk());
@@ -2853,11 +2937,15 @@
ASSERT_NE(*session, nullptr);
*useHalBufManager = false;
+ bool sessionHalBufferManager = false;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
*useHalBufManager = (entry.data.u8[0] ==
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ sessionHalBufferManager =
+ (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
}
outputPreviewStreams.clear();
@@ -2912,7 +3000,9 @@
config.streamConfigCounter = streamConfigCounter;
std::vector<HalStream> halConfigs;
- ret = (*session)->configureStreams(config, &halConfigs);
+ ret = configureStreams(*session, config, sessionHalBufferManager, useHalBufManager,
+ &halConfigs);
+
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(physicalIds.size(), halConfigs.size());
*halStreams = halConfigs;
@@ -2992,11 +3082,15 @@
ASSERT_NE(*session, nullptr);
*useHalBufManager = false;
+ bool sessionHalBufferManager = false;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
*useHalBufManager = (entry.data.u8[0] ==
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ sessionHalBufferManager =
+ (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
}
outputStreams.clear();
@@ -3050,7 +3144,8 @@
ASSERT_TRUE(ret.isOk());
ASSERT_EQ(supported, true);
- ret = (*session)->configureStreams(config, halStreams);
+ ret = configureStreams(*session, config, sessionHalBufferManager, useHalBufManager, halStreams);
+
ASSERT_TRUE(ret.isOk());
if (*useHalBufManager) {
@@ -3434,11 +3529,15 @@
}
*useHalBufManager = false;
+ bool sessionHalBufferManager = false;
status = find_camera_metadata_ro_entry(
staticMeta, ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &entry);
if ((0 == status) && (entry.count == 1)) {
*useHalBufManager = (entry.data.u8[0] ==
ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
+ sessionHalBufferManager =
+ (entry.data.u8[0] ==
+ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
}
auto st = getJpegBufferSize(staticMeta, jpegBufferSize);
@@ -3491,7 +3590,8 @@
StreamConfiguration config = {streams, StreamConfigurationMode::NORMAL_MODE, CameraMetadata()};
- (*session)->configureStreams(config, halStreams);
+ ret = configureStreams(*session, config, sessionHalBufferManager, useHalBufManager, halStreams);
+
ASSERT_TRUE(ret.isOk());
if (*useHalBufManager) {
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index 0ebd4ef..b51544f 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -64,6 +64,7 @@
using ::aidl::android::hardware::camera::device::BufferRequestStatus;
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::CaptureResult;
+using ::aidl::android::hardware::camera::device::ConfigureStreamsRet;
using ::aidl::android::hardware::camera::device::ErrorCode;
using ::aidl::android::hardware::camera::device::HalStream;
using ::aidl::android::hardware::camera::device::ICameraDevice;
@@ -201,6 +202,11 @@
int32_t* partialResultCount /*out*/, std::shared_ptr<DeviceCb>* outCb /*out*/,
int32_t* jpegBufferSize /*out*/, bool* useHalBufManager /*out*/);
+ ndk::ScopedAStatus configureStreams(std::shared_ptr<ICameraDeviceSession>& session,
+ const StreamConfiguration& config,
+ bool sessionHalBufferManager, bool* useHalBufManager,
+ std::vector<HalStream>* halStreams);
+
void configureStreams(
const std::string& name, const std::shared_ptr<ICameraProvider>& provider,
PixelFormat format, std::shared_ptr<ICameraDeviceSession>* session /*out*/,
@@ -273,12 +279,13 @@
static void verifySettingsOverrideCharacteristics(const camera_metadata_t* metadata);
static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
- const StreamConfiguration& config, bool expectedStatus,
- bool expectStreamCombQuery);
+ const StreamConfiguration& config, bool expectedStatus);
static void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
const std::vector<uint8_t>& resultMetadata);
+ static void verifyLensIntrinsicsResult(const std::vector<uint8_t>& resultMetadata);
+
static void verifyBuffersReturned(const std::shared_ptr<ICameraDeviceSession>& session,
int32_t streamId, const std::shared_ptr<DeviceCb>& cb,
uint32_t streamConfigCounter = 0);
@@ -617,6 +624,7 @@
// device@<major>.<minor>/<type>/id
const char* kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/\\s+/(.+)";
const std::string CAMERA_DEVICE_API_VERSION_1 = "1.1";
+const int32_t CAMERA_DEVICE_API_MINOR_VERSION_3 = 3;
const int32_t kMaxVideoWidth = 4096;
const int32_t kMaxVideoHeight = 2160;
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index 7e0969a..2c11d3f 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -388,15 +388,16 @@
// Verify logical camera result metadata
bool isLogicalCamera =
Status::OK == CameraAidlTest::isLogicalMultiCamera(staticMetadataBuffer);
+ camera_metadata_t* collectedMetadata =
+ const_cast<camera_metadata_t*>(request->collectedResult.getAndLock());
+ uint8_t* rawMetadata = reinterpret_cast<uint8_t*>(collectedMetadata);
+ std::vector metadata =
+ std::vector(rawMetadata, rawMetadata + get_camera_metadata_size(collectedMetadata));
if (isLogicalCamera) {
- camera_metadata_t* collectedMetadata =
- const_cast<camera_metadata_t*>(request->collectedResult.getAndLock());
- uint8_t* rawMetadata = reinterpret_cast<uint8_t*>(collectedMetadata);
- std::vector metadata = std::vector(
- rawMetadata, rawMetadata + get_camera_metadata_size(collectedMetadata));
CameraAidlTest::verifyLogicalCameraResult(staticMetadataBuffer, metadata);
- request->collectedResult.unlock(collectedMetadata);
}
+ CameraAidlTest::verifyLensIntrinsicsResult(metadata);
+ request->collectedResult.unlock(collectedMetadata);
}
uint32_t numBuffersReturned = results.outputBuffers.size();
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index b3ca293..9bee3b9 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -90,7 +90,7 @@
"compatibility_matrix.9.xml",
],
kernel_configs: [
- "kernel_config_v_5.15",
"kernel_config_v_6.1",
+ "kernel_config_v_6.6",
],
}
diff --git a/compatibility_matrices/compatibility_matrix.8.xml b/compatibility_matrices/compatibility_matrix.8.xml
index 9057788..777eb84 100644
--- a/compatibility_matrices/compatibility_matrix.8.xml
+++ b/compatibility_matrices/compatibility_matrix.8.xml
@@ -116,7 +116,7 @@
</hal>
<hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.biometrics.face</name>
- <version>3</version>
+ <version>3-4</version>
<interface>
<name>IFace</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 2f33a28..328f1c8 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -134,7 +134,7 @@
</hal>
<hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.biometrics.fingerprint</name>
- <version>3</version>
+ <version>3-4</version>
<interface>
<name>IFingerprint</name>
<instance>default</instance>
@@ -157,6 +157,22 @@
</interface>
</hal>
<hal format="aidl" optional="true">
+ <name>android.hardware.bluetooth.ranging</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothChannelSounding</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
+ <name>android.hardware.bluetooth.finder</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothFinder</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl" optional="true">
<name>android.hardware.boot</name>
<interface>
<name>IBootControl</name>
@@ -173,7 +189,7 @@
</hal>
<hal format="aidl" optional="true" updatable-via-apex="true">
<name>android.hardware.camera.provider</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>ICameraProvider</name>
<regex-instance>[^/]+/[0-9]+</regex-instance>
@@ -251,7 +267,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.health</name>
- <version>1-2</version>
+ <version>3</version>
<interface>
<name>IHealth</name>
<instance>default</instance>
@@ -569,7 +585,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.thermal</name>
- <version>1</version>
+ <version>2</version>
<interface>
<name>IThermal</name>
<instance>default</instance>
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
index d0099ff..4e99082 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHubCallback.aidl
@@ -40,5 +40,6 @@
void handleTransactionResult(in int transactionId, in boolean success);
void handleNanSessionRequest(in android.hardware.contexthub.NanSessionRequest request);
byte[16] getUuid();
+ String getName();
const int CONTEXTHUB_NAN_TRANSACTION_TIMEOUT_MS = 10000;
}
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index 9683d2d..fea1079 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -147,7 +147,7 @@
/**
* Register a callback for the HAL implementation to send asynchronous messages to the service
- * from a Context hub. There can only be one callback registered for a single Context Hub ID.
+ * from a Context hub. Each HAL client can only have one callback for each Context Hub ID.
*
* A call to this function when a callback has already been registered must override the
* previous registration.
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
index 41fb266..ebfc4d8 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHubCallback.aidl
@@ -92,13 +92,21 @@
/**
* This callback is passed to the HAL implementation to allow the HAL to request a UUID that
- * uniquely identifies an IContextHubCallback.
+ * uniquely identifies a client.
*
* @return a byte array representating the UUID
*/
byte[16] getUuid();
/**
+ * This callback gets the name of a client implementing this IContextHubCallback interface,
+ * which must be a hard-coded string and does not change at runtime.
+ *
+ * <p>The name provides a human-readable way to identify a client for troubleshooting purpose.
+ */
+ String getName();
+
+ /**
* Amount of time, in milliseconds, that a handleNanSessionRequest can be pending before the
* Contexthub service must respond.
*/
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index e780857..76b25b6 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -49,8 +49,9 @@
using ::android::hardware::contexthub::vts_utils::waitForCallback;
// 6612b522-b717-41c8-b48d-c0b1cc64e142
-const std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
- 0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+constexpr std::array<uint8_t, 16> kUuid = {0x66, 0x12, 0xb5, 0x22, 0xb7, 0x17, 0x41, 0xc8,
+ 0xb4, 0x8d, 0xc0, 0xb1, 0xcc, 0x64, 0xe1, 0x42};
+const String16 kName{"VtsAidlHalContextHubTargetTest"};
class ContextHubAidl : public testing::TestWithParam<std::tuple<std::string, int32_t>> {
public:
@@ -135,6 +136,11 @@
*out_uuid = kUuid;
return Status::ok();
}
+
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
};
TEST_P(ContextHubAidl, TestRegisterCallback) {
@@ -171,6 +177,11 @@
return Status::ok();
}
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
+
std::promise<std::vector<NanoappInfo>> promise;
};
@@ -242,6 +253,11 @@
return Status::ok();
}
+ Status getName(::android::String16* out_name) override {
+ *out_name = kName;
+ return Status::ok();
+ }
+
uint32_t expectedTransactionId = 0;
std::promise<bool> promise;
};
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
index f02f8aa..ee004d6 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Capability.aidl
@@ -45,4 +45,5 @@
BOOT_DISPLAY_CONFIG = 5,
HDR_OUTPUT_CONVERSION_CONFIG = 6,
REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
+ LAYER_LIFECYCLE_BATCH_COMMAND = 8,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
index 7632707..06ed922 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -37,4 +37,5 @@
android.hardware.graphics.composer3.Buffer buffer;
android.hardware.graphics.common.Dataspace dataspace;
android.hardware.graphics.common.Rect[] damage;
+ float hdrSdrRatio = 1.0f;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
index 00598eb..e6db116 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayRequest.aidl
@@ -37,12 +37,12 @@
long display;
int mask;
android.hardware.graphics.composer3.DisplayRequest.LayerRequest[] layerRequests;
- const int FLIP_CLIENT_TARGET = (1 << 0);
- const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1);
+ const int FLIP_CLIENT_TARGET = (1 << 0) /* 1 */;
+ const int WRITE_CLIENT_TARGET_TO_OUTPUT = (1 << 1) /* 2 */;
@VintfStability
parcelable LayerRequest {
long layer;
int mask;
- const int CLEAR_CLIENT_TARGET = (1 << 0);
+ const int CLEAR_CLIENT_TARGET = (1 << 0) /* 1 */;
}
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
index 1990350..89dae83 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/FormatColorComponent.aidl
@@ -34,8 +34,8 @@
package android.hardware.graphics.composer3;
@Backing(type="byte") @VintfStability
enum FormatColorComponent {
- FORMAT_COMPONENT_0 = (1 << 0),
- FORMAT_COMPONENT_1 = (1 << 1),
- FORMAT_COMPONENT_2 = (1 << 2),
- FORMAT_COMPONENT_3 = (1 << 3),
+ FORMAT_COMPONENT_0 = (1 << 0) /* 1 */,
+ FORMAT_COMPONENT_1 = (1 << 1) /* 2 */,
+ FORMAT_COMPONENT_2 = (1 << 2) /* 4 */,
+ FORMAT_COMPONENT_3 = (1 << 3) /* 8 */,
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
index 7e62f5e..e64bd52 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -44,5 +44,5 @@
oneway void onVsyncPeriodTimingChanged(long display, in android.hardware.graphics.composer3.VsyncPeriodChangeTimeline updatedTimeline);
oneway void onVsyncIdle(long display);
oneway void onRefreshRateChangedDebug(in android.hardware.graphics.composer3.RefreshRateChangedDebugData data);
- oneway void onHotplugEvent(long display, android.hardware.graphics.common.DisplayHotplugEvent event);
+ void onHotplugEvent(long display, android.hardware.graphics.common.DisplayHotplugEvent event);
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
index 6d32218..87c8c18 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -55,4 +55,6 @@
@nullable android.hardware.graphics.composer3.PerFrameMetadataBlob[] perFrameMetadataBlob;
@nullable android.hardware.graphics.common.Rect[] blockingRegion;
@nullable int[] bufferSlotsToClear;
+ android.hardware.graphics.composer3.LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
+ int newBufferSlotCount;
}
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
new file mode 100644
index 0000000..ac78cd5
--- /dev/null
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.graphics.composer3;
+@Backing(type="int") @VintfStability
+enum LayerLifecycleBatchCommandType {
+ MODIFY = 0,
+ CREATE = 1,
+ DESTROY = 2,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
index 4638610..1dfc074 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Capability.aidl
@@ -86,4 +86,14 @@
* @see IComposerCallback.onRefreshRateChangedDebug
*/
REFRESH_RATE_CHANGED_CALLBACK_DEBUG = 7,
+
+ /**
+ * Specifies that the device HAL supports the batching of layer creation and destruction
+ * for better performance.
+ *
+ * @see IComposerClient.executeCommands
+ * @see LayerCommand.layerLifecycleBatchCommandType
+ * @see LayerCommand.newBufferSlotCount
+ */
+ LAYER_LIFECYCLE_BATCH_COMMAND = 8,
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
index 56488d5..bc9f63a 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ClientTarget.aidl
@@ -36,4 +36,14 @@
* The surface damage regions.
*/
Rect[] damage;
+
+ /**
+ * The HDR/SDR ratio.
+ * Only meaningful for extended_range client targets to communicate the amount of HDR heaedroom
+ * inside the client target. For floating point client targets, this means that for each color
+ * channel the maximum SDR luminance is 1.0, and the maximum display relative luminance is
+ * the hdrSdrRatio.
+ * Note that this ratio is meant to be >= 1.0.
+ */
+ float hdrSdrRatio = 1.0f;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
index 5df140d..96eccd7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerCallback.aidl
@@ -138,5 +138,5 @@
* @param display is the display that triggers the hotplug event.
* @param event is the type of event that occurred.
*/
- oneway void onHotplugEvent(long display, DisplayHotplugEvent event);
+ void onHotplugEvent(long display, DisplayHotplugEvent event);
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index fd50be9..e961c48 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -23,6 +23,7 @@
import android.hardware.graphics.composer3.Buffer;
import android.hardware.graphics.composer3.Color;
import android.hardware.graphics.composer3.LayerBrightness;
+import android.hardware.graphics.composer3.LayerLifecycleBatchCommandType;
import android.hardware.graphics.composer3.ParcelableBlendMode;
import android.hardware.graphics.composer3.ParcelableComposition;
import android.hardware.graphics.composer3.ParcelableDataspace;
@@ -265,4 +266,17 @@
* be freed.
*/
@nullable int[] bufferSlotsToClear;
+
+ /**
+ * Specifies if this layer command is on type modify, create or destroy.
+ * This command is replacing the older IComposerClient.createLayer and destroyLayer
+ * and making it more efficient with reduced aidls to the HAL.
+ * The HAL will report the errors by setting CommandResultPayload::CommandError.
+ */
+ LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
+
+ /**
+ * Specifies the number of buffer slot to be reserved.
+ */
+ int newBufferSlotCount;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
new file mode 100644
index 0000000..ec2d55f
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+/**
+ * Possible batch command types for a given layer.
+ */
+@VintfStability
+@Backing(type="int")
+enum LayerLifecycleBatchCommandType {
+ /**
+ * Layer attributes are being modified for already created layer.
+ */
+ MODIFY = 0,
+ /**
+ * This indicates that the current LayerCommand should also create the layer,
+ * before processing the other attributes in the LayerCommand.
+ */
+ CREATE = 1,
+ /**
+ * This indicates that the current LayerCommand should also destroyes the layer,
+ * after processing the other attributes in the LayerCommand.
+ */
+ DESTROY = 2,
+}
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index 92ed6d3..a1ccbfe 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -29,6 +29,7 @@
#include <aidl/android/hardware/graphics/composer3/Composition.h>
#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
+#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
@@ -83,11 +84,13 @@
}
void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
- int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) {
+ int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage,
+ float hdrSdrRatio) {
ClientTarget clientTargetCommand;
clientTargetCommand.buffer = getBufferCommand(slot, target, acquireFence);
clientTargetCommand.dataspace = dataspace;
clientTargetCommand.damage.assign(damage.begin(), damage.end());
+ clientTargetCommand.hdrSdrRatio = hdrSdrRatio;
getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand));
}
@@ -97,6 +100,15 @@
getBufferCommand(slot, buffer, releaseFence));
}
+ void setLayerLifecycleBatchCommandType(int64_t display, int64_t layer,
+ LayerLifecycleBatchCommandType cmd) {
+ getLayerCommand(display, layer).layerLifecycleBatchCommandType = cmd;
+ }
+
+ void setNewBufferSlotCount(int64_t display, int64_t layer, int32_t newBufferSlotToCount) {
+ getLayerCommand(display, layer).newBufferSlotCount = newBufferSlotToCount;
+ }
+
void validateDisplay(int64_t display,
std::optional<ClockMonotonicTimestamp> expectedPresentTime,
int32_t frameIntervalNs) {
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 58eca6e..2e3f4df 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -500,7 +500,7 @@
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
- clientDataspace, std::vector<common::Rect>(1, damage));
+ clientDataspace, std::vector<common::Rect>(1, damage), 1.f);
layer->setToClientComposition(*mWriter);
mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
VtsComposerClient::kNoFrameIntervalNs);
@@ -608,7 +608,7 @@
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
- clientDataspace, std::vector<common::Rect>(1, clientFrame));
+ clientDataspace, std::vector<common::Rect>(1, clientFrame), 1.f);
clientLayer->setToClientComposition(*mWriter);
mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
VtsComposerClient::kNoFrameIntervalNs);
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 7fcf2e4..2bbaf29 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1828,7 +1828,7 @@
auto& writer = getWriter(getPrimaryDisplayId());
writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
- Dataspace::UNKNOWN, std::vector<Rect>());
+ Dataspace::UNKNOWN, std::vector<Rect>(), 1.0f);
execute();
}
@@ -2927,6 +2927,69 @@
}
}
+class GraphicsComposerAidlBatchedCommandTest : public GraphicsComposerAidlCommandTest {
+ protected:
+ void SetUp() override {
+ GraphicsComposerAidlCommandTest::SetUp();
+ if (getInterfaceVersion() <= 2) {
+ GTEST_SKIP() << "Device interface version is expected to be >= 3";
+ }
+ }
+ void TearDown() override {
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
+ }
+};
+
+TEST_P(GraphicsComposerAidlBatchedCommandTest, CreateBatchedCommand) {
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlBatchedCommandTest, DestroyBatchedCommand) {
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+ writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::DESTROY);
+ layer++;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::CREATE);
+ writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+}
+
+TEST_P(GraphicsComposerAidlBatchedCommandTest, NoCreateDestroyBatchedCommandIncorrectLayer) {
+ auto& writer = getWriter(getPrimaryDisplayId());
+ int64_t layer = 5;
+ writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+ LayerLifecycleBatchCommandType::DESTROY);
+ execute();
+ const auto errors = mReader.takeErrors();
+ ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlBatchedCommandTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, GraphicsComposerAidlBatchedCommandTest,
+ testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+ ::android::PrintInstanceNameToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsComposerAidlCommandTest,
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index e288f17..4691dd6 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -48,7 +48,7 @@
},
],
- frozen: true,
+ frozen: false,
}
@@ -80,7 +80,7 @@
name: "android.hardware.health-translate-ndk",
defaults: ["android.hardware.health-translate-ndk_defaults"],
shared_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
],
}
@@ -97,7 +97,7 @@
name: "android.hardware.health-translate-java",
srcs: ["android/hardware/health/Translate.java"],
libs: [
- "android.hardware.health-V2-java",
+ "android.hardware.health-V3-java",
"android.hardware.health-V2.0-java",
"android.hardware.health-V2.1-java",
],
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
index 2dd01b1..089c8ac 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryHealthData.aidl
@@ -37,4 +37,6 @@
long batteryManufacturingDateSeconds;
long batteryFirstUsageSeconds;
long batteryStateOfHealth;
+ @nullable String batterySerialNumber;
+ android.hardware.health.BatteryPartStatus batteryPartStatus = android.hardware.health.BatteryPartStatus.UNSUPPORTED;
}
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
new file mode 100644
index 0000000..e013e31
--- /dev/null
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.health;
+@Backing(type="int") @VintfStability
+enum BatteryPartStatus {
+ UNSUPPORTED,
+ ORIGINAL,
+ REPLACED,
+}
diff --git a/health/aidl/android/hardware/health/BatteryHealthData.aidl b/health/aidl/android/hardware/health/BatteryHealthData.aidl
index 594bcce..7245298 100644
--- a/health/aidl/android/hardware/health/BatteryHealthData.aidl
+++ b/health/aidl/android/hardware/health/BatteryHealthData.aidl
@@ -16,6 +16,8 @@
package android.hardware.health;
+import android.hardware.health.BatteryPartStatus;
+
/*
* Battery health data
*/
@@ -36,4 +38,14 @@
* Otherwise, value must be in the range 0 to 100.
*/
long batteryStateOfHealth;
+ /**
+ * Serial number of the battery. Null if not supported. If supported, a string of at least 6
+ * alphanumeric characters. Characters may either be upper or lower case, but for comparison
+ * and uniqueness purposes, must be treated as case-insensitive.
+ */
+ @nullable String batterySerialNumber;
+ /**
+ * Indicator for part originality of the battery.
+ */
+ BatteryPartStatus batteryPartStatus = BatteryPartStatus.UNSUPPORTED;
}
diff --git a/health/aidl/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/android/hardware/health/BatteryPartStatus.aidl
new file mode 100644
index 0000000..6c2060a
--- /dev/null
+++ b/health/aidl/android/hardware/health/BatteryPartStatus.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health;
+
+/**
+ * Possible values for BatteryPartStatus.
+ * Note: These are currently in sync with BatteryManager and must not
+ * be extended / altered.
+ */
+@VintfStability
+@Backing(type="int")
+enum BatteryPartStatus {
+ /**
+ * Device cannot differentiate an original battery from a replaced battery.
+ */
+ UNSUPPORTED = 0,
+ /**
+ * Device has the original battery it was manufactured with.
+ */
+ ORIGINAL = 1,
+ /**
+ * Device has a replaced battery.
+ */
+ REPLACED = 2,
+}
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index b51e4f3..2071f08 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -29,7 +29,7 @@
"libcutils",
"liblog",
"libutils",
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
// TODO(b/177269435): remove when BatteryMonitor works with AIDL HealthInfo.
"libhidlbase",
@@ -48,7 +48,7 @@
name: "libhealth_aidl_charger_defaults",
shared_libs: [
// common
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"libbase",
"libcutils",
"liblog",
@@ -195,7 +195,7 @@
"service_fuzzer_defaults",
],
static_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"libbase",
"liblog",
"fuzz_libhealth_aidl_impl",
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 4ad8f50..6df623a 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -62,6 +62,18 @@
Health::~Health() {}
+static inline ndk::ScopedAStatus TranslateStatus(::android::status_t err) {
+ switch (err) {
+ case ::android::OK:
+ return ndk::ScopedAStatus::ok();
+ case ::android::NAME_NOT_FOUND:
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ default:
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ IHealth::STATUS_UNKNOWN, ::android::statusToString(err).c_str());
+ }
+}
+
//
// Getters.
//
@@ -78,16 +90,7 @@
LOG(DEBUG) << "getProperty(" << id << ")"
<< " fails: (" << err << ") " << ::android::statusToString(err);
}
-
- switch (err) {
- case ::android::OK:
- return ndk::ScopedAStatus::ok();
- case ::android::NAME_NOT_FOUND:
- return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
- default:
- return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
- IHealth::STATUS_UNKNOWN, ::android::statusToString(err).c_str());
- }
+ return TranslateStatus(err);
}
ndk::ScopedAStatus Health::getChargeCounterUah(int32_t* out) {
@@ -153,6 +156,21 @@
!res.isOk()) {
LOG(WARNING) << "Cannot get Battery_state_of_health: " << res.getDescription();
}
+ if (auto res = battery_monitor_.getSerialNumber(&out->batterySerialNumber);
+ res != ::android::OK) {
+ LOG(WARNING) << "Cannot get Battery_serial_number: "
+ << TranslateStatus(res).getDescription();
+ }
+
+ int64_t part_status = static_cast<int64_t>(BatteryPartStatus::UNSUPPORTED);
+ if (auto res = GetProperty<int64_t>(&battery_monitor_, ::android::BATTERY_PROP_PART_STATUS,
+ static_cast<int64_t>(BatteryPartStatus::UNSUPPORTED),
+ &part_status);
+ !res.isOk()) {
+ LOG(WARNING) << "Cannot get Battery_part_status: " << res.getDescription();
+ }
+ out->batteryPartStatus = static_cast<BatteryPartStatus>(part_status);
+
return ndk::ScopedAStatus::ok();
}
diff --git a/health/aidl/default/android.hardware.health-service.example.xml b/health/aidl/default/android.hardware.health-service.example.xml
index 1fe9b8d..2acaaba 100644
--- a/health/aidl/default/android.hardware.health-service.example.xml
+++ b/health/aidl/default/android.hardware.health-service.example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.health</name>
- <version>2</version>
+ <version>3</version>
<fqname>IHealth/default</fqname>
</hal>
</manifest>
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index b735a87..6d2b530 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -39,7 +39,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"libgmock",
],
header_libs: [
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 783ce11..9360789 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -84,6 +84,21 @@
return AnyOfArray(enum_range<T>().begin(), enum_range<T>().end());
}
+MATCHER(IsValidSerialNumber, "") {
+ if (!arg) {
+ return true;
+ }
+ if (arg->size() < 6) {
+ return false;
+ }
+ for (const auto& c : *arg) {
+ if (!isalnum(c)) {
+ return false;
+ }
+ }
+ return true;
+}
+
class HealthAidl : public testing::TestWithParam<std::string> {
public:
void SetUp() override {
@@ -270,7 +285,7 @@
ASSERT_THAT(static_cast<int>(value), AnyOf(Eq(1), Eq(4)));
}
-MATCHER(IsValidHealthData, "") {
+MATCHER_P(IsValidHealthData, version, "") {
*result_listener << "value is " << arg.toString() << ".";
if (!ExplainMatchResult(Ge(-1), arg.batteryManufacturingDateSeconds, result_listener)) {
*result_listener << " for batteryManufacturingDateSeconds.";
@@ -284,6 +299,15 @@
*result_listener << " for batteryStateOfHealth.";
return false;
}
+ if (!ExplainMatchResult(IsValidSerialNumber(), arg.batterySerialNumber, result_listener)) {
+ *result_listener << " for batterySerialNumber.";
+ return false;
+ }
+ if (!ExplainMatchResult(IsValidEnum<BatteryPartStatus>(), arg.batteryPartStatus,
+ result_listener)) {
+ *result_listener << " for batteryPartStatus.";
+ return false;
+ }
return true;
}
@@ -303,7 +327,7 @@
status = health->getBatteryHealthData(&value);
ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
if (!status.isOk()) return;
- ASSERT_THAT(value, IsValidHealthData());
+ ASSERT_THAT(value, IsValidHealthData(version));
}
MATCHER(IsValidStorageInfo, "") {
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index 14c32ae..b0ea743 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -34,7 +34,7 @@
"-Werror",
],
static_libs: [
- "android.hardware.health-V2-ndk",
+ "android.hardware.health-V3-ndk",
"android.hardware.health-translate-ndk",
"android.hardware.health@1.0",
"android.hardware.health@2.0",
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
index 6a5f512..a5ba919 100644
--- a/health/utils/libhealthshim/shim.cpp
+++ b/health/utils/libhealthshim/shim.cpp
@@ -230,6 +230,7 @@
ScopedAStatus HealthShim::getBatteryHealthData(BatteryHealthData* out) {
out->batteryManufacturingDateSeconds = 0;
out->batteryFirstUsageSeconds = 0;
+ out->batteryPartStatus = BatteryPartStatus::UNSUPPORTED;
return ResultToStatus(Result::NOT_SUPPORTED);
}
diff --git a/ir/aidl/default/android.hardware.ir-service.example.rc b/ir/aidl/default/android.hardware.ir-service.example.rc
index 1a721da..d27f282 100644
--- a/ir/aidl/default/android.hardware.ir-service.example.rc
+++ b/ir/aidl/default/android.hardware.ir-service.example.rc
@@ -1,4 +1,4 @@
-service vendor.ir-default /apex/com.android.hardware.ir/bin/hw/android.hardware.ir-service.example
+service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.example
class hal
user system
group system
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
index b8a0710..46eca69 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/Mode.aidl
@@ -52,4 +52,5 @@
GAME,
GAME_LOADING,
DISPLAY_CHANGE,
+ AUTOMOTIVE_PROJECTION,
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
index 9c1f381..cb37719 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
@@ -39,4 +39,6 @@
CPU_LOAD_RESET = 2,
CPU_LOAD_RESUME = 3,
POWER_EFFICIENCY = 4,
+ GPU_LOAD_UP = 5,
+ GPU_LOAD_DOWN = 6,
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
index e86cd40..45013dd 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
@@ -36,4 +36,7 @@
parcelable WorkDuration {
long timeStampNanos;
long durationNanos;
+ long workPeriodStartTimestampNanos;
+ long cpuDurationNanos;
+ long gpuDurationNanos;
}
diff --git a/power/aidl/android/hardware/power/Mode.aidl b/power/aidl/android/hardware/power/Mode.aidl
index 78f0363..a8fba72 100644
--- a/power/aidl/android/hardware/power/Mode.aidl
+++ b/power/aidl/android/hardware/power/Mode.aidl
@@ -173,4 +173,10 @@
* or switching between inner and outer panels.
*/
DISPLAY_CHANGE,
+
+ /**
+ * This mode indicates that the device is rendering to a remote display in
+ * a vehicle (such as Android Auto projection screen).
+ */
+ AUTOMOTIVE_PROJECTION,
}
diff --git a/power/aidl/android/hardware/power/SessionHint.aidl b/power/aidl/android/hardware/power/SessionHint.aidl
index a172e12..ae91061 100644
--- a/power/aidl/android/hardware/power/SessionHint.aidl
+++ b/power/aidl/android/hardware/power/SessionHint.aidl
@@ -52,4 +52,17 @@
* power hint session is noncritical despite its CPU intensity.
*/
POWER_EFFICIENCY = 4,
+
+ /**
+ * This hint indicates an increase in GPU workload intensity. It means that
+ * this hint session needs extra GPU resources to meet the target duration.
+ * This hint must be sent before reporting the actual duration to the session.
+ */
+ GPU_LOAD_UP = 5,
+
+ /**
+ * This hint indicates a decrease in GPU workload intensity. It means that
+ * this hint session can reduce GPU resources and still meet the target duration.
+ */
+ GPU_LOAD_DOWN = 6,
}
diff --git a/power/aidl/android/hardware/power/WorkDuration.aidl b/power/aidl/android/hardware/power/WorkDuration.aidl
index a06a058..fcd638b 100644
--- a/power/aidl/android/hardware/power/WorkDuration.aidl
+++ b/power/aidl/android/hardware/power/WorkDuration.aidl
@@ -23,8 +23,30 @@
* sample was measured.
*/
long timeStampNanos;
+
/**
- * Work duration in nanoseconds.
+ * Total work duration in nanoseconds.
*/
long durationNanos;
+
+ /**
+ * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the work starts.
+ * The work period start timestamp could be zero if the call is from
+ * the legacy SDK/NDK reportActualWorkDuration API.
+ */
+ long workPeriodStartTimestampNanos;
+
+ /**
+ * CPU work duration in nanoseconds.
+ * The CPU work duration could be the same as the total work duration if
+ * the call is from the legacy SDK/NDK reportActualWorkDuration API.
+ */
+ long cpuDurationNanos;
+
+ /**
+ * GPU work duration in nanoseconds.
+ * The GPU work duration could be zero if the call is from the legacy
+ * SDK/NDK reportActualWorkDuration API.
+ */
+ long gpuDurationNanos;
}
diff --git a/radio/OWNERS b/radio/OWNERS
index 67ac2e2..8107287 100644
--- a/radio/OWNERS
+++ b/radio/OWNERS
@@ -2,3 +2,4 @@
jackyu@google.com
sarahchin@google.com
+jayachandranc@google.com
\ No newline at end of file
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
index 3161322..eedb8ed 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ConnectionEvent.aidl
@@ -35,18 +35,16 @@
/* @hide */
@Backing(type="int") @JavaDerive(toString=true) @VintfStability
enum ConnectionEvent {
- CS_SERVICE_GSM = 0,
- SIGNALLING_GSM = 1,
- PS_SERVICE_GPRS = 2,
- SIGNALLING_GPRS = 3,
- PS_SERVICE_3G = 4,
- SIGNALLING_3G = 5,
- NAS_SIGNALLING_LTE = 6,
- AS_SIGNALLING_LTE = 7,
- VOLTE_SIP = 8,
- VOLTE_RTP = 9,
- NAS_SIGNALLING_5G = 10,
- AS_SIGNALLING_5G = 11,
- VONR_SIP = 12,
- VONR_RTP = 13,
+ CS_SIGNALLING_GSM = 0,
+ PS_SIGNALLING_GPRS = 1,
+ CS_SIGNALLING_3G = 2,
+ PS_SIGNALLING_3G = 3,
+ NAS_SIGNALLING_LTE = 4,
+ AS_SIGNALLING_LTE = 5,
+ VOLTE_SIP = 6,
+ VOLTE_RTP = 7,
+ NAS_SIGNALLING_5G = 8,
+ AS_SIGNALLING_5G = 9,
+ VONR_SIP = 10,
+ VONR_RTP = 11,
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
index 97ce004..1664501 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -53,7 +53,6 @@
EEA1 = 42,
EEA2 = 43,
EEA3 = 44,
- EEA4_ZUC = 45,
NEA0 = 55,
NEA1 = 56,
NEA2 = 57,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
new file mode 100644
index 0000000..5838959
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.radio.sim;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable CarrierInfo {
+ String mcc;
+ String mnc;
+ @nullable String spn;
+ @nullable String gid1;
+ @nullable String gid2;
+ @nullable String imsiPrefix;
+ @nullable List<android.hardware.radio.sim.Plmn> ephlmn;
+ @nullable String iccid;
+ @nullable String impi;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index 84cdf5d..a5b8dc9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -35,10 +35,18 @@
/* @hide */
@JavaDerive(toString=true) @VintfStability
parcelable CarrierRestrictions {
+ /**
+ * @deprecated use @List<CarrierInfo> allowedCarrierInfoList
+ */
android.hardware.radio.sim.Carrier[] allowedCarriers;
+ /**
+ * @deprecated use @List<CarrierInfo> excludedCarrierInfoList
+ */
android.hardware.radio.sim.Carrier[] excludedCarriers;
boolean allowedCarriersPrioritized;
android.hardware.radio.sim.CarrierRestrictions.CarrierRestrictionStatus status;
+ android.hardware.radio.sim.CarrierInfo[] allowedCarrierInfoList = {};
+ android.hardware.radio.sim.CarrierInfo[] excludedCarrierInfoList = {};
@Backing(type="int") @VintfStability
enum CarrierRestrictionStatus {
UNKNOWN = 0,
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
new file mode 100644
index 0000000..b29a4a7
--- /dev/null
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.radio.sim;
+/* @hide */
+@JavaDerive(toString=true) @VintfStability
+parcelable Plmn {
+ String mcc;
+ String mnc;
+}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 5a5e8ac..8cfe417 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -37,4 +37,11 @@
enum SimLockMultiSimPolicy {
NO_MULTISIM_POLICY,
ONE_VALID_SIM_MUST_BE_PRESENT,
+ APPLY_TO_ALL_SLOTS,
+ APPLY_TO_ONLY_SLOT_1,
+ VALID_SIM_MUST_PRESENT_ON_SLOT_1,
+ ACTIVE_SERVICE_ON_SLOT_1_TO_UNBLOCK_OTHER_SLOTS,
+ ACTIVE_SERVICE_ON_ANY_SLOT_TO_UNBLOCK_OTHER_SLOTS,
+ ALL_SIMS_MUST_BE_VALID,
+ SLOT_POLICY_OTHER,
}
diff --git a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
index 639ba89..2e39ebf 100644
--- a/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
+++ b/radio/aidl/android/hardware/radio/network/ConnectionEvent.aidl
@@ -25,31 +25,31 @@
@Backing(type="int")
@JavaDerive(toString=true)
enum ConnectionEvent {
- // 2G GSM
- CS_SERVICE_GSM = 0,
- SIGNALLING_GSM = 1,
+ // 2G GSM circuit switched
+ CS_SIGNALLING_GSM = 0,
// 2G GPRS packet services
- PS_SERVICE_GPRS = 2,
- SIGNALLING_GPRS = 3,
+ PS_SIGNALLING_GPRS = 1,
- // 3G packet services
- PS_SERVICE_3G = 4,
- SIGNALLING_3G = 5,
+ // 3G circuit switched
+ CS_SIGNALLING_3G = 2,
+
+ // 3G packet switched
+ PS_SIGNALLING_3G = 3,
// 4G LTE packet services
- NAS_SIGNALLING_LTE = 6,
- AS_SIGNALLING_LTE = 7,
+ NAS_SIGNALLING_LTE = 4,
+ AS_SIGNALLING_LTE = 5,
// VoLTE
- VOLTE_SIP = 8,
- VOLTE_RTP = 9,
+ VOLTE_SIP = 6,
+ VOLTE_RTP = 7,
// 5G packet services
- NAS_SIGNALLING_5G = 10,
- AS_SIGNALLING_5G = 11,
+ NAS_SIGNALLING_5G = 8,
+ AS_SIGNALLING_5G = 9,
// VoNR
- VONR_SIP = 12,
- VONR_RTP = 13,
+ VONR_SIP = 10,
+ VONR_RTP = 11,
}
diff --git a/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl b/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl
index 1225c41..5a23661 100644
--- a/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl
+++ b/radio/aidl/android/hardware/radio/network/NasProtocolMessage.aidl
@@ -17,8 +17,9 @@
package android.hardware.radio.network;
/**
- * Each enum value represents a message type on the NAS. The relevant cellular generation is noted.
- * Sample spec references are provided, but generally only reference one network generation's spec.
+ * Each enum value represents a message type on the Non-Access Stratum (NAS). The relevant cellular
+ * generation is noted for each message type. Sample spec references are provided, but generally
+ * only reference one network generation's spec.
*
* @hide
*/
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
index 6d2c018..71c654c 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -52,7 +52,6 @@
EEA1 = 42,
EEA2 = 43,
EEA3 = 44,
- EEA4_ZUC = 45,
// 5G PS services (3GPP TS 33.401 for 5G NSA and 3GPP TS 33.501 for 5G SA)
NEA0 = 55,
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
new file mode 100644
index 0000000..a890497
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sim;
+
+import android.hardware.radio.sim.Plmn;
+
+/** @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable CarrierInfo {
+ /**
+ * MCC (Mobile Country Code) of Carrier. Wild char is either '*' or '?'.
+ */
+ String mcc;
+
+ /**
+ * MNC (Mobile Network Code) of the Carrier. Wild char is either '*' or '?'.
+ */
+ String mnc;
+ /**
+ * Service Provider Name(SPN) of the SIM card of the Carrier.
+ */
+ @nullable
+ String spn;
+ /**
+ * GID1 value of the SIM card of the Carrier.
+ */
+ @nullable
+ String gid1;
+ /**
+ * GID2 value of the SIM card of the Carrier.
+ */
+ @nullable
+ String gid2;
+
+ /**
+ * IMSI (International Mobile Subscriber Identity) prefix. Wild char is '*'.
+ */
+ @nullable
+ String imsiPrefix;
+ /**
+ * Equivalent HPLMN of the SIM card of the Carrier.
+ */
+ @nullable
+ List<Plmn> ephlmn;
+ /**
+ * ICCID (Integrated Circuit Card Identification) of the SIM card.
+ */
+ @nullable
+ String iccid;
+ /**
+ * IMPI (IMS Private Identity) of the SIM card of the Carrier.
+ */
+ @nullable
+ String impi;
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index d5e0c43..0002d5a 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -17,6 +17,7 @@
package android.hardware.radio.sim;
import android.hardware.radio.sim.Carrier;
+import android.hardware.radio.sim.CarrierInfo;
/** @hide */
@VintfStability
@@ -40,12 +41,14 @@
}
/**
* Allowed carriers
+ * @deprecated use @List<CarrierInfo> allowedCarrierInfoList
*/
Carrier[] allowedCarriers;
/**
* Explicitly excluded carriers which match allowed_carriers. Eg. allowedCarriers match mcc/mnc,
* excludedCarriers has same mcc/mnc and gid1 is ABCD. It means except the carrier whose gid1
* is ABCD, all carriers with the same mcc/mnc are allowed.
+ * @deprecated use @List<CarrierInfo> excludedCarrierInfoList
*/
Carrier[] excludedCarriers;
/**
@@ -59,4 +62,14 @@
boolean allowedCarriersPrioritized;
/** Current restriction status as defined in CarrierRestrictionStatus enum */
CarrierRestrictionStatus status;
-}
+
+ /** Allowed carriers. */
+ CarrierInfo[] allowedCarrierInfoList = {};
+
+ /**
+ * Explicitly excluded carriers which match allowed_carriers. Eg. allowedCarriers match mcc/mnc,
+ * excludedCarriers has same mcc/mnc and gid1 is ABCD. It means except the carrier whose gid1
+ * is ABCD, all carriers with the same mcc/mnc are allowed.
+ */
+ CarrierInfo[] excludedCarrierInfoList = {};
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/sim/Plmn.aidl b/radio/aidl/android/hardware/radio/sim/Plmn.aidl
new file mode 100644
index 0000000..fd82692
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/sim/Plmn.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.sim;
+
+/** @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable Plmn {
+ /**
+ * MCC (Mobile Country Code) of the PLMN
+ */
+ String mcc;
+ /**
+ * MNC (Mobile Network Code) of the PLMN
+ */
+ String mnc;
+}
\ No newline at end of file
diff --git a/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
index 18f97f7..89d85a9 100644
--- a/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimLockMultiSimPolicy.aidl
@@ -21,14 +21,56 @@
@Backing(type="int")
@JavaDerive(toString=true)
enum SimLockMultiSimPolicy {
+
/**
* Indicates that configuration applies to each slot independently.
*/
NO_MULTISIM_POLICY,
+
/**
* Indicates that any SIM card can be used as far as one valid card is present in the device.
* For the modem, a SIM card is valid when its content (i.e. MCC, MNC, GID, SPN) matches the
* carrier restriction configuration.
*/
ONE_VALID_SIM_MUST_BE_PRESENT,
+
+ /**
+ * Indicates that the SIM lock policy applies uniformly to all sim slots.
+ */
+ APPLY_TO_ALL_SLOTS,
+
+ /**
+ * The SIM lock configuration applies exclusively to sim slot 1, leaving
+ * all other sim slots unlocked irrespective of the SIM card in slot 1
+ */
+ APPLY_TO_ONLY_SLOT_1,
+
+ /**
+ * Valid sim cards must be present on sim slot1 in order
+ * to use other sim slots.
+ */
+ VALID_SIM_MUST_PRESENT_ON_SLOT_1,
+
+ /**
+ * Valid sim card must be present on slot1 and it must be in full service
+ * in order to use other sim slots.
+ */
+ ACTIVE_SERVICE_ON_SLOT_1_TO_UNBLOCK_OTHER_SLOTS,
+
+ /**
+ * Valid sim card be present on any slot and it must be in full service
+ * in order to use other sim slots.
+ */
+ ACTIVE_SERVICE_ON_ANY_SLOT_TO_UNBLOCK_OTHER_SLOTS,
+
+ /**
+ * Valid sim cards must be present on all slots. If any SIM cards become
+ * invalid then device would set other SIM cards as invalid as well.
+ */
+ ALL_SIMS_MUST_BE_VALID,
+
+ /**
+ * In case there is no match policy listed above.
+ */
+ SLOT_POLICY_OTHER
}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 98422af..32b246a 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -90,6 +90,11 @@
serial = GetRandomSerialNumber();
+ // get aidl version
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+
// save current value
radio_network->getAllowedNetworkTypesBitmap(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -125,6 +130,11 @@
RadioError::INVALID_ARGUMENTS, RadioError::MODEM_ERR,
RadioError::REQUEST_NOT_SUPPORTED, RadioError::NO_RESOURCES}));
if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ if (aidl_version < 2) {
+ radioRsp_network->networkTypeBitmapResponse
+ &= ~static_cast<int32_t>(RadioAccessFamily::LTE_CA);
+ }
+
// verify we get the value we set
EXPECT_EQ(radioRsp_network->networkTypeBitmapResponse, allowedNetworkTypesBitmap);
}
@@ -2372,9 +2382,16 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ if (aidl_version >= 3 && deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ } else {
+ // For aidl_version 2, API is optional
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
}
/**
@@ -2406,9 +2423,16 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
- ASSERT_TRUE(CheckAnyOfErrors(
- radioRsp_network->rspInfo.error,
- {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ if (aidl_version >= 3 && deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::MODEM_ERR}));
+ } else {
+ // For aidl_version 2, API is optional
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ }
}
TEST_P(RadioNetworkTest, isCellularIdentifierTransparencyEnabled) {
diff --git a/security/authgraph/aidl/Android.bp b/security/authgraph/aidl/Android.bp
index d94f640..f3d1281 100644
--- a/security/authgraph/aidl/Android.bp
+++ b/security/authgraph/aidl/Android.bp
@@ -34,7 +34,7 @@
platform_apis: true,
},
ndk: {
- apps_enabled: false,
+ enabled: true,
},
rust: {
enabled: true,
diff --git a/security/authgraph/aidl/vts/functional/lib.rs b/security/authgraph/aidl/vts/functional/lib.rs
index da3fa1c..f4c1da9 100644
--- a/security/authgraph/aidl/vts/functional/lib.rs
+++ b/security/authgraph/aidl/vts/functional/lib.rs
@@ -26,6 +26,7 @@
use authgraph_boringssl as boring;
use authgraph_core::{error::Error as AgError, keyexchange as ke};
use coset::CborSerializable;
+use std::{cell::RefCell, rc::Rc};
pub mod sink;
pub mod source;
@@ -34,7 +35,7 @@
pub fn test_ag_participant() -> Result<ke::AuthGraphParticipant, AgError> {
Ok(ke::AuthGraphParticipant::new(
boring::crypto_trait_impls(),
- Box::<boring::test_device::AgDevice>::default(),
+ Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
ke::MAX_OPENED_SESSIONS,
)?)
}
diff --git a/security/authgraph/aidl/vts/functional/sink.rs b/security/authgraph/aidl/vts/functional/sink.rs
index bb357b8..a331eef 100644
--- a/security/authgraph/aidl/vts/functional/sink.rs
+++ b/security/authgraph/aidl/vts/functional/sink.rs
@@ -29,11 +29,11 @@
}
/// Perform mainline AuthGraph key exchange with the provided sink and local implementation.
-/// Return the agreed AES keys in plaintext.
+/// Return the agreed AES keys in plaintext, together with the session ID.
pub fn test_mainline(
local_source: &mut ke::AuthGraphParticipant,
sink: binder::Strong<dyn IAuthGraphKeyExchange>,
-) -> [key::AesKey; 2] {
+) -> ([key::AesKey; 2], Vec<u8>) {
// Step 1: create an ephemeral ECDH key at the (local) source.
let source_init_info = local_source
.create()
@@ -113,7 +113,7 @@
Ok(array) => array,
Err(_) => panic!("wrong number of decrypted shared key arcs"),
};
- decrypted_shared_keys_array
+ (decrypted_shared_keys_array, sink_info.sessionId)
}
/// Perform mainline AuthGraph key exchange with the provided sink, but provide an invalid
diff --git a/security/authgraph/aidl/vts/functional/source.rs b/security/authgraph/aidl/vts/functional/source.rs
index a1e76b3..019e1e8 100644
--- a/security/authgraph/aidl/vts/functional/source.rs
+++ b/security/authgraph/aidl/vts/functional/source.rs
@@ -29,11 +29,11 @@
}
/// Perform mainline AuthGraph key exchange with the provided source.
-/// Return the agreed AES keys in plaintext.
+/// Return the agreed AES keys in plaintext, together with the session ID.
pub fn test_mainline(
local_sink: &mut ke::AuthGraphParticipant,
source: binder::Strong<dyn IAuthGraphKeyExchange>,
-) -> [key::AesKey; 2] {
+) -> ([key::AesKey; 2], Vec<u8>) {
// Step 1: create an ephemeral ECDH key at the (remote) source.
let source_init_info = source
.create()
@@ -120,7 +120,7 @@
Ok(array) => array,
Err(_) => panic!("wrong number of decrypted shared key arcs"),
};
- decrypted_shared_keys_array
+ (decrypted_shared_keys_array, source_info.sessionId)
}
/// Perform mainline AuthGraph key exchange with the provided source, but provide an invalid session
diff --git a/security/authgraph/default/src/fuzzer.rs b/security/authgraph/default/src/fuzzer.rs
index d401777..387d72f 100644
--- a/security/authgraph/default/src/fuzzer.rs
+++ b/security/authgraph/default/src/fuzzer.rs
@@ -22,10 +22,9 @@
use authgraph_nonsecure::LocalTa;
use binder_random_parcel_rs::fuzz_service;
use libfuzzer_sys::fuzz_target;
-use std::sync::{Arc, Mutex};
fuzz_target!(|data: &[u8]| {
let local_ta = LocalTa::new().expect("Failed to create an AuthGraph local TA.");
- let service = AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+ let service = AuthGraphService::new_as_binder(local_ta);
fuzz_service(&mut service.as_binder(), data);
});
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
index 14741aa..1f851b2 100644
--- a/security/authgraph/default/src/lib.rs
+++ b/security/authgraph/default/src/lib.rs
@@ -22,36 +22,62 @@
ta::{AuthGraphTa, Role},
};
use authgraph_hal::channel::SerializedChannel;
-use std::sync::{Arc, Mutex};
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::{mpsc, Mutex};
/// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore
/// insecure).
pub struct LocalTa {
- ta: Arc<Mutex<AuthGraphTa>>,
+ channels: Mutex<Channels>,
+}
+
+struct Channels {
+ in_tx: mpsc::Sender<Vec<u8>>,
+ out_rx: mpsc::Receiver<Vec<u8>>,
}
impl LocalTa {
/// Create a new instance.
pub fn new() -> Result<Self, error::Error> {
- Ok(Self {
- ta: Arc::new(Mutex::new(AuthGraphTa::new(
+ // Create a pair of channels to communicate with the TA thread.
+ let (in_tx, in_rx) = mpsc::channel();
+ let (out_tx, out_rx) = mpsc::channel();
+
+ // The TA code expects to run single threaded, so spawn a thread to run it in.
+ std::thread::spawn(move || {
+ let mut ta = AuthGraphTa::new(
keyexchange::AuthGraphParticipant::new(
boring::crypto_trait_impls(),
- Box::<boring::test_device::AgDevice>::default(),
+ Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
keyexchange::MAX_OPENED_SESSIONS,
- )?,
+ )
+ .expect("failed to create AG participant"),
Role::Both,
- ))),
+ );
+ // Loop forever processing request messages.
+ loop {
+ let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+ let rsp_data = ta.process(&req_data);
+ out_tx.send(rsp_data).expect("failed to send out rsp");
+ }
+ });
+ Ok(Self {
+ channels: Mutex::new(Channels { in_tx, out_rx }),
})
}
}
-/// Pretend to be a serialized channel to the TA, but actually just directly invoke the TA with
-/// incoming requests.
impl SerializedChannel for LocalTa {
const MAX_SIZE: usize = usize::MAX;
- fn execute(&mut self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
- Ok(self.ta.lock().unwrap().process(req_data))
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ // Serialize across both request and response.
+ let channels = self.channels.lock().unwrap();
+ channels
+ .in_tx
+ .send(req_data.to_vec())
+ .expect("failed to send in request");
+ Ok(channels.out_rx.recv().expect("failed to receive response"))
}
}
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index 81f2dd6..ced7567 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -25,7 +25,6 @@
use authgraph_hal::service;
use authgraph_nonsecure::LocalTa;
use log::{error, info};
-use std::sync::{Arc, Mutex};
static SERVICE_NAME: &str = "android.hardware.security.authgraph.IAuthGraphKeyExchange";
static SERVICE_INSTANCE: &str = "nonsecure";
@@ -65,9 +64,8 @@
binder::ProcessState::start_thread_pool();
// Register the service
- let local_ta =
- LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
- let service = service::AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+ let local_ta = LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
+ let service = service::AuthGraphService::new_as_binder(local_ta);
let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE);
binder::add_service(&service_name, service.as_binder()).map_err(|e| {
format!(
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
index 79189a1..b8c69eb 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -17,6 +17,7 @@
#pragma once
#include <memory>
+#include <string>
#include <vector>
#include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
@@ -129,8 +130,8 @@
* "name": <string>
* }
*/
-JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name,
- const cppbor::Array& csr);
+JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor::Array& csr,
+ const std::string& serialno_prop);
/**
* Parses a DeviceInfo structure from the given CBOR data. The parsed data is then validated to
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
index 6edbfc1..a830041 100644
--- a/security/keymint/support/remote_prov_utils.cpp
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -337,9 +337,9 @@
return result;
}
-JsonOutput jsonEncodeCsrWithBuild(const std::string instance_name, const cppbor::Array& csr) {
+JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor::Array& csr,
+ const std::string& serialno_prop) {
const std::string kFingerprintProp = "ro.build.fingerprint";
- const std::string kSerialNoProp = "ro.serialno";
if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
return JsonOutput::Error("Unable to read build fingerprint");
@@ -364,7 +364,7 @@
Json::Value json(Json::objectValue);
json["name"] = instance_name;
json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
- json["serialno"] = ::android::base::GetProperty(kSerialNoProp, /*default=*/"");
+ json["serialno"] = ::android::base::GetProperty(serialno_prop, /*default=*/"");
json["csr"] = base64.data(); // Boring writes a NUL-terminated c-string
Json::StreamWriterBuilder factory;
@@ -978,7 +978,7 @@
return hwtrust::DiceChain::Kind::kVsr13;
case __ANDROID_API_U__:
return hwtrust::DiceChain::Kind::kVsr14;
- case __ANDROID_API_V__:
+ case 202404: /* TODO(b/315056516) Use a version macro for vendor API 24Q2 */
return hwtrust::DiceChain::Kind::kVsr15;
default:
return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
diff --git a/security/keymint/support/remote_prov_utils_test.cpp b/security/keymint/support/remote_prov_utils_test.cpp
index eaaba45..630f7bb 100644
--- a/security/keymint/support/remote_prov_utils_test.cpp
+++ b/security/keymint/support/remote_prov_utils_test.cpp
@@ -182,10 +182,11 @@
}
TEST(RemoteProvUtilsTest, JsonEncodeCsr) {
+ const std::string kSerialNoProp = "ro.serialno";
cppbor::Array array;
array.add(1);
- auto [json, error] = jsonEncodeCsrWithBuild(std::string("test"), array);
+ auto [json, error] = jsonEncodeCsrWithBuild(std::string("test"), array, kSerialNoProp);
ASSERT_TRUE(error.empty()) << error;
diff --git a/security/rkp/README.md b/security/rkp/README.md
index 71f70cb..2180d0f 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -196,8 +196,8 @@
privileged vm, the RKP VM, is reponsible for generating and managing the keys for client
VMs that run virtualized workloads. See the following for more background information on the
RKP VM:
-* [rkp-vm]: https://android.googlesource.com/platform/packages/modules/Virtualization/+/main/service_vm/README.md#rkp-vm-remote-key-provisioning-virtual-machine
-* [rkp-service]: https://source.android.com/docs/core/ota/modular-system/remote-key-provisioning#stack-architecture
+* [rkp-vm](https://android.googlesource.com/platform/packages/modules/Virtualization/+/main/service_vm/README.md#rkp-vm-remote-key-provisioning-virtual-machine)
+* [rkp-service](https://source.android.com/docs/core/ota/modular-system/remote-key-provisioning#stack-architecture)
It is important to distinquish the RKP VM from other components, such as KeyMint. An
[RKP VM marker](https://pigweed.googlesource.com/open-dice/+/HEAD/docs/android.md#configuration-descriptor)
diff --git a/security/secretkeeper/OWNERS b/security/secretkeeper/OWNERS
new file mode 100644
index 0000000..acf4c6c
--- /dev/null
+++ b/security/secretkeeper/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 867125
+
+alanstokes@google.com
+drysdale@google.com
+hasinitg@google.com
+shikhapanwar@google.com
diff --git a/security/secretkeeper/aidl/Android.bp b/security/secretkeeper/aidl/Android.bp
index c77d299..ac923ca 100644
--- a/security/secretkeeper/aidl/Android.bp
+++ b/security/secretkeeper/aidl/Android.bp
@@ -20,8 +20,15 @@
name: "android.hardware.security.secretkeeper",
vendor_available: true,
srcs: ["android/hardware/security/secretkeeper/*.aidl"],
+ imports: [
+ "android.hardware.security.authgraph-V1",
+ ],
stability: "vintf",
+ frozen: false,
backend: {
+ java: {
+ enabled: false,
+ },
ndk: {
enabled: true,
},
@@ -34,3 +41,44 @@
},
},
}
+
+// cc_defaults that includes the latest Secretkeeper AIDL library.
+// Modules that depend on Secretkeeper directly can include this cc_defaults to avoid
+// managing dependency versions explicitly.
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_ndk_static",
+ static_libs: [
+ "android.hardware.security.secretkeeper-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_ndk_shared",
+ shared_libs: [
+ "android.hardware.security.secretkeeper-V1-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_cpp_static",
+ static_libs: [
+ "android.hardware.security.secretkeeper-V1-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_cpp_shared",
+ shared_libs: [
+ "android.hardware.security.secretkeeper-V1-cpp",
+ ],
+}
+
+// A rust_defaults that includes the latest Secretkeeper AIDL library.
+// Modules that depend on Secretkeeper directly can include this rust_defaults to avoid
+// managing dependency versions explicitly.
+rust_defaults {
+ name: "secretkeeper_use_latest_hal_aidl_rust",
+ rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
+ ],
+}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
new file mode 100644
index 0000000..cc07f9b
--- /dev/null
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ErrorCode.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.security.secretkeeper;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum ErrorCode {
+ OK = 0,
+ UNKNOWN_KEY_ID = 1,
+ INTERNAL_ERROR = 2,
+ REQUEST_MALFORMED = 3,
+}
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index 2eb33c5..023fc8f 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -34,5 +34,6 @@
package android.hardware.security.secretkeeper;
@VintfStability
interface ISecretkeeper {
+ android.hardware.security.authgraph.IAuthGraphKeyExchange getAuthGraphKe();
byte[] processSecretManagementRequest(in byte[] request);
}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
new file mode 100644
index 0000000..e9cce09
--- /dev/null
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ErrorCode.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.secretkeeper;
+
+/**
+ * Secretkeeper unencrypted error code, returned via AIDL as service specific errors in
+ * EX_SERVICE_SPECIFIC.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum ErrorCode {
+ OK = 0,
+ UNKNOWN_KEY_ID = 1,
+ INTERNAL_ERROR = 2,
+ REQUEST_MALFORMED = 3,
+
+ // TODO(b/291224769): Create a more exhaustive set of error code values.
+}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index af715a9..cb3e9b9 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -16,6 +16,8 @@
package android.hardware.security.secretkeeper;
+import android.hardware.security.authgraph.IAuthGraphKeyExchange;
+
@VintfStability
/**
* Secretkeeper service definition.
@@ -29,17 +31,22 @@
* - A completely separate, purpose-built and certified secure CPU.
*
* TODO(b/291224769): Extend the HAL interface to include:
- * 1. Session setup api: This is used to perform cryptographic operations that allow shared keys to
- * be exchanged between session participants, typically (but not necessarily) a pVM instance and
- * Secretkeeper. This session setup is based on public key cryptography.
- * 2. Dice policy operation - These allow sealing of the secrets with a class of Dice chains.
+ * 1. Dice policy operation - These allow sealing of the secrets with a class of Dice chains.
* Typical operations are (securely) updating the dice policy sealing the Secrets above. These
* operations are core to AntiRollback protected secrets - ie, ensuring secrets of a pVM are only
* accessible to same or higher versions of the images.
- * 3. Maintenance api: This is required for removing the Secretkeeper entries for obsolete pvMs.
+ * 2. Maintenance API: This is required for removing the Secretkeeper entries for obsolete pVMs.
*/
interface ISecretkeeper {
/**
+ * Retrieve the instance of the `IAuthGraphKeyExchange` HAL that should be used for shared
+ * session key establishment. These keys are used to perform encryption of messages as
+ * described in SecretManagement.cddl, allowing the client and Secretkeeper to have a
+ * cryptographically secure channel.
+ */
+ IAuthGraphKeyExchange getAuthGraphKe();
+
+ /**
* processSecretManagementRequest method is used for interacting with the Secret Management API
*
* Secret Management API: The clients can use this API to store (& get) 32 bytes of data.
@@ -53,7 +60,11 @@
* Virtual Machines). For this, service (& client) must implement a key exchange protocol, which
* is critical for establishing the secure channel.
*
+ * If an encrypted response cannot be generated, then a service-specific Binder error using an
+ * error code from ErrorCode.aidl will be returned.
+ *
* Secretkeeper database should guarantee the following properties:
+ *
* 1. Confidentiality: No entity (of security privilege lower than Secretkeeper) should
* be able to get a client's data in clear.
*
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
index 5631937..66ca8ed 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
@@ -1,116 +1,97 @@
; CDDL for the Secret Management API.
-; Also see processSecretManagementRequest method in ISecretkeeper.aidl
-; ProtectedRequestPacket is used by client for accessing Secret Management API
-; in Secretkeeper service. The service returns ProtectedResponsePacket of the corresponding type.
+; The input parameter to the `processSecretManagementRequest` operation in
+; `ISecretkeeper.aidl` is always an encrypted request message, CBOR-encoded as a
+; COSE_Encrypt0 object. The encryption uses the first of the keys agreed using
+; the associated AuthGraph instance, referred to as `KeySourceToSink`.
+ProtectedRequestPacket = CryptoPayload<RequestPacket, KeySourceToSink>
-; ProtectedRequestPacket & ProtectedResponsePacket are encrypted wrappers
-; on RequestPacket & ResponsePacket using symmetric keys agreed between Secretkeeper & clients
-; (these are referred to as KeySourceToSink & KeySinkToSource)
-;
-; The API operation required is encoded using 'Opcode', the arguments using 'Params'
-; and returned values as 'Result'.
-
-ProtectedRequestPacket =
- ProtectedGetVersionRequest / ProtectedStoreSecretRequest / ProtectedGetSecretRequest
-ProtectedResponsePacket =
- ProtectedGetVersionResponse / ProtectedStoreSecretResponse / ProtectedGetSecretResponse
-
-ProtectedGetVersionRequest = ProtectedRequestPacket<GetVersionRequestPacket>
-ProtectedGetVersionResponse = ProtectedResponsePacket<GetVersionResponsePacket>
-ProtectedStoreSecretRequest = ProtectedRequestPacket<StoreSecretRequestPacket>
-ProtectedStoreSecretResponse = ProtectedResponsePacket<StoreSecretResponsePacket>
-ProtectedGetSecretRequest = ProtectedRequestPacket<GetSecretRequestPacket>
-ProtectedGetSecretResponse = ProtectedResponsePacket<GetSecretResponsePacket>
-
-GetVersionRequestPacket = RequestPacket<GetVersionOpcode, GetVersionParams>
-GetVersionResponsePacket = ResponsePacket<GetVersionResult>
-StoreSecretRequestPacket = RequestPacket<StoreSecretOpcode, StoreSecretParams>
-StoreSecretResponsePacket = ResponsePacket<StoreSecretResult>
-GetSecretRequestPacket = RequestPacket<GetOpcode, GetSecretParams>
-GetSecretResponsePacket = ResponsePacket<GetSecretResult>
-
-RequestPacket<Opcode, Params> = [
- Opcode,
- Params
-]
-ResponsePacket<Result> = ResponsePacketError / ResponsePacketSuccess<Result>
-
-ResponsePacketSuccess = [
- 0, ; Indicates successful Response
- result : Result
-]
-ResponsePacketError = [
- error_code: ErrorCode, ; Indicate the error
- error_message: tstr ; Additional human-readable context
-]
-
-Opcode = &(
- GetVersionOpcode: 1, ; Get version of the SecretManagement API
- StoreSecretOpcode: 2, ; Store a secret
- GetSecretOpcode: 3, ; Get the secret
-)
-
-GetVersionParams = ()
-GetVersionResult = (version : uint)
-
-StoreSecretParams = (
- id : bstr .size 64 ; Unique identifier of the secret
- secret : bstr .size 32,
- sealing_policy : bstr .cbor DicePolicy, ; See DicePolicy.cddl for definition of DicePolicy
-)
-StoreSecretResult = ()
-
-GetSecretParams = (
- id : bstr .size 64 ; Unique identifier of the secret
- ; Use this to update the sealing policy associated with a secret during GetSecret operation.
- updated_sealing_policy : bstr .cbor DicePolicy / nil,
-)
-GetSecretResult = (secret : bstr .size 32)
-
-
-ProtectedRequestPacket<Payload, Key> = CryptoPayload<Payload, KeySourceToSink>
-ProtectedResponsePacket<Payload, Key> = ProtectedResponseError
- / ProtectedResponseSuccess<Payload>
-
-ProtectedResponseSuccess<Payload> = [
- 0, ; Indicates successful crypto operations. Note: Payload
- ; may contain Error from functional layer.
- message: CryptoPayload<Payload, KeySinkToSource> ; message is the encrypted payload
-]
-
-ProtectedResponseError = [
- error_code: CryptoErrorCode, ; Indicates the error. This is in cleartext & will be
- ; visible to Android. These are errors from crypto
- ; layer & indicates the request could not even be read
- message: tstr ; Additional human-readable context
-]
-
-CryptoPayload<Payload, Key> = [ ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
+CryptoPayload<Payload, Key> = [ ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
protected: bstr .cbor {
1 : 3, ; Algorithm: AES-GCM mode w/ 256-bit key, 128-bit tag
4 : bstr ; key identifier, uniquely identifies the session
; TODO(b/291228560): Refer to the Key Exchange spec.
},
unprotected: {
- 5 : bstr .size 12 ; IV
+ 5 : bstr .size 12 ; IV
},
- ciphertext : bstr ; AES-GCM-256(Key, bstr .cbor Payload)
- ; AAD for the encryption is CBOR-serialized
- ; Enc_structure (RFC 9052 s5.3) with empty external_aad.
+ ciphertext : bstr ; AES-GCM-256(Key, bstr .cbor Payload)
+ ; AAD for the encryption is CBOR-serialized
+ ; Enc_structure (RFC 9052 s5.3) with empty external_aad.
]
-; TODO(b/291224769): Create a more exhaustive set of CryptoErrorCode
-CryptoErrorCode = &(
- CryptoErrorCode_SessionExpired: 1,
+; Once decrypted, the request packet is an encoded CBOR array holding:
+; - An initial integer indicating which request is present.
+; - Subsequent objects holding the parameters for that specific request.
+RequestPacket =
+ [GetVersionOpcode, GetVersionParams] /
+ [StoreSecretOpcode, StoreSecretParams] /
+ [GetSecretOpcode, GetSecretParams]
+
+GetVersionOpcode = 1 ; Get version of the SecretManagement API
+StoreSecretOpcode = 2 ; Store a secret
+GetSecretOpcode = 3 ; Get the secret
+
+GetVersionParams = ()
+
+StoreSecretParams = (
+ id : SecretId,
+ secret : Secret,
+ sealing_policy : bstr .cbor DicePolicy,
)
+; INCLUDE DicePolicy.cddl for: DicePolicy
+
+GetSecretParams = (
+ id : SecretId,
+ ; Retrieving the value of a secret may optionally also update the sealing
+ ; policy associated with a secret.
+ updated_sealing_policy : bstr .cbor DicePolicy / nil,
+)
+
+SecretId = bstr .size 64 ; Unique identifier of the secret.
+Secret = bstr .size 32 ; The secret value.
+
+; The return value from a successful `processSecretManagementRequest` operation is a
+; response message encrypted with the second of the keys agreed using the associated
+; AuthGraph instance, referred to as `KeySinkToSource`.
+ProtectedResponsePacket = CryptoPayload<ResponsePacket, KeySinkToSource>
+
+; Once decrypted, the inner response message is encoded as a CBOR array holding:
+; - An initial integer return code value.
+; - Subsequently:
+; - If the return code is zero: result value(s).
+; - If the return code is non-zero: an error message.
+ResponsePacket =
+ [0, Result] /
+ [error_code: ErrorCode, error_message: tstr]
+
+; An error code in the inner response message indicates a failure in
+; secret management processing.
; TODO(b/291224769): Create a more exhaustive set of ErrorCodes
ErrorCode = &(
; Use this as if no other error code can be used.
ErrorCode_UnexpectedServerError: 1,
; Indicate the Request was malformed & hence couldnt be served.
ErrorCode_RequestMalformed: 2,
+ ; Requested Entry not found.
+ ErrorCode_EntryNotFound: 3,
+ ; Error happened while serialization or deserialization.
+ SerializationError: 4,
+ ; Indicates that Dice Policy matching did not succeed & hence access not granted.
+ ErrorCode_DicePolicyError: 5,
)
-; INCLUDE DicePolicy.cddl for: DicePolicy
\ No newline at end of file
+; The particular result variant present is determined by which request
+; message was originally sent.
+Result = &(
+ GetVersionResult,
+ StoreSecretResult,
+ GetSecretResult,
+)
+
+GetVersionResult = (version : uint)
+
+StoreSecretResult = ()
+
+GetSecretResult = (secret : Secret)
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index 6818298..c130a3a 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -27,8 +27,14 @@
],
rustlibs: [
"libsecretkeeper_comm_nostd",
+ "libsecretkeeper_core_nostd",
"android.hardware.security.secretkeeper-V1-rust",
+ "libauthgraph_boringssl",
+ "libauthgraph_core",
+ "libcoset",
+ "libauthgraph_vts_test",
"libbinder_rs",
+ "libcoset",
"liblog_rust",
],
require_root: true,
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 28923f7..a473bd0 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -16,20 +16,53 @@
#[cfg(test)]
use binder::StatusCode;
+use coset::{CborSerializable, CoseEncrypt0};
use log::warn;
+use secretkeeper_core::cipher;
use secretkeeper_comm::data_types::error::SecretkeeperError;
use secretkeeper_comm::data_types::request::Request;
use secretkeeper_comm::data_types::request_response_impl::{
- GetVersionRequest, GetVersionResponse,
-};
+ GetVersionRequest, GetVersionResponse, GetSecretRequest, GetSecretResponse, StoreSecretRequest,
+ StoreSecretResponse };
+use secretkeeper_comm::data_types::{Id, ID_SIZE, Secret, SECRET_SIZE};
use secretkeeper_comm::data_types::response::Response;
use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
+use authgraph_vts_test as ag_vts;
+use authgraph_boringssl as boring;
+use authgraph_core::key;
const SECRETKEEPER_IDENTIFIER: &str =
"android.hardware.security.secretkeeper.ISecretkeeper/nonsecure";
const CURRENT_VERSION: u64 = 1;
+// TODO(b/291238565): This will change once libdice_policy switches to Explicit-key DiceCertChain
+// This is generated by patching libdice_policy such that it dumps an example dice chain &
+// a policy, such that the former matches the latter.
+const HYPOTHETICAL_DICE_POLICY: [u8; 43] = [
+ 0x83, 0x01, 0x81, 0x83, 0x01, 0x80, 0xA1, 0x01, 0x00, 0x82, 0x83, 0x01, 0x81, 0x01, 0x73, 0x74,
+ 0x65, 0x73, 0x74, 0x69, 0x6E, 0x67, 0x5F, 0x64, 0x69, 0x63, 0x65, 0x5F, 0x70, 0x6F, 0x6C, 0x69,
+ 0x63, 0x79, 0x83, 0x02, 0x82, 0x03, 0x18, 0x64, 0x19, 0xE9, 0x75,
+];
+
+// Random bytes (of ID_SIZE/SECRET_SIZE) generated for tests.
+const ID_EXAMPLE: [u8; ID_SIZE] = [
+ 0xF1, 0xB2, 0xED, 0x3B, 0xD1, 0xBD, 0xF0, 0x7D, 0xE1, 0xF0, 0x01, 0xFC, 0x61, 0x71, 0xD3, 0x42,
+ 0xE5, 0x8A, 0xAF, 0x33, 0x6C, 0x11, 0xDC, 0xC8, 0x6F, 0xAE, 0x12, 0x5C, 0x26, 0x44, 0x6B, 0x86,
+ 0xCC, 0x24, 0xFD, 0xBF, 0x91, 0x4A, 0x54, 0x84, 0xF9, 0x01, 0x59, 0x25, 0x70, 0x89, 0x38, 0x8D,
+ 0x5E, 0xE6, 0x91, 0xDF, 0x68, 0x60, 0x69, 0x26, 0xBE, 0xFE, 0x79, 0x58, 0xF7, 0xEA, 0x81, 0x7D,
+];
+const ID_NOT_STORED: [u8; ID_SIZE] = [
+ 0x56, 0xD0, 0x4E, 0xAA, 0xC1, 0x7B, 0x55, 0x6B, 0xA0, 0x2C, 0x65, 0x43, 0x39, 0x0A, 0x6C, 0xE9,
+ 0x1F, 0xD0, 0x0E, 0x20, 0x3E, 0xFB, 0xF5, 0xF9, 0x3F, 0x5B, 0x11, 0x1B, 0x18, 0x73, 0xF6, 0xBB,
+ 0xAB, 0x9F, 0xF2, 0xD6, 0xBD, 0xBA, 0x25, 0x68, 0x22, 0x30, 0xF2, 0x1F, 0x90, 0x05, 0xF3, 0x64,
+ 0xE7, 0xEF, 0xC6, 0xB6, 0xA0, 0x85, 0xC9, 0x40, 0x40, 0xF0, 0xB4, 0xB9, 0xD8, 0x28, 0xEE, 0x9C,
+];
+const SECRET_EXAMPLE: [u8; SECRET_SIZE] = [
+ 0xA9, 0x89, 0x97, 0xFE, 0xAE, 0x97, 0x55, 0x4B, 0x32, 0x35, 0xF0, 0xE8, 0x93, 0xDA, 0xEA, 0x24,
+ 0x06, 0xAC, 0x36, 0x8B, 0x3C, 0x95, 0x50, 0x16, 0x67, 0x71, 0x65, 0x26, 0xEB, 0xD0, 0xC3, 0x98,
+];
+
fn get_connection() -> Option<binder::Strong<dyn ISecretkeeper>> {
match binder::get_interface(SECRETKEEPER_IDENTIFIER) {
Ok(sk) => Some(sk),
@@ -43,63 +76,149 @@
}
}
-// TODO(b/2797757): Add tests that match different HAL defined objects (like request/response)
-// with expected bytes.
+/// Secretkeeper client information.
+struct SkClient {
+ sk: binder::Strong<dyn ISecretkeeper>,
+ aes_keys: [key::AesKey; 2],
+ session_id: Vec<u8>,
+}
+impl SkClient {
+ fn new() -> Option<Self> {
+ let sk = get_connection()?;
+ let (aes_keys, session_id) = authgraph_key_exchange(sk.clone());
+ Some(Self {
+ sk,
+ aes_keys,
+ session_id,
+ })
+ }
+ /// Wrapper around `ISecretkeeper::processSecretManagementRequest` that handles
+ /// encryption and decryption.
+ fn secret_management_request(&self, req_data: &[u8]) -> Vec<u8> {
+ let aes_gcm = boring::BoringAes;
+ let rng = boring::BoringRng;
+ let request_bytes = cipher::encrypt_message(
+ &aes_gcm,
+ &rng,
+ &self.aes_keys[0],
+ &self.session_id,
+ &req_data,
+ )
+ .unwrap();
+
+ let response_bytes = self
+ .sk
+ .processSecretManagementRequest(&request_bytes)
+ .unwrap();
+
+ let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes).unwrap();
+ cipher::decrypt_message(&aes_gcm, &self.aes_keys[1], &response_encrypt0).unwrap()
+ }
+}
+
+/// Perform AuthGraph key exchange, returning the session keys and session ID.
+fn authgraph_key_exchange(sk: binder::Strong<dyn ISecretkeeper>) -> ([key::AesKey; 2], Vec<u8>) {
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_mainline(&mut source, sink)
+}
+
+/// Test that the AuthGraph instance returned by SecretKeeper correctly performs
+/// mainline key exchange against a local source implementation.
#[test]
-fn secret_management_get_version() {
- let secretkeeper = match get_connection() {
+fn authgraph_mainline() {
+ let sk = match get_connection() {
Some(sk) => sk,
None => {
warn!("Secretkeeper HAL is unavailable, skipping test");
return;
}
};
+ let (_aes_keys, _session_id) = authgraph_key_exchange(sk);
+}
+
+/// Test that the AuthGraph instance returned by SecretKeeper correctly rejects
+/// a corrupted session ID signature.
+#[test]
+fn authgraph_corrupt_sig() {
+ let sk = match get_connection() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_corrupt_sig(&mut source, sink);
+}
+
+/// Test that the AuthGraph instance returned by SecretKeeper correctly detects
+/// when corrupted keys are returned to it.
+#[test]
+fn authgraph_corrupt_keys() {
+ let sk = match get_connection() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+ let sink = sk.getAuthGraphKe().expect("failed to get AuthGraph");
+ let mut source = ag_vts::test_ag_participant().expect("failed to create a local source");
+ ag_vts::sink::test_corrupt_keys(&mut source, sink);
+}
+
+// TODO(b/2797757): Add tests that match different HAL defined objects (like request/response)
+// with expected bytes.
+
+#[test]
+fn secret_management_get_version() {
+ let sk_client = match SkClient::new() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+
let request = GetVersionRequest {};
let request_packet = request.serialize_to_packet();
- let request_bytes = request_packet.into_bytes().unwrap();
+ let request_bytes = request_packet.to_vec().unwrap();
- // TODO(b/291224769) The request will need to be encrypted & response need to be decrypted
- // with key & related artifacts pre-shared via Authgraph Key Exchange HAL.
+ let response_bytes = sk_client.secret_management_request(&request_bytes);
- let response_bytes = secretkeeper
- .processSecretManagementRequest(&request_bytes)
- .unwrap();
-
- let response_packet = ResponsePacket::from_bytes(&response_bytes).unwrap();
+ let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
assert_eq!(
response_packet.response_type().unwrap(),
ResponseType::Success
);
let get_version_response =
*GetVersionResponse::deserialize_from_packet(response_packet).unwrap();
- assert_eq!(get_version_response.version(), CURRENT_VERSION);
+ assert_eq!(get_version_response.version, CURRENT_VERSION);
}
#[test]
fn secret_management_malformed_request() {
- let secretkeeper = match get_connection() {
+ let sk_client = match SkClient::new() {
Some(sk) => sk,
None => {
warn!("Secretkeeper HAL is unavailable, skipping test");
return;
}
};
+
let request = GetVersionRequest {};
let request_packet = request.serialize_to_packet();
- let mut request_bytes = request_packet.into_bytes().unwrap();
+ let mut request_bytes = request_packet.to_vec().unwrap();
// Deform the request
request_bytes[0] = !request_bytes[0];
- // TODO(b/291224769) The request will need to be encrypted & response need to be decrypted
- // with key & related artifacts pre-shared via Authgraph Key Exchange HAL.
+ let response_bytes = sk_client.secret_management_request(&request_bytes);
- let response_bytes = secretkeeper
- .processSecretManagementRequest(&request_bytes)
- .unwrap();
-
- let response_packet = ResponsePacket::from_bytes(&response_bytes).unwrap();
+ let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
assert_eq!(
response_packet.response_type().unwrap(),
ResponseType::Error
@@ -107,3 +226,86 @@
let err = *SecretkeeperError::deserialize_from_packet(response_packet).unwrap();
assert_eq!(err, SecretkeeperError::RequestMalformed);
}
+
+#[test]
+fn secret_management_store_get_secret_found() {
+ let sk_client = match SkClient::new() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+
+ let store_request = StoreSecretRequest {
+ id: Id(ID_EXAMPLE),
+ secret: Secret(SECRET_EXAMPLE),
+ sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
+ };
+
+ let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+
+ let store_response = sk_client.secret_management_request(&store_request);
+ let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+
+ assert_eq!(
+ store_response.response_type().unwrap(),
+ ResponseType::Success
+ );
+ // Really just checking that the response is indeed StoreSecretResponse
+ let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
+
+ // Get the secret that was just stored
+ let get_request = GetSecretRequest {
+ id: Id(ID_EXAMPLE),
+ updated_sealing_policy: None,
+ };
+ let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+
+ let get_response = sk_client.secret_management_request(&get_request);
+ let get_response = ResponsePacket::from_slice(&get_response).unwrap();
+ assert_eq!(get_response.response_type().unwrap(), ResponseType::Success);
+ let get_response = *GetSecretResponse::deserialize_from_packet(get_response).unwrap();
+ assert_eq!(get_response.secret.0, SECRET_EXAMPLE);
+}
+
+#[test]
+fn secret_management_store_get_secret_not_found() {
+ let sk_client = match SkClient::new() {
+ Some(sk) => sk,
+ None => {
+ warn!("Secretkeeper HAL is unavailable, skipping test");
+ return;
+ }
+ };
+
+ // Store a secret (corresponding to an id).
+ let store_request = StoreSecretRequest {
+ id: Id(ID_EXAMPLE),
+ secret: Secret(SECRET_EXAMPLE),
+ sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
+ };
+
+ let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+ let store_response = sk_client.secret_management_request(&store_request);
+ let store_response = ResponsePacket::from_slice(&store_response).unwrap();
+
+ assert_eq!(
+ store_response.response_type().unwrap(),
+ ResponseType::Success
+ );
+
+ // (Try to) Get the secret that was never stored
+ let get_request = GetSecretRequest {
+ id: Id(ID_NOT_STORED),
+ updated_sealing_policy: None,
+ };
+ let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+ let get_response = sk_client.secret_management_request(&get_request);
+
+ // Check that response is `SecretkeeperError::EntryNotFound`
+ let get_response = ResponsePacket::from_slice(&get_response).unwrap();
+ assert_eq!(get_response.response_type().unwrap(), ResponseType::Error);
+ let err = *SecretkeeperError::deserialize_from_packet(get_response).unwrap();
+ assert_eq!(err, SecretkeeperError::EntryNotFound);
+}
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
index 1c39fa6..08cc67a 100644
--- a/security/secretkeeper/default/Android.bp
+++ b/security/secretkeeper/default/Android.bp
@@ -22,16 +22,55 @@
name: "android.hardware.security.secretkeeper-service.nonsecure",
relative_install_path: "hw",
vendor: true,
- init_rc: ["secretkeeper.rc"],
- vintf_fragments: ["secretkeeper.xml"],
+ installable: false, // install APEX
+ prefer_rlib: true,
+ defaults: [
+ "authgraph_use_latest_hal_aidl_rust",
+ ],
rustlibs: [
"android.hardware.security.secretkeeper-V1-rust",
"libandroid_logger",
+ "libauthgraph_boringssl",
+ "libauthgraph_core",
+ "libauthgraph_hal",
"libbinder_rs",
"liblog_rust",
"libsecretkeeper_comm_nostd",
+ "libsecretkeeper_core_nostd",
+ "libsecretkeeper_hal",
],
srcs: [
"src/main.rs",
],
}
+
+prebuilt_etc {
+ name: "secretkeeper.rc",
+ src: "secretkeeper.rc",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "secretkeeper.xml",
+ src: "secretkeeper.xml",
+ sub_dir: "vintf",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.security.secretkeeper",
+ manifest: "apex_manifest.json",
+ file_contexts: "apex_file_contexts",
+ key: "com.android.hardware.key",
+ certificate: ":com.android.hardware.certificate",
+ vendor: true,
+ updatable: false,
+
+ binaries: [
+ "android.hardware.security.secretkeeper-service.nonsecure",
+ ],
+ prebuilts: [
+ "secretkeeper.rc",
+ "secretkeeper.xml",
+ ],
+}
diff --git a/security/secretkeeper/default/apex_file_contexts b/security/secretkeeper/default/apex_file_contexts
new file mode 100644
index 0000000..71369a8
--- /dev/null
+++ b/security/secretkeeper/default/apex_file_contexts
@@ -0,0 +1,3 @@
+(/.*)? u:object_r:vendor_file:s0
+/etc(/.*)? u:object_r:vendor_configs_file:s0
+/bin/hw/android\.hardware\.security\.secretkeeper-service\.nonsecure u:object_r:hal_secretkeeper_default_exec:s0
diff --git a/security/secretkeeper/default/apex_manifest.json b/security/secretkeeper/default/apex_manifest.json
new file mode 100644
index 0000000..7287095
--- /dev/null
+++ b/security/secretkeeper/default/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.security.secretkeeper",
+ "version": 1
+}
\ No newline at end of file
diff --git a/security/secretkeeper/default/secretkeeper.rc b/security/secretkeeper/default/secretkeeper.rc
index f39f9b7..38ee50d 100644
--- a/security/secretkeeper/default/secretkeeper.rc
+++ b/security/secretkeeper/default/secretkeeper.rc
@@ -1,4 +1,4 @@
-service vendor.secretkeeper /vendor/bin/hw/android.hardware.security.secretkeeper-service.nonsecure
+service vendor.secretkeeper /apex/com.android.hardware.security.secretkeeper/bin/hw/android.hardware.security.secretkeeper-service.nonsecure
interface aidl android.hardware.security.secretkeeper.ISecretkeeper/nonsecure
class hal
user nobody
diff --git a/security/secretkeeper/default/src/main.rs b/security/secretkeeper/default/src/main.rs
index 2d367c5..c8c1521 100644
--- a/security/secretkeeper/default/src/main.rs
+++ b/security/secretkeeper/default/src/main.rs
@@ -14,80 +14,111 @@
* limitations under the License.
*/
-use binder::{BinderFeatures, Interface};
+//! Non-secure implementation of the Secretkeeper HAL.
+mod store;
+
+use authgraph_boringssl as boring;
+use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
+use authgraph_core::ta::{AuthGraphTa, Role};
+use authgraph_hal::channel::SerializedChannel;
use log::{error, info, Level};
-use secretkeeper_comm::data_types::error::SecretkeeperError;
-use secretkeeper_comm::data_types::packet::{RequestPacket, ResponsePacket};
-use secretkeeper_comm::data_types::request::Request;
-use secretkeeper_comm::data_types::request_response_impl::{
- GetVersionRequest, GetVersionResponse, Opcode,
-};
-use secretkeeper_comm::data_types::response::Response;
+use secretkeeper_core::ta::SecretkeeperTa;
+use secretkeeper_hal::SecretkeeperService;
+use std::sync::Arc;
+use std::sync::Mutex;
+use store::InMemoryStore;
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
- BnSecretkeeper, BpSecretkeeper, ISecretkeeper,
+ BpSecretkeeper, ISecretkeeper,
};
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::mpsc;
-const CURRENT_VERSION: u64 = 1;
+/// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
+/// insecure).
+pub struct LocalTa {
+ in_tx: mpsc::Sender<Vec<u8>>,
+ out_rx: mpsc::Receiver<Vec<u8>>,
+}
-#[derive(Debug, Default)]
-pub struct NonSecureSecretkeeper;
+/// Prefix byte for messages intended for the AuthGraph TA.
+const AG_MESSAGE_PREFIX: u8 = 0x00;
+/// Prefix byte for messages intended for the Secretkeeper TA.
+const SK_MESSAGE_PREFIX: u8 = 0x01;
-impl Interface for NonSecureSecretkeeper {}
+impl LocalTa {
+ /// Create a new instance.
+ pub fn new() -> Self {
+ // Create a pair of channels to communicate with the TA thread.
+ let (in_tx, in_rx) = mpsc::channel();
+ let (out_tx, out_rx) = mpsc::channel();
-impl ISecretkeeper for NonSecureSecretkeeper {
- fn processSecretManagementRequest(&self, request: &[u8]) -> binder::Result<Vec<u8>> {
- Ok(self.process_opaque_request(request))
+ // The TA code expects to run single threaded, so spawn a thread to run it in.
+ std::thread::spawn(move || {
+ let mut crypto_impls = boring::crypto_trait_impls();
+ let storage_impl = Box::new(InMemoryStore::default());
+ let sk_ta = Rc::new(RefCell::new(
+ SecretkeeperTa::new(&mut crypto_impls, storage_impl)
+ .expect("Failed to create local Secretkeeper TA"),
+ ));
+ let mut ag_ta = AuthGraphTa::new(
+ AuthGraphParticipant::new(crypto_impls, sk_ta.clone(), MAX_OPENED_SESSIONS)
+ .expect("Failed to create local AuthGraph TA"),
+ Role::Sink,
+ );
+
+ // Loop forever processing request messages.
+ loop {
+ let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+ let rsp_data = match req_data[0] {
+ AG_MESSAGE_PREFIX => ag_ta.process(&req_data[1..]),
+ SK_MESSAGE_PREFIX => {
+ // It's safe to `borrow_mut()` because this code is not a callback
+ // from AuthGraph (the only other holder of an `Rc`), and so there
+ // can be no live `borrow()`s in this (single) thread.
+ sk_ta.borrow_mut().process(&req_data[1..])
+ }
+ prefix => panic!("unexpected messageprefix {prefix}!"),
+ };
+ out_tx.send(rsp_data).expect("failed to send out rsp");
+ }
+ });
+ Self { in_tx, out_rx }
+ }
+
+ fn execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8> {
+ let mut prefixed_req = Vec::with_capacity(req_data.len() + 1);
+ prefixed_req.push(prefix);
+ prefixed_req.extend_from_slice(req_data);
+ self.in_tx
+ .send(prefixed_req)
+ .expect("failed to send in request");
+ self.out_rx.recv().expect("failed to receive response")
}
}
-impl NonSecureSecretkeeper {
- // A set of requests to Secretkeeper are 'opaque' - encrypted bytes with inner structure
- // described by CDDL. They need to be decrypted, deserialized and processed accordingly.
- fn process_opaque_request(&self, request: &[u8]) -> Vec<u8> {
- // TODO(b/291224769) The request will need to be decrypted & response need to be encrypted
- // with key & related artifacts pre-shared via Authgraph Key Exchange HAL.
- self.process_opaque_request_unhandled_error(request)
- .unwrap_or_else(
- // SecretkeeperError is also a valid 'Response', serialize to a response packet.
- |sk_err| {
- Response::serialize_to_packet(&sk_err)
- .into_bytes()
- .expect("Panicking due to serialization failing")
- },
- )
+pub struct AuthGraphChannel(Arc<Mutex<LocalTa>>);
+impl SerializedChannel for AuthGraphChannel {
+ const MAX_SIZE: usize = usize::MAX;
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ Ok(self
+ .0
+ .lock()
+ .unwrap()
+ .execute_for(AG_MESSAGE_PREFIX, req_data))
}
+}
- fn process_opaque_request_unhandled_error(
- &self,
- request: &[u8],
- ) -> Result<Vec<u8>, SecretkeeperError> {
- let request_packet = RequestPacket::from_bytes(request).map_err(|e| {
- error!("Failed to get Request packet from bytes: {:?}", e);
- SecretkeeperError::RequestMalformed
- })?;
- let response_packet = match request_packet
- .opcode()
- .map_err(|_| SecretkeeperError::RequestMalformed)?
- {
- Opcode::GetVersion => Self::process_get_version_request(request_packet)?,
- _ => todo!("TODO(b/291224769): Unimplemented operations"),
- };
-
- response_packet
- .into_bytes()
- .map_err(|_| SecretkeeperError::UnexpectedServerError)
- }
-
- fn process_get_version_request(
- request: RequestPacket,
- ) -> Result<ResponsePacket, SecretkeeperError> {
- // Deserialization really just verifies the structural integrity of the request such
- // as args being empty.
- let _request = GetVersionRequest::deserialize_from_packet(request)
- .map_err(|_| SecretkeeperError::RequestMalformed)?;
- let response = GetVersionResponse::new(CURRENT_VERSION);
- Ok(response.serialize_to_packet())
+pub struct SecretkeeperChannel(Arc<Mutex<LocalTa>>);
+impl SerializedChannel for SecretkeeperChannel {
+ const MAX_SIZE: usize = usize::MAX;
+ fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+ Ok(self
+ .0
+ .lock()
+ .unwrap()
+ .execute_for(SK_MESSAGE_PREFIX, req_data))
}
}
@@ -104,17 +135,17 @@
error!("{}", panic_info);
}));
- let service = NonSecureSecretkeeper::default();
- let service_binder = BnSecretkeeper::new_binder(service, BinderFeatures::default());
+ let ta = Arc::new(Mutex::new(LocalTa::new()));
+ let ag_channel = AuthGraphChannel(ta.clone());
+ let sk_channel = SecretkeeperChannel(ta.clone());
+
+ let service = SecretkeeperService::new_as_binder(sk_channel, ag_channel);
let service_name = format!(
"{}/nonsecure",
<BpSecretkeeper as ISecretkeeper>::get_descriptor()
);
- binder::add_service(&service_name, service_binder.as_binder()).unwrap_or_else(|e| {
- panic!(
- "Failed to register service {} because of {:?}.",
- service_name, e
- );
+ binder::add_service(&service_name, service.as_binder()).unwrap_or_else(|e| {
+ panic!("Failed to register service {service_name} because of {e:?}.",);
});
info!("Registered Binder service, joining threadpool.");
binder::ProcessState::join_thread_pool();
diff --git a/security/secretkeeper/default/src/store.rs b/security/secretkeeper/default/src/store.rs
new file mode 100644
index 0000000..7b2d0b9
--- /dev/null
+++ b/security/secretkeeper/default/src/store.rs
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+use secretkeeper_comm::data_types::error::Error;
+use secretkeeper_core::store::KeyValueStore;
+use std::collections::HashMap;
+
+/// An in-memory implementation of KeyValueStore. Please note that this is entirely for
+/// testing purposes. Refer to the documentation of `PolicyGatedStorage` & Secretkeeper HAL for
+/// persistence requirements.
+#[derive(Default)]
+pub struct InMemoryStore(HashMap<Vec<u8>, Vec<u8>>);
+impl KeyValueStore for InMemoryStore {
+ fn store(&mut self, key: &[u8], val: &[u8]) -> Result<(), Error> {
+ // This will overwrite the value if key is already present.
+ let _ = self.0.insert(key.to_vec(), val.to_vec());
+ Ok(())
+ }
+
+ fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
+ let optional_val = self.0.get(key);
+ Ok(optional_val.cloned())
+ }
+}
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 384ee97..08ee773 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -23,18 +23,6 @@
default_applicable_licenses: ["hardware_interfaces_license"],
}
-filegroup {
- name: "sensors-default.rc",
- srcs: ["sensors-default.rc"],
-}
-
-prebuilt_etc {
- name: "sensors-default.xml",
- src: "sensors-default.xml",
- sub_dir: "vintf",
- installable: false,
-}
-
cc_library_static {
name: "libsensorsexampleimpl",
vendor: true,
@@ -59,21 +47,62 @@
cc_binary {
name: "android.hardware.sensors-service.example",
relative_install_path: "hw",
- init_rc: [":sensors-default.rc"],
- vintf_fragments: [":sensors-default.xml"],
+ installable: false, // install APEX below
+
vendor: true,
shared_libs: [
- "libbase",
"libbinder_ndk",
- "libfmq",
- "libpower",
- "libcutils",
"liblog",
- "libutils",
- "android.hardware.sensors-V2-ndk",
],
static_libs: [
+ "android.hardware.common-V2-ndk",
+ "android.hardware.common.fmq-V1-ndk",
+ "android.hardware.sensors-V2-ndk",
+ "android.system.suspend-V1-ndk",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libpower",
"libsensorsexampleimpl",
+ "libutils",
],
srcs: ["main.cpp"],
}
+
+prebuilt_etc {
+ name: "sensors-default.rc",
+ src: "sensors-default.rc",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "sensors-default.xml",
+ src: "sensors-default.xml",
+ sub_dir: "vintf",
+ installable: false,
+}
+
+// Default vendor APEX for android.hardware.sensors.
+// Custom implementations may use override_apex based on this APEX.
+apex {
+ name: "com.android.hardware.sensors",
+ manifest: "apex_manifest.json",
+ key: "com.android.hardware.key",
+ certificate: ":com.android.hardware.certificate",
+ file_contexts: "file_contexts",
+ updatable: false,
+ vendor: true,
+
+ binaries: ["android.hardware.sensors-service.example"],
+ prebuilts: [
+ "sensors-default.rc", // init rc
+ "sensors-default.xml", // vintf fragment
+ "android.hardware.sensor.ambient_temperature.prebuilt.xml",
+ "android.hardware.sensor.barometer.prebuilt.xml",
+ "android.hardware.sensor.gyroscope.prebuilt.xml",
+ "android.hardware.sensor.hinge_angle.prebuilt.xml",
+ "android.hardware.sensor.light.prebuilt.xml",
+ "android.hardware.sensor.proximity.prebuilt.xml",
+ "android.hardware.sensor.relative_humidity.prebuilt.xml",
+ ],
+}
diff --git a/sensors/aidl/default/apex/Android.bp b/sensors/aidl/default/apex/Android.bp
deleted file mode 100644
index 5482086..0000000
--- a/sensors/aidl/default/apex/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-package {
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-genrule {
- name: "com.android.hardware.sensors.rc-gen",
- srcs: [":sensors-default.rc"],
- out: ["com.android.hardware.sensors.rc"],
- cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.sensors/' $(in) > $(out)",
-}
-
-prebuilt_etc {
- name: "com.android.hardware.sensors.rc",
- src: ":com.android.hardware.sensors.rc-gen",
- installable: false,
-}
-
-// Default vendor APEX for android.hardware.sensors.
-// Custom implementations may use override_apex based on this APEX.
-apex {
- name: "com.android.hardware.sensors",
- manifest: "apex_manifest.json",
- key: "com.android.hardware.key",
- certificate: ":com.android.hardware.certificate",
- file_contexts: "file_contexts",
- updatable: false,
- vendor: true,
-
- binaries: ["android.hardware.sensors-service.example"],
- prebuilts: [
- "com.android.hardware.sensors.rc", // init rc
- "sensors-default.xml", // vintf fragment
- "android.hardware.sensor.ambient_temperature.prebuilt.xml",
- "android.hardware.sensor.barometer.prebuilt.xml",
- "android.hardware.sensor.gyroscope.prebuilt.xml",
- "android.hardware.sensor.hinge_angle.prebuilt.xml",
- "android.hardware.sensor.light.prebuilt.xml",
- "android.hardware.sensor.proximity.prebuilt.xml",
- "android.hardware.sensor.relative_humidity.prebuilt.xml",
- ],
-}
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey b/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
deleted file mode 100644
index 98dfb71..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.pem
deleted file mode 100644
index a2f1833..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEArUwl9rjXtNrSqJ2rfEryTnVEte7uhZlsn42rXRHFZtuV8N03
-AKAFDDkhJIT+FqmVJLW1Whrno+goaKzA23BodZcSo/xOJuTopgQ/TVqIO2QZ2WUS
-1NiYT3+kydZgtBHhfS+ek9h6aTLgJUn/XBX2xgEA6kp/NkcLpGkqj9Xs7XUpG+n/
-KnyYg+/YFqooEKHTTi4dT9YgRblgzv5zhCKxjB9gqy8dmhwDTpbPGavNiMIZvnSs
-aQzXh7+UMwte+V4QdaEqonoVWm85vEh6rsPpvvmxvlkVnUstRWRwsvbA183gvwZg
-f7OmAgpVu0kEkSHpoJJWpDUhzxmTdxmwvmL92eCJqQUjvxLqak4uBt+epUgbgxcA
-nS7rNg6PsNlHhYl5wRArPP17iW/QK3qnoz8rKgJCtdxPPD13byA13eY9q+Fdwb2H
-uHxGu1iYlRxUAzptvb6pIED/v9MMw/g3yMJkR89WG+pBLbUXHko6H0qOVchYrd8C
-OtcGo7GBBPbJmj9ZGZDX7p5YBSdTZs8f9wWqJmXkfVR60zZE0dOnOchzL44c8oUh
-uwEZMee7Ae/2LfWnfIe5KBNTvvH1CzU8KbQUJJVbATbb3j/eYExgsbnk0WgFi6i4
-osuJZZmfC44tAg18gXozcji+xYuW3MIMV2+drdc3xXn7LXKn5JZCLVJ6n+cCAwEA
-AQKCAgATT6P/XVO0NJo67e75F8Tul0TD3U85FgKzuO66nUtZDekkgRIrAKnvVcJq
-tmM2FUmoYJNH6i2b5zfxiianjVwmlmIeYfQ3g1Slg12megsqSxpSTmAN1eELItcz
-Iq9+AWwWLiNGqF3jsSanIRrSoSPxppT6hrisTLhwZsO2aYlQYLjnAmlLy7yXHzf+
-NpHmYJISaTMc/Wh1PJYcGuC2fcM5MRntmX9799kqfcWwP6PUtIR347p+rk6qMuAJ
-3B+GPEQrR31fw6jzfed6Ir2BEhXPETYMVxMAhysRS4L/fl247pk30Dcao+NA4PPy
-vc1Devr0yLnc7IrK8DetkvBOFuvgl53gHPZ4f7ge2PQMPghwjBaFuXklcfY96PVw
-Yo/CyAN+VEANThFFcKUzovtHI6m3sNTlxE6F+AYvx5dE/WZKmE5/cYCSJ8bhLPJl
-G68VkdeNv0LMZ/7rf1OEWP/YWw/5/tQ7MJ0IO5GShjE2EAGG0SZgK8/fwHZZJFES
-oYVWlriGtGDfiYjPLqVIjdZI6iOo6BMQh6pl0TPIJpn3ODqtRy8gN3TMvG6VcTJy
-QE3Z+br7UsK4gXSw0+MNLC3VKhX2bjT5q9lVpVnLv4L7q1ad4kwHblFAo686ZbWt
-eKTUv7QTI3fFqYeZEgCqRBQZ3UoKyWOBg0MAbf26hZFTFFpbEQKCAQEA2JdW6wDM
-iO1haR168l497nUC382/f/fJA8vzFdJ7cHVM95Tx/5JNYNJSL30XDyux9RJNqnFu
-tByec4c5CVuX/Gv/B4Q++xaaI7OVT9hTl/aoTShObGRJGbVh8xZagb7on7dAfD6G
-1SzTaahxQT5neoiki13GvJ6teL+0ZbCxRDMfPyy79lRzH5d0mw+EQvtc0Vvkweyj
-zf/Mn0yMZHO19oCKjJo8QkciseOqaS2mpgtOiRDc01uuaFAcw6taiERrR86xK2Yl
-OowIx6Yu8n7jRyTGUfr2Oz97a/zDVMVRi3BuyePOyCD9PfUmoj9JyCFbQSS1Lq3N
-AWacnNwQpkDDiQKCAQEAzNQ3/hKhjrLyEm2ktQk1Tzyk4eGu/NElxSKM7uJTeU0k
-xxKuMNMQCJbZmklJKojVYZ0fsh6AyLEpBMV6mWTmVo0qA/A09jKD2tsKu52KGCMt
-vgrN4Gi5JJJACNbtpG7uSJstAYuUGYQSTuS/xCE+urgMVbWBTocsf0bEeEe0FRWX
-txhS/zdj6wspTd6lJ0SSahWG/BsV7990zaRDGYv0N1+SwF8/C0Ml99WbyRof6oP9
-jx0esKA+giWc5lSk+Ag2gpsTIH36aF53lQnDBZL3hqSgqP0ollKa9Uyjfmp65D1m
-TwoENrKnVNO5ZKteTM3SGQ+zsHxBPpinK7T2BPe77wKCAQBdS+Nu2ys/mDErnD1H
-hXzb6J9SVEg3ET8PWZzeO4pciMqcoxYS5qxaFn68Yf+60zGWxUmbL71l7CX80bSp
-6UBwxPxX+ok+kx/WXRbmC+MGRIN+qOwPGKu8XTtSAMD/voJpugAXBMADt4lhq+MN
-HZppV865Ea33tco3hyxn2VKic/rztYtJslrcstrRqD9qsufqbtD9D7gHljZIMCsR
-Yh5xjjEgG5f1XLr/MXhIUhfE0n4D4LWefZGE8W1Sg889f2tOxSPf8+H5dDSb+2Oh
-pTK1hIvA6H+ESfYaMAjbzRsxGz89y9lYr40mUSFRJj3b7TJnvy4ka00xW0f+8XRi
-iOcxAoIBAB0o8Te4i0t3akL5XQNw5if7qDWIHZNcaxYfjxTLH7sbIms825OT2KqA
-X0Y5vLLTfB1Dcym2cfsgTYiiXIvN84TK3/pjjgamtmLH4EVJbkl1aKOvghO6lPEB
-6R/ZCUfpiv7HKKcZqeHgDYMxyaMwYG/Ql+Dz0A7P66PK/VlqS9bclha43cf7qLvj
-gOPXGIf4mSeFHQxzBrJ5i3VjNzJB3GitsIS2ipEd5B/eRylgEL8gP07KhH38silx
-FV8tGbc95BS/4v8zMBz/peKP2zXF8Hs4oK6uK8MKy4i0emoa2pf3rcL+2A65bF0F
-L1WHmAszGf/7Xkd3yQoSTWpJfuTCJ/0CggEBAJjkBaEoiRYp0RBq1Ty0wa+xbPHp
-gAcpco+VC3T8uqniKBDrf5QsMDm7+P9IZRYrfgyy0KFeG4mHrTt61JgOLnhSTOyz
-EEChc8SOn6+vqMB36FmSSqVb6CdLEZhv5dtTzzHgyd3xS3cwga9Mf2SCoG/l34HJ
-XzfoQyLKvqF0kWOq/76k+kBM5QwWIGc2fVXcpJpWaAuPWKDQJnkvTcPp8XPyEADv
-z2YbSDDqqcwczX2DWepf2t2RU1fdyjS5wS6pNDvsuyd6gwUTQT1P5ODHbIdAwcdi
-5Gxui8voJmzvrfabIsN6H73ZS4Lw20ZB+ejYyiwxZcb0os45C1coicMJ9wQ=
------END RSA PRIVATE KEY-----
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.pk8 b/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
deleted file mode 100644
index 7a1cca0..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.pk8
+++ /dev/null
Binary files differ
diff --git a/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem b/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
deleted file mode 100644
index 20a06f9..0000000
--- a/sensors/aidl/default/apex/com.android.hardware.sensors.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3TCCA8UCFAbIl4RS714WSLo4k64MHsINz4VEMA0GCSqGSIb3DQEBCwUAMIGp
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
-LmFuZHJvaWQuaGFyZHdhcmUuc2Vuc29yczAgFw0yMTA5MDMxNjEyNDNaGA80NzU5
-MDczMTE2MTI0M1owgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5oYXJkd2FyZS5zZW5zb3JzMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnluNTPcq4pDEeb5gEYszRYQCawq8czUY
-J+x2b0i7qO2wLidX45CX6BLZ9N7c5veoV3FvC1wMTRR6lGAyg7UbD80vVmPdmr6R
-vw2AdIqrghXinvAEv6gxQQPVQa8UHkCL4lULLXo2gdmoCBM8VJHihjO/2F8ZLsP/
-nKhYx9Nr6w9LEyalmHTkXOgNyrNprpbJwugdk3hDXbAK+j5nF9fsz/iWFoXnPuNe
-oqdWj21YhXKDAbewBXaM6l3qmTdGsVVJL4HmVURGUY2f2UZwMWTEjpy9UDzyfqqg
-CSdH1RLmGVAINyfNI3Zswo0CjnOCf0jW6mq9/6mfGYu8hBCrky/rOH8reDwYZTGe
-H6JbNj0dhEN5HzQcxGEQQ43L1nmH7XlnuPO0xPSsw5binPVuUvURivR3PSsFgpPl
-0Uche62XgLAXCXhNV2uUQtZLVFGug7JcGgS4O3GoKr6w35Q+W9SEXanXFMW6X+wN
-hkbhB4MDSuKTZrjEnZEyxMOLG8ILN9i7osa+yjWONTn9bZc6q3Y9jyu3u84o8kC8
-KDcvr8YZEL63nQsQXO44GiQmqBptuB+ehcAC6uRCKkY9tQ95EQ7laGQ3C85d3gPj
-NcGjT7SSuUir7n+LI9pZsotedd9+rGhiiyT8CM4sVWiYJFnA2UX/bsnkZyAOq9Po
-jz1aMdHc4wUCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEATEPN2SZk8pJc4DaWmhyR
-MUklzVeuN0J0Mij1mHuVmID7Q5IhBBXxtVmwRIo208rHSvFLAo7Z4FnuZCV3A/c9
-TlXT3S2t+iYG5eOyXSsoSc/uerJ7kIBcOe27qIrO9GwcK5CQlTaXP+CG1gbLp1nl
-IaqKAT+eb/ji5wmFxMI77wo3uKLPTCfpaptFNaYlRqvxiXdJsCZwCPgmCtXJUeeZ
-R/HKOA4PcS2QB+HwhYePY5kUJPwt6MwJEyno72oenfl49FrGHj0BzVmQ7KMfiYjZ
-eRSB2Wbo50xfiICkPlUcvWD8rRNg7N9CM/Q5O0MW3ivAe42aGap/8qfXUa+L5vu4
-9vaxgQvBVcPXE/pyeCYM8beB84Us+FOYPC7gIUhcctBqGYAQmHzp3sXvIg0DVxz7
-0aqolFGpjRFqbgheS9WRkDHFpYrhR1XMVOQjussHqWEyRcvliqeFlZr8+JNkJNi+
-lmGMdnEAWZs8PL0/AEf+8y0Nr/w0k3Y6IZCDcwpxbpJQOU5pAbkfUzEJHkxMfuvW
-ZshvqIMOaLWCGxZaxlbLRxWGuarWYzfmDY3n9TwJmAIUdMLiswv3UsCmLBJO1XGX
-SUWfgi4fyG1/phfzhdU3efMvmN+XT16/ykMrY8P5S+ghwK12IZ3DgTl0ooLFABUj
-zYeQ8LLz3SP9LNgeLnPP/po=
------END CERTIFICATE-----
diff --git a/sensors/aidl/default/apex/apex_manifest.json b/sensors/aidl/default/apex_manifest.json
similarity index 100%
rename from sensors/aidl/default/apex/apex_manifest.json
rename to sensors/aidl/default/apex_manifest.json
diff --git a/sensors/aidl/default/apex/file_contexts b/sensors/aidl/default/file_contexts
similarity index 100%
rename from sensors/aidl/default/apex/file_contexts
rename to sensors/aidl/default/file_contexts
diff --git a/sensors/aidl/default/sensors-default.rc b/sensors/aidl/default/sensors-default.rc
index 96da85d..e0b0ef0 100644
--- a/sensors/aidl/default/sensors-default.rc
+++ b/sensors/aidl/default/sensors-default.rc
@@ -1,4 +1,4 @@
-service vendor.sensors-default /vendor/bin/hw/android.hardware.sensors-service.example
+service vendor.sensors-default /apex/com.android.hardware.sensors/bin/hw/android.hardware.sensors-service.example
class hal
user system
group system
diff --git a/thermal/aidl/Android.bp b/thermal/aidl/Android.bp
index 9382b94..734aab7 100644
--- a/thermal/aidl/Android.bp
+++ b/thermal/aidl/Android.bp
@@ -45,6 +45,6 @@
imports: [],
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
index 1f87cf2..5e88aa0 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingType.aidl
@@ -46,4 +46,8 @@
POWER_AMPLIFIER,
DISPLAY,
SPEAKER,
+ WIFI,
+ CAMERA,
+ FLASHLIGHT,
+ USB_PORT,
}
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
index e9710a7..665a36e 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/TemperatureType.aidl
@@ -35,7 +35,7 @@
/* @hide */
@Backing(type="int") @VintfStability
enum TemperatureType {
- UNKNOWN = (-1),
+ UNKNOWN = (-1) /* -1 */,
CPU = 0,
GPU = 1,
BATTERY = 2,
@@ -50,4 +50,10 @@
DISPLAY = 11,
MODEM = 12,
SOC = 13,
+ WIFI = 14,
+ CAMERA = 15,
+ FLASHLIGHT = 16,
+ SPEAKER = 17,
+ AMBIENT = 18,
+ POGO = 19,
}
diff --git a/thermal/aidl/android/hardware/thermal/CoolingType.aidl b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
index 08beb55..c00028d 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingType.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingType.aidl
@@ -34,4 +34,8 @@
POWER_AMPLIFIER,
DISPLAY,
SPEAKER,
+ WIFI,
+ CAMERA,
+ FLASHLIGHT,
+ USB_PORT,
}
diff --git a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
index 467d096..ce2a9fc 100644
--- a/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
+++ b/thermal/aidl/android/hardware/thermal/TemperatureType.aidl
@@ -44,4 +44,10 @@
DISPLAY = 11,
MODEM = 12,
SOC = 13,
+ WIFI = 14,
+ CAMERA = 15,
+ FLASHLIGHT = 16,
+ SPEAKER = 17,
+ AMBIENT = 18,
+ POGO = 19,
}
diff --git a/thermal/aidl/default/Android.bp b/thermal/aidl/default/Android.bp
index 451e1e2..9fe62ce 100644
--- a/thermal/aidl/default/Android.bp
+++ b/thermal/aidl/default/Android.bp
@@ -27,7 +27,7 @@
vendor: true,
stl: "c++_static",
static_libs: [
- "android.hardware.thermal-V1-ndk",
+ "android.hardware.thermal-V2-ndk",
"libbase",
],
shared_libs: [
diff --git a/thermal/aidl/default/thermal-example.xml b/thermal/aidl/default/thermal-example.xml
index bdee744..08dc68c 100644
--- a/thermal/aidl/default/thermal-example.xml
+++ b/thermal/aidl/default/thermal-example.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.thermal</name>
- <version>1</version>
+ <version>2</version>
<fqname>IThermal/default</fqname>
</hal>
</manifest>
diff --git a/thermal/aidl/vts/Android.bp b/thermal/aidl/vts/Android.bp
index b00eb33..0812811 100644
--- a/thermal/aidl/vts/Android.bp
+++ b/thermal/aidl/vts/Android.bp
@@ -32,7 +32,7 @@
"libbinder_ndk",
],
static_libs: [
- "android.hardware.thermal-V1-ndk",
+ "android.hardware.thermal-V2-ndk",
],
test_suites: [
"vts",
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
index 0212e7e..8a3c6f0 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.cpp
@@ -36,6 +36,7 @@
ALOGE("HdmiCecMock died");
auto hdmiCecMock = static_cast<HdmiCecMock*>(cookie);
hdmiCecMock->mCecThreadRun = false;
+ pthread_join(hdmiCecMock->mThreadId, NULL);
}
ScopedAStatus HdmiCecMock::addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) {
@@ -89,7 +90,9 @@
mCallback = callback;
if (callback != nullptr) {
- AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+ mDeathRecipient =
+ ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
mOutputFile = open(CEC_MSG_OUT_FIFO, O_RDWR | O_CLOEXEC);
@@ -220,7 +223,7 @@
int r = -1;
// Open the input pipe
- while (mInputFile < 0) {
+ while (mCecThreadRun && mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(CEC_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
@@ -257,7 +260,15 @@
HdmiCecMock::HdmiCecMock() {
ALOGE("[halimp_aidl] Opening a virtual CEC HAL for testing and virtual machine.");
mCallback = nullptr;
- mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+}
+
+HdmiCecMock::~HdmiCecMock() {
+ ALOGE("[halimp_aidl] HdmiCecMock shutting down.");
+ mCallback = nullptr;
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+ mCecThreadRun = false;
+ pthread_join(mThreadId, NULL);
}
} // namespace implementation
diff --git a/tv/hdmi/cec/aidl/default/HdmiCecMock.h b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
index aca0581..e78b1cf 100644
--- a/tv/hdmi/cec/aidl/default/HdmiCecMock.h
+++ b/tv/hdmi/cec/aidl/default/HdmiCecMock.h
@@ -40,6 +40,7 @@
struct HdmiCecMock : public BnHdmiCec {
HdmiCecMock();
+ ~HdmiCecMock();
::ndk::ScopedAStatus addLogicalAddress(CecLogicalAddress addr, Result* _aidl_return) override;
::ndk::ScopedAStatus clearLogicalAddress() override;
::ndk::ScopedAStatus enableAudioReturnChannel(int32_t portId, bool enable) override;
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
index 8f4411b..954982e 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.cpp
@@ -15,12 +15,11 @@
*/
#define LOG_TAG "android.hardware.tv.hdmi.connection"
+#include "HdmiConnectionMock.h"
#include <android-base/logging.h>
#include <fcntl.h>
#include <utils/Log.h>
-#include "HdmiConnectionMock.h"
-
using ndk::ScopedAStatus;
namespace android {
@@ -34,6 +33,7 @@
ALOGE("HdmiConnectionMock died");
auto hdmi = static_cast<HdmiConnectionMock*>(cookie);
hdmi->mHdmiThreadRun = false;
+ pthread_join(hdmi->mThreadId, NULL);
}
ScopedAStatus HdmiConnectionMock::getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) {
@@ -55,12 +55,15 @@
ScopedAStatus HdmiConnectionMock::setCallback(
const std::shared_ptr<IHdmiConnectionCallback>& callback) {
if (mCallback != nullptr) {
+ stopThread();
mCallback = nullptr;
}
-
if (callback != nullptr) {
mCallback = callback;
- AIBinder_linkToDeath(this->asBinder().get(), mDeathRecipient.get(), 0 /* cookie */);
+ mDeathRecipient =
+ ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+
+ AIBinder_linkToDeath(callback->asBinder().get(), mDeathRecipient.get(), this /* cookie */);
mInputFile = open(HDMI_MSG_IN_FIFO, O_RDWR | O_CLOEXEC);
pthread_create(&mThreadId, NULL, __threadLoop, this);
@@ -153,7 +156,7 @@
int r = -1;
// Open the input pipe
- while (mInputFile < 0) {
+ while (mHdmiThreadRun && mInputFile < 0) {
usleep(1000 * 1000);
mInputFile = open(HDMI_MSG_IN_FIFO, O_RDONLY | O_CLOEXEC);
}
@@ -193,7 +196,21 @@
.physicalAddress = mPhysicalAddress};
mPortConnectionStatus[0] = false;
mHpdSignal[0] = HpdSignal::HDMI_HPD_PHYSICAL;
- mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(serviceDied));
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+}
+
+void HdmiConnectionMock::stopThread() {
+ if (mCallback != nullptr) {
+ ALOGE("[halimp_aidl] HdmiConnectionMock shutting down.");
+ mCallback = nullptr;
+ mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(nullptr);
+ mHdmiThreadRun = false;
+ pthread_join(mThreadId, NULL);
+ }
+}
+
+HdmiConnectionMock::~HdmiConnectionMock() {
+ stopThread();
}
} // namespace implementation
diff --git a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
index c013fdd..8c66f08 100644
--- a/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
+++ b/tv/hdmi/connection/aidl/default/HdmiConnectionMock.h
@@ -41,7 +41,7 @@
struct HdmiConnectionMock : public BnHdmiConnection {
HdmiConnectionMock();
-
+ ~HdmiConnectionMock();
::ndk::ScopedAStatus getPortInfo(std::vector<HdmiPortInfo>* _aidl_return) override;
::ndk::ScopedAStatus isConnected(int32_t portId, bool* _aidl_return) override;
::ndk::ScopedAStatus setCallback(
@@ -56,6 +56,7 @@
void threadLoop();
int readMessageFromFifo(unsigned char* buf, int msgCount);
void handleHotplugMessage(unsigned char* msgBuf);
+ void stopThread();
private:
static void serviceDied(void* cookie);
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index 2b8e481..efb2454 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -14,7 +14,6 @@
use std::fs::{File, OpenOptions};
use std::io::{self, Read, Write};
-use std::os::fd::AsRawFd;
use std::os::unix::fs::OpenOptionsExt;
enum State {
@@ -61,13 +60,11 @@
}
pub fn makeraw(file: File) -> io::Result<File> {
- let fd = file.as_raw_fd();
-
- // Configure the file descritpro as raw fd.
+ // Configure the file descriptor as raw fd.
use nix::sys::termios::*;
- let mut attrs = tcgetattr(fd)?;
+ let mut attrs = tcgetattr(&file)?;
cfmakeraw(&mut attrs);
- tcsetattr(fd, SetArg::TCSANOW, &attrs)?;
+ tcsetattr(&file, SetArg::TCSANOW, &attrs)?;
Ok(file)
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl
new file mode 100644
index 0000000..cd4a456
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanData.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi;
+@VintfStability
+parcelable CachedScanData {
+ int[] scannedFrequenciesMhz;
+ android.hardware.wifi.CachedScanResult[] cachedScanResults;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl
new file mode 100644
index 0000000..1806b0f
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CachedScanResult.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi;
+@VintfStability
+parcelable CachedScanResult {
+ long timeStampInUs;
+ byte[] ssid;
+ byte[6] bssid;
+ int rssiDbm;
+ int frequencyMhz;
+ android.hardware.wifi.WifiChannelWidthInMhz channelWidthMhz;
+ android.hardware.wifi.WifiRatePreamble preambleType;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
index 2d7fe03..5ed7517 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -84,6 +84,7 @@
void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
@PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApOrBridgedApIface(in android.hardware.wifi.IfaceConcurrencyType iface, in android.hardware.wifi.common.OuiKeyedData[] vendorData);
+ void setVoipMode(in android.hardware.wifi.IWifiChip.VoipMode mode);
const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
@Backing(type="int") @VintfStability
enum FeatureSetMask {
@@ -96,6 +97,7 @@
WIGIG = (1 << 6) /* 64 */,
SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
T2LM_NEGOTIATION = (1 << 8) /* 256 */,
+ SET_VOIP_MODE = (1 << 9) /* 512 */,
}
@VintfStability
parcelable ChipConcurrencyCombinationLimit {
@@ -162,6 +164,11 @@
NAN_INSTANT_MODE = (1 << 2) /* 4 */,
}
@Backing(type="int") @VintfStability
+ enum VoipMode {
+ OFF = 0,
+ VOICE = 1,
+ }
+ @Backing(type="int") @VintfStability
enum ChannelCategoryMask {
INDOOR_CHANNEL = (1 << 0) /* 1 */,
DFS_CHANNEL = (1 << 1) /* 2 */,
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
index 923deff..ccb7876 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIface.aidl
@@ -61,6 +61,14 @@
void stopRssiMonitoring(in int cmdId);
void stopSendingKeepAlivePackets(in int cmdId);
void setDtimMultiplier(in int multiplier);
+ android.hardware.wifi.CachedScanData getCachedScanData();
+ android.hardware.wifi.TwtCapabilities twtGetCapabilities();
+ void twtSessionSetup(in int cmdId, in android.hardware.wifi.TwtRequest twtRequest);
+ void twtSessionUpdate(in int cmdId, in int sessionId, in android.hardware.wifi.TwtRequest twtRequest);
+ void twtSessionSuspend(in int cmdId, in int sessionId);
+ void twtSessionResume(in int cmdId, in int sessionId);
+ void twtSessionTeardown(in int cmdId, in int sessionId);
+ void twtSessionGetStats(in int cmdId, in int sessionId);
@Backing(type="int") @VintfStability
enum FeatureSetMask {
APF = (1 << 0) /* 1 */,
@@ -77,5 +85,7 @@
TDLS_OFFCHANNEL = (1 << 11) /* 2048 */,
ND_OFFLOAD = (1 << 12) /* 4096 */,
KEEP_ALIVE = (1 << 13) /* 8192 */,
+ ROAMING_MODE_CONTROL = (1 << 14) /* 16384 */,
+ CACHED_SCAN_DATA = (1 << 15) /* 32768 */,
}
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
index 48b85b0..629ca3d 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -38,4 +38,31 @@
oneway void onBackgroundScanFailure(in int cmdId);
oneway void onBackgroundScanResults(in int cmdId, in android.hardware.wifi.StaScanData[] scanDatas);
oneway void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+ oneway void onTwtFailure(in int cmdId, in android.hardware.wifi.IWifiStaIfaceEventCallback.TwtErrorCode error);
+ oneway void onTwtSessionCreate(in int cmdId, in android.hardware.wifi.TwtSession twtSession);
+ oneway void onTwtSessionUpdate(in int cmdId, in android.hardware.wifi.TwtSession twtSession);
+ oneway void onTwtSessionTeardown(in int cmdId, in int twtSessionId, in android.hardware.wifi.IWifiStaIfaceEventCallback.TwtTeardownReasonCode reasonCode);
+ oneway void onTwtSessionStats(in int cmdId, in int twtSessionId, in android.hardware.wifi.TwtSessionStats twtSessionStats);
+ oneway void onTwtSessionSuspend(in int cmdId, in int twtSessionId);
+ oneway void onTwtSessionResume(in int cmdId, in int twtSessionId);
+ @Backing(type="byte") @VintfStability
+ enum TwtErrorCode {
+ FAILURE_UNKNOWN,
+ ALREADY_RESUMED,
+ ALREADY_SUSPENDED,
+ INVALID_PARAMS,
+ MAX_SESSION_REACHED,
+ NOT_AVAILABLE,
+ NOT_SUPPORTED,
+ PEER_NOT_SUPPORTED,
+ PEER_REJECTED,
+ TIMEOUT,
+ }
+ @Backing(type="byte") @VintfStability
+ enum TwtTeardownReasonCode {
+ UNKNOWN,
+ LOCALLY_REQUESTED,
+ INTERNALLY_INITIATED,
+ PEER_INITIATED,
+ }
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
index dd0a5ed..b5f78b0 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -38,4 +38,6 @@
byte[6] peerDiscMacAddr;
android.hardware.wifi.NanBootstrappingMethod requestBootstrappingMethod;
byte[] cookie;
+ boolean isComeback;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
index 6dd9b26..7b17493 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -36,4 +36,5 @@
parcelable NanBootstrappingResponse {
int bootstrappingInstanceId;
boolean acceptRequest;
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
index 5ead651..a3693d6 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanConfigRequest.aidl
@@ -45,4 +45,5 @@
char rssiWindowSize;
int macAddressRandomizationIntervalSec;
android.hardware.wifi.NanBandSpecificConfig[3] bandSpecificConfig;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
index 635dbce..48e9501 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -39,4 +39,10 @@
byte[32] pmk;
byte[] passphrase;
byte[16] scid;
+ boolean enable16ReplyCountersForTksa;
+ boolean enable16ReplyCountersForGtksa;
+ boolean supportGtkAndIgtk;
+ boolean supportBigtksa;
+ boolean enableNcsBip256;
+ boolean requiresEnhancedFrameProtection;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
index 317489f..4acc773 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanMatchInd.aidl
@@ -51,4 +51,5 @@
byte[] scid;
android.hardware.wifi.NanPairingConfig peerPairingConfig;
android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
index 8ecf22a..699ecdc 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -40,4 +40,5 @@
android.hardware.wifi.NanPairingRequestType requestType;
boolean enablePairingCache;
android.hardware.wifi.NpkSecurityAssociation npksa;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
index 2a644ae..121b038 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequest.aidl
@@ -40,4 +40,5 @@
boolean enablePairingCache;
byte[16] pairingIdentityKey;
android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
index 66762b9..57072c0 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -41,4 +41,5 @@
android.hardware.wifi.NanPairingRequestType requestType;
boolean enablePairingCache;
android.hardware.wifi.NanIdentityResolutionAttribute peerNira;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
index c49f5f9..bdc8357 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
@@ -40,4 +40,5 @@
boolean autoAcceptDataPathRequests;
android.hardware.wifi.NanPairingConfig pairingConfig;
byte[16] identityKey;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
index a58890c..da81c39 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -40,4 +40,5 @@
boolean enablePairingCache;
byte[16] pairingIdentityKey;
android.hardware.wifi.NanPairingSecurityConfig securityConfig;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
index 96be096..bf525a9 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -43,4 +43,5 @@
android.hardware.wifi.MacAddress[] intfAddr;
android.hardware.wifi.NanPairingConfig pairingConfig;
byte[16] identityKey;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
index cf64687..56ef2d2 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
@@ -42,4 +42,9 @@
android.hardware.wifi.RttPreamble preambleSupport;
android.hardware.wifi.RttBw bwSupport;
byte mcVersion;
+ android.hardware.wifi.RttPreamble azPreambleSupport;
+ android.hardware.wifi.RttBw azBwSupport;
+ boolean ntbInitiatorSupported;
+ boolean ntbResponderSupported;
+ int maxTxLtfRepetitionCount;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
index ccdf2ce..b7830bd 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
@@ -48,4 +48,7 @@
int burstDuration;
android.hardware.wifi.RttPreamble preamble;
android.hardware.wifi.RttBw bw;
+ int ntbMinMeasurementTimeMillis;
+ int ntbMaxMeasurementTimeMillis;
+ int txLtfRepetitionCount;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
index de26f28..2802464 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttPreamble.aidl
@@ -34,6 +34,7 @@
package android.hardware.wifi;
@Backing(type="int") @VintfStability
enum RttPreamble {
+ INVALID = 0,
LEGACY = 0x1,
HT = 0x2,
VHT = 0x4,
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
index 8375dcb..30f5f58 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
@@ -59,4 +59,7 @@
android.hardware.wifi.WifiInformationElement lcr;
int channelFreqMHz;
android.hardware.wifi.RttBw packetBw;
+ int txLtfRepetitionCount;
+ int ntbMinMeasurementTimeMillis;
+ int ntbMaxMeasurementTimeMillis;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
index 2b6087a..cb25673 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
@@ -36,4 +36,6 @@
enum RttType {
ONE_SIDED = 1,
TWO_SIDED = 2,
+ TWO_SIDED_11MC = TWO_SIDED /* 2 */,
+ TWO_SIDED_11AZ_NTB = 3,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
index 1f3d91f..fd7d567 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaRoamingState.aidl
@@ -36,4 +36,5 @@
enum StaRoamingState {
DISABLED = 0,
ENABLED = 1,
+ AGGRESSIVE = 2,
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
new file mode 100644
index 0000000..d8e73fb
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi;
+@VintfStability
+parcelable TwtCapabilities {
+ boolean isTwtRequesterSupported;
+ boolean isTwtResponderSupported;
+ boolean isBroadcastTwtSupported;
+ boolean isFlexibleTwtScheduleSupported;
+ int minWakeDurationMicros;
+ int maxWakeDurationMicros;
+ int minWakeIntervalMicros;
+ int maxWakeIntervalMicros;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
new file mode 100644
index 0000000..3051b94
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi;
+@VintfStability
+parcelable TwtRequest {
+ int mloLinkId;
+ int minWakeDurationMicros;
+ int maxWakeDurationMicros;
+ int minWakeIntervalMicros;
+ int maxWakeIntervalMicros;
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
new file mode 100644
index 0000000..92c2533
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi;
+@VintfStability
+parcelable TwtSession {
+ int sessionId;
+ int mloLinkId;
+ int wakeDurationMicros;
+ int wakeIntervalMicros;
+ android.hardware.wifi.TwtSession.TwtNegotiationType negotiationType;
+ boolean isTriggerEnabled;
+ boolean isAnnounced;
+ boolean isImplicit;
+ boolean isProtected;
+ boolean isUpdatable;
+ boolean isSuspendable;
+ boolean isResponderPmModeEnabled;
+ @Backing(type="byte") @VintfStability
+ enum TwtNegotiationType {
+ INDIVIDUAL = 0,
+ BROADCAST = 1,
+ }
+}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
new file mode 100644
index 0000000..528444a
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi;
+@VintfStability
+parcelable TwtSessionStats {
+ int avgTxPktCount;
+ int avgRxPktCount;
+ int avgTxPktSize;
+ int avgRxPktSize;
+ int avgEospDurationMicros;
+ int eospCount;
+}
diff --git a/wifi/aidl/android/hardware/wifi/CachedScanData.aidl b/wifi/aidl/android/hardware/wifi/CachedScanData.aidl
new file mode 100644
index 0000000..feda079
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CachedScanData.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.CachedScanResult;
+
+/**
+ * Scan data cached in Wifi firmware
+ */
+@VintfStability
+parcelable CachedScanData {
+ /**
+ * List of scanned frequencies in MHz.
+ */
+ int[] scannedFrequenciesMhz;
+
+ /**
+ * List of scan results.
+ */
+ CachedScanResult[] cachedScanResults;
+}
diff --git a/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl b/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl
new file mode 100644
index 0000000..9c9dbc7
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CachedScanResult.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.WifiChannelWidthInMhz;
+import android.hardware.wifi.WifiRatePreamble;
+
+/**
+ * Scan result cached in Wifi firmware
+ */
+@VintfStability
+parcelable CachedScanResult {
+ /**
+ * Time in micro seconds since boot when the scan was done
+ */
+ long timeStampInUs;
+ /**
+ * SSID of beacon excluding null.
+ */
+ byte[] ssid;
+ /**
+ * BSSID of beacon
+ */
+ byte[6] bssid;
+ /**
+ * Beacon received signal stength indicatior (RSSI), in dbm
+ */
+ int rssiDbm;
+ /**
+ * Frequency of beacon, in MHz
+ */
+ int frequencyMhz;
+ /**
+ * Channel bandwidth of found network
+ */
+ WifiChannelWidthInMhz channelWidthMhz;
+ /**
+ * Supported rate and preamble type
+ */
+ WifiRatePreamble preambleType;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index 733ff62..d12d26c 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -83,6 +83,10 @@
* Chip supports Tid-To-Link mapping negotiation.
*/
T2LM_NEGOTIATION = 1 << 8,
+ /**
+ * Chip supports voip mode setting.
+ */
+ SET_VOIP_MODE = 1 << 9,
}
/**
@@ -385,6 +389,16 @@
}
/**
+ * This enum represents the different VoIP mode that can be set through |setVoipMode|.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum VoipMode {
+ OFF = 0,
+ VOICE = 1,
+ }
+
+ /**
* Configure the Chip.
* This may NOT be called to reconfigure a chip due to an internal
* limitation. Calling this when chip is already configured in a different
@@ -1173,4 +1187,23 @@
@PropagateAllowBlocking
IWifiApIface createApOrBridgedApIface(
in IfaceConcurrencyType iface, in OuiKeyedData[] vendorData);
+
+ /**
+ * API to set the wifi VoIP mode.
+ *
+ * The VoIP mode is a hint to the HAL to enable or disable Wi-Fi VoIP
+ * optimization. The optimization should be enabled if the mode is NOT set to |OFF|.
+ * Furthermore, HAL should implement relevant optimization techniques based on the
+ * current operational mode.
+ *
+ * Note: Wi-Fi VoIP optimization may trade-off power against Wi-Fi
+ * performance but it provides better voice quility.
+ *
+ * @param mode Voip mode as defined by the enum |VoipMode|
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+ * |WifiStatusCode.ERROR_INVALID_ARGS|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void setVoipMode(in VoipMode mode);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
index 6d6afaf..6c5451b 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIface.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi;
+import android.hardware.wifi.CachedScanData;
import android.hardware.wifi.IWifiStaIfaceEventCallback;
import android.hardware.wifi.StaApfPacketFilterCapabilities;
import android.hardware.wifi.StaBackgroundScanCapabilities;
@@ -24,6 +25,8 @@
import android.hardware.wifi.StaRoamingCapabilities;
import android.hardware.wifi.StaRoamingConfig;
import android.hardware.wifi.StaRoamingState;
+import android.hardware.wifi.TwtCapabilities;
+import android.hardware.wifi.TwtRequest;
import android.hardware.wifi.WifiBand;
import android.hardware.wifi.WifiDebugRxPacketFateReport;
import android.hardware.wifi.WifiDebugTxPacketFateReport;
@@ -99,6 +102,14 @@
* Support for keep alive packet offload.
*/
KEEP_ALIVE = 1 << 13,
+ /**
+ * Support for configuring roaming mode.
+ */
+ ROAMING_MODE_CONTROL = 1 << 14,
+ /**
+ * Support for cached scan data report.
+ */
+ CACHED_SCAN_DATA = 1 << 15,
}
/**
@@ -552,4 +563,125 @@
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void setDtimMultiplier(in int multiplier);
+
+ /**
+ * Get the cached scan data.
+ *
+ * @return Instance of |CachedScanData|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ CachedScanData getCachedScanData();
+
+ /**
+ * Get Target Wake Time (TWT) local device capabilities for the station interface.
+ *
+ * @return Instance of |TwtCapabilities|.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ TwtCapabilities twtGetCapabilities();
+
+ /**
+ * Setup a Target Wake Time (TWT) session.
+ *
+ * Supported only if |TwtCapabilities.isTwtRequesterSupported| is set. Results in asynchronous
+ * callback |IWifiStaIfaceEventCallback.onTwtSessionCreate| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param twtRequest TWT Request parameters.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionSetup(in int cmdId, in TwtRequest twtRequest);
+
+ /**
+ * Update a Target Wake Time (TWT) session.
+ *
+ * Supported only if the TWT session can be updated. See |TwtSession.isUpdatable|. Results in
+ * asynchronous callback |IWifiStaIfaceEventCallback.onTwtSessionUpdate| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @param twtRequest TWT Request parameters.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionUpdate(in int cmdId, in int sessionId, in TwtRequest twtRequest);
+
+ /**
+ * Suspend a Target Wake Time (TWT) session until a resume is called.
+ *
+ * Supported only if the TWT session supports suspend and resume. See
+ * |TwtSession.isSuspendable|. Results in asynchronous callback
+ * |IWifiStaIfaceEventCallback.onTwtSessionSuspend| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionSuspend(in int cmdId, in int sessionId);
+
+ /**
+ * Resume a Target Wake Time (TWT) session which is suspended.
+ *
+ * Supported only if the TWT session supports suspend and resume. See
+ * |TwtSession.isSuspendable|. Results in asynchronous callback
+ * |IWifiStaIfaceEventCallback.onTwtSessionResume| on success or
+ * |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionResume(in int cmdId, in int sessionId);
+
+ /**
+ * Teardown a Target Wake Time (TWT) session.
+ *
+ * Results in asynchronous callback |IWifiStaIfaceEventCallback.onTwtSessionTeardown| on
+ * success or |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionTeardown(in int cmdId, in int sessionId);
+
+ /**
+ * Get stats for a Target Wake Time (TWT) session.
+ *
+ * Results in asynchronous callback |IWifiStaIfaceEventCallback.onTwtSessionStats| on success
+ * or |IWifiStaIfaceEventCallback.onTwtFailure| on failure.
+ *
+ * @param cmdId Command Id to use for this invocation. The value 0 is reserved.
+ * @param sessionId TWT session id.
+ * @throws ServiceSpecificException with one of the following values:
+ * |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
+ * |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+ * |WifiStatusCode.ERROR_UNKNOWN|
+ */
+ void twtSessionGetStats(in int cmdId, in int sessionId);
}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
index 93a255f..dda7c77 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiStaIfaceEventCallback.aidl
@@ -18,6 +18,8 @@
import android.hardware.wifi.StaScanData;
import android.hardware.wifi.StaScanResult;
+import android.hardware.wifi.TwtSession;
+import android.hardware.wifi.TwtSessionStats;
@VintfStability
oneway interface IWifiStaIfaceEventCallback {
@@ -61,4 +63,104 @@
* @param currRssi RSSI of the currently connected access point.
*/
void onRssiThresholdBreached(in int cmdId, in byte[6] currBssid, in int currRssi);
+
+ @VintfStability
+ @Backing(type="byte")
+ enum TwtErrorCode {
+ /** Unknown failure */
+ FAILURE_UNKNOWN,
+ /** TWT session is already resumed */
+ ALREADY_RESUMED,
+ /** TWT session is already suspended */
+ ALREADY_SUSPENDED,
+ /** Invalid parameters */
+ INVALID_PARAMS,
+ /** Maximum number of sessions reached */
+ MAX_SESSION_REACHED,
+ /** Requested operation is not available */
+ NOT_AVAILABLE,
+ /** Requested operation is not supported */
+ NOT_SUPPORTED,
+ /** Requested operation is not supported by the peer */
+ PEER_NOT_SUPPORTED,
+ /** Requested operation is rejected by the peer */
+ PEER_REJECTED,
+ /** Requested operation is timed out */
+ TIMEOUT,
+ }
+
+ @VintfStability
+ @Backing(type="byte")
+ enum TwtTeardownReasonCode {
+ /** Unknown reason */
+ UNKNOWN,
+ /** Teardown requested by the framework */
+ LOCALLY_REQUESTED,
+ /** Teardown initiated internally by the firmware or driver */
+ INTERNALLY_INITIATED,
+ /** Teardown initiated by the peer */
+ PEER_INITIATED,
+ }
+
+ /**
+ * Called to indicate a TWT failure. If there is no command associated with this failure cmdId
+ * will be 0.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param error error code.
+ */
+ void onTwtFailure(in int cmdId, in TwtErrorCode error);
+
+ /**
+ * Called when a Target Wake Time session is created. See |IWifiStaIface.twtSessionSetup|.
+ *
+ * @param cmdId Id used to identify the command.
+ * @param twtSession TWT session.
+ */
+ void onTwtSessionCreate(in int cmdId, in TwtSession twtSession);
+
+ /**
+ * Called when a Target Wake Time session is updated. See |IWifiStaIface.twtSessionUpdate|.
+ *
+ * @param cmdId Id used to identify the command.
+ * @param twtSession TWT session.
+ */
+ void onTwtSessionUpdate(in int cmdId, in TwtSession twtSession);
+
+ /**
+ * Called when the Target Wake Time session is torndown.
+ * See |IWifiStaIface.twtSessionTeardown|.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param twtSessionId TWT session id.
+ * @param reasonCode reason code for the TWT teardown.
+ */
+ void onTwtSessionTeardown(
+ in int cmdId, in int twtSessionId, in TwtTeardownReasonCode reasonCode);
+
+ /**
+ * Called when TWT session stats available. See |IWifiStaIface.twtSessionGetStats|.
+ *
+ * @param cmdId Id used to identify the command.
+ * @param twtSessionId TWT session id.
+ * @param twtSessionStats TWT session stats.
+ */
+ void onTwtSessionStats(in int cmdId, in int twtSessionId, in TwtSessionStats twtSessionStats);
+
+ /**
+ * Called when the Target Wake Time session is suspended.
+ * See |IWifiStaIface.twtSessionSuspend|.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param twtSessionId TWT session id.
+ */
+ void onTwtSessionSuspend(in int cmdId, in int twtSessionId);
+
+ /**
+ * Called when the Target Wake Time session is resumed. See |IWifiStaIface.twtSessionResume|.
+ *
+ * @param cmdId Id used to identify the command. The value 0 indicates no associated command.
+ * @param twtSessionId TWT session id.
+ */
+ void onTwtSessionResume(in int cmdId, in int twtSessionId);
}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
index 4b74cd9..e23bd23 100644
--- a/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingRequest.aidl
@@ -45,4 +45,16 @@
* Cookie received from previous |NanBootstrappingConfirmInd| for comeback request.
*/
byte[] cookie;
+
+ /**
+ * Identify if it is a request for come back response
+ */
+ boolean isComeback;
+
+ /**
+ * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+ * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+ * ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
index dbe8923..a2ee0e6 100644
--- a/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanBootstrappingResponse.aidl
@@ -29,4 +29,11 @@
* True if accept the request, false otherwise.
*/
boolean acceptRequest;
+
+ /**
+ * ID of an active publish or subscribe discovery session. Follow-up message is transmitted in
+ * the context of the discovery session. NAN Spec: Service Descriptor Attribute (SDA) / Instance
+ * ID
+ */
+ byte discoverySessionId;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
index 82a7b6e..47561dc 100644
--- a/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanConfigRequest.aidl
@@ -17,6 +17,7 @@
package android.hardware.wifi;
import android.hardware.wifi.NanBandSpecificConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Configuration parameters of NAN. Used when enabling and re-configuring a NAN cluster.
@@ -79,4 +80,9 @@
* Additional configuration provided per band. Indexed by |NanBandIndex|.
*/
NanBandSpecificConfig[3] bandSpecificConfig;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
index 9a2013b..b6c5eef 100644
--- a/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanDataPathSecurityConfig.aidl
@@ -58,4 +58,49 @@
* setting up the Secure Data Path.
*/
byte[16] scid;
+
+ /**
+ * Enables the 16 replay counter for ND-TKSA(NAN Data Pairwise Security Association) and
+ * NM-TKSA(NAN managerment Pairwise Security Association), if set to false will use 4 replay
+ * counter as default
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean enable16ReplyCountersForTksa;
+
+ /**
+ * Enables the 16 replay counter for GTKSA(Group Transient Key security associations), if set to
+ * false will use 4 replay counter as default.
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean enable16ReplyCountersForGtksa;
+
+ /**
+ * GTK(Group Transient Key) used to protect group addressed data frames,
+ * IGTK(Integrity Group Transient Key) used to protect multicast management frames, set to true
+ * if supported.
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean supportGtkAndIgtk;
+
+ /**
+ * BIGTK(Beacon Integrity Group Transient Key) used to protect Beacon frames, set to true if
+ * supported.
+ * Ref: Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean supportBigtksa;
+
+ /**
+ * Enables NCS-BIP-256 for IGTKSA(Integrity Group Transient Key security associations)
+ * and BIGTK(Beacon Integrity Group Transient Key security associations), if set to false will
+ * use NCS-BIP-128 as default
+ * Wi-Fi Aware spec 4.0: 9.5.21.2 Cipher Suite Information attribute
+ */
+ boolean enableNcsBip256;
+
+ /**
+ * Require enhanced frame protection if supported, which includes multicast management frame
+ * protection, group addressed data protection and beacon frame protection.
+ * Wi-Fi Aware spec 4.0: 7.3 frame protection
+ */
+ boolean requiresEnhancedFrameProtection;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
index 5a04376..622213c 100644
--- a/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanMatchInd.aidl
@@ -19,6 +19,7 @@
import android.hardware.wifi.NanCipherSuiteType;
import android.hardware.wifi.NanIdentityResolutionAttribute;
import android.hardware.wifi.NanPairingConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Match indication structure.
@@ -137,4 +138,9 @@
* The NIRA from peer for NAN pairing verification
*/
NanIdentityResolutionAttribute peerNira;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
index a5670ec..692d3d6 100644
--- a/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPairingConfirmInd.aidl
@@ -19,6 +19,7 @@
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanStatus;
import android.hardware.wifi.NpkSecurityAssociation;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* NAN pairing confirmation indication structure. Event indication is
@@ -51,4 +52,9 @@
* The security association negotiated for the pairing, can be cached for future verification
*/
NpkSecurityAssociation npksa;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
index 0c2080b..950d1e2 100644
--- a/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequest.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanPairingSecurityConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* NAN pairing initiate request.
@@ -54,4 +55,9 @@
* Security config used for the pairing
*/
NanPairingSecurityConfig securityConfig;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
index ec8548f..7e98bac 100644
--- a/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPairingRequestInd.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.NanIdentityResolutionAttribute;
import android.hardware.wifi.NanPairingRequestType;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* NAN pairing request indication message structure.
@@ -58,4 +59,9 @@
* The NIRA from peer for NAN pairing verification
*/
NanIdentityResolutionAttribute peerNira;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
index 956a7df..ae75caf 100644
--- a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
@@ -20,6 +20,7 @@
import android.hardware.wifi.NanPairingConfig;
import android.hardware.wifi.NanPublishType;
import android.hardware.wifi.NanTxType;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Publish request. Specifies a publish discovery operation.
@@ -55,4 +56,9 @@
* The Identity key for pairing, will generate NIRA for verification by the peer
*/
byte[16] identityKey;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
index fab2a40..0527f06 100644
--- a/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanRespondToPairingIndicationRequest.aidl
@@ -18,6 +18,7 @@
import android.hardware.wifi.NanPairingRequestType;
import android.hardware.wifi.NanPairingSecurityConfig;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Response to a pairing request from a peer.
@@ -51,4 +52,9 @@
* Security config used for the pairing
*/
NanPairingSecurityConfig securityConfig;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
index 0b246ed..e7094bf 100644
--- a/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanSubscribeRequest.aidl
@@ -21,6 +21,7 @@
import android.hardware.wifi.NanPairingConfig;
import android.hardware.wifi.NanSrfType;
import android.hardware.wifi.NanSubscribeType;
+import android.hardware.wifi.common.OuiKeyedData;
/**
* Subscribe request. Specifies a subscribe discovery operation.
@@ -76,4 +77,9 @@
* The Identity key for pairing, will generate NIRA for verification by the peer
*/
byte[16] identityKey;
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
index 7c47ed5..0352ec8 100644
--- a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -33,24 +33,25 @@
*/
boolean rttFtmSupported;
/**
- * Whether initiator supports LCI request. Applies to 2-sided RTT.
+ * Whether initiator supports Location Configuration Information (LCI) request. Applies to
+ * 2-sided RTT.
*/
boolean lciSupported;
/**
- * Whether initiator supports LCR request. Applies to 2-sided RTT.
+ * Whether initiator supports Location Civic Report (LCR) request. Applies to 2-sided RTT.
*/
boolean lcrSupported;
/**
- * Whether 11mc responder mode is supported.
+ * Whether IEEE 802.11mc responder mode is supported.
*/
boolean responderSupported;
/**
- * Bit mask indicating what preamble is supported by initiator.
+ * Bit mask indicating what preamble is supported by IEEE 802.11mc initiator.
* Combination of |RttPreamble| values.
*/
RttPreamble preambleSupport;
/**
- * Bit mask indicating what BW is supported by initiator.
+ * Bit mask indicating what BW is supported by IEEE 802.11mc initiator.
* Combination of |RttBw| values.
*/
RttBw bwSupport;
@@ -59,4 +60,27 @@
* For instance, version 4.0 must be 40 and version 4.3 must be 43 etc.
*/
byte mcVersion;
+ /**
+ * Bit mask indicating what preamble is supported by IEEE 802.11az initiator.
+ * Combination of |RttPreamble| values.
+ */
+ RttPreamble azPreambleSupport;
+ /**
+ * Bit mask indicating what BW is supported by IEEE 802.11az initiator.
+ * Combination of |RttBw| values.
+ */
+ RttBw azBwSupport;
+ /**
+ * Whether the initiator supports IEEE 802.11az Non-Trigger-based (non-TB) measurement.
+ */
+ boolean ntbInitiatorSupported;
+ /**
+ * Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported.
+ */
+ boolean ntbResponderSupported;
+ /**
+ * Maximum HE LTF repetitions the IEEE 802.11az initiator is capable of transmitting in the
+ * preamble of I2R NDP.
+ */
+ int maxTxLtfRepetitionCount;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
index fc2c2e0..e970656 100644
--- a/wifi/aidl/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -32,7 +32,7 @@
*/
byte[6] addr;
/**
- * 1-sided or 2-sided RTT.
+ * 1-sided or 2-sided RTT (IEEE 802.11mc or IEEE 802. 11az).
*/
RttType type;
/**
@@ -47,6 +47,8 @@
* Time interval between bursts (units: 100 ms).
* Applies to 1-sided and 2-sided RTT multi-burst requests.
* Range: 0-31, 0: no preference by initiator (2-sided RTT).
+ *
+ * Note: Applicable to IEEE 802.11mc only.
*/
int burstPeriod;
/**
@@ -60,6 +62,9 @@
* number of RTT results is the following:
* for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
* for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
+ *
+ * Note: Applicable to IEEE 802.11mc only. For IEEE 802.11az refer
+ * |RttConfig.txLtfRepetitionCount|.
*/
int numBurst;
/**
@@ -70,6 +75,8 @@
* equals the number of FTM frames that the
* initiator will request that the responder sends
* in a single frame.
+ *
+ * Note: Applicable to IEEE 802.11mc only.
*/
int numFramesPerBurst;
/**
@@ -95,8 +102,8 @@
*/
boolean mustRequestLcr;
/**
- * Applies to 1-sided and 2-sided RTT. Valid values will
- * be 2-11 and 15 as specified by the 802.11mc std for
+ * Applies to 1-sided and 2-sided IEEE 802.11mc RTT. Valid values will
+ * be 2-11 and 15 as specified by the IEEE 802.11mc std for
* the FTM parameter burst duration. In a multi-burst
* request, if responder overrides with larger value,
* the initiator will return failure. In a single-burst
@@ -113,4 +120,17 @@
* RTT BW to be used in the RTT frames.
*/
RttBw bw;
+ /**
+ * IEEE 802.11az Non-Trigger-based (non-TB) minimum measurement time in milliseconds.
+ */
+ int ntbMinMeasurementTimeMillis;
+ /**
+ * IEEE 802.11az Non-Trigger-based (non-TB) maximum measurement time in milliseconds.
+ */
+ int ntbMaxMeasurementTimeMillis;
+ /**
+ * Multiple transmissions of HE-LTF symbols in an HE Ranging NDP. A value of 1 indicates no
+ * repetition.
+ */
+ int txLtfRepetitionCount;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttPreamble.aidl b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
index e460a94..21df171 100644
--- a/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttPreamble.aidl
@@ -22,6 +22,7 @@
@VintfStability
@Backing(type="int")
enum RttPreamble {
+ INVALID = 0,
LEGACY = 0x1,
HT = 0x2,
VHT = 0x4,
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index 6c45e2c..2cb0afa 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -33,6 +33,8 @@
byte[6] addr;
/**
* Burst number in a multi-burst request.
+ *
+ * Note: Applicable to 1-sided RTT and 2-sided IEEE 802.11mc only.
*/
int burstNum;
/**
@@ -45,7 +47,7 @@
int successNumber;
/**
* Maximum number of "FTM frames per burst" supported by
- * the responder STA. Applies to 2-sided RTT only.
+ * the responder STA. Applies to 2-sided IEEE 802.11mc RTT only.
* If reponder overrides with larger value:
* - for single-burst request, initiator will truncate the
* larger value and send a TMR_STOP after receiving as
@@ -59,10 +61,8 @@
*/
RttStatus status;
/**
- * If status is RTT_STATUS_FAIL_BUSY_TRY_LATER,
- * this will be the time provided by the responder as to
- * when the request can be tried again. Applies to 2-sided
- * RTT only. In sec, 1-31 sec.
+ * If status is RTT_STATUS_FAIL_BUSY_TRY_LATER, this will be the time provided by the responder
+ * as to when the request can be tried again. Applies to 2-sided RTT only. In sec, 1-31 sec.
*/
byte retryAfterDuration;
/**
@@ -104,11 +104,13 @@
*/
int distanceInMm;
/**
- * Standard deviation in mm (optional).
+ * Standard deviation in mm.
*/
int distanceSdInMm;
/**
* Difference between max and min distance recorded in mm (optional).
+ *
+ * Note: Only applicable for IEEE 802.11mc
*/
int distanceSpreadInMm;
/**
@@ -116,21 +118,20 @@
*/
long timeStampInUs;
/**
- * Actual time taken by the FW to finish one burst
- * measurement (in ms). Applies to 1-sided and 2-sided RTT.
+ * Actual time taken by the FW to finish one burst measurement (in ms). Applies to 1-sided
+ * and 2-sided IEEE 802.11mc RTT.
*/
int burstDurationInMs;
/**
- * Number of bursts allowed by the responder. Applies
- * to 2-sided RTT only.
+ * Number of bursts allowed by the responder. Applies to 2-sided IEEE 802.11mc RTT only.
*/
int negotiatedBurstNum;
/**
- * For 11mc only.
+ * For IEEE 802.11mc and IEEE 802.11az only.
*/
WifiInformationElement lci;
/**
- * For 11mc only.
+ * For IEEE 802.11mc and IEEE 802.11az only.
*/
WifiInformationElement lcr;
/**
@@ -140,8 +141,38 @@
int channelFreqMHz;
/**
* RTT packet bandwidth.
- * This value is an average bandwidth of the bandwidths of measurement
- * frames. Cap the average close to a specific valid RttBw.
+ * This value is an average bandwidth of the bandwidths of measurement frames. Cap the average
+ * close to a specific valid RttBw.
*/
RttBw packetBw;
+ /**
+ * IEEE 802.11az Transmit LTF repetitions used to get this result.
+ */
+ int txLtfRepetitionCount;
+ /**
+ * Minimum non-trigger based (non-TB) dynamic measurement time in milliseconds assigned by the
+ * IEEE 802.11az responder.
+ *
+ * After initial non-TB negotiation, if the next ranging request for this peer comes in between
+ * [ntbMinMeasurementTime, ntbMaxMeasurementTime], vendor software shall do the NDPA sounding
+ * sequence for dynamic non-TB measurement.
+ *
+ * If the ranging request for this peer comes sooner than minimum measurement time, vendor
+ * software shall return the cached result of the last measurement including the time stamp
+ * |RttResult.timestamp|.
+ */
+ int ntbMinMeasurementTimeMillis;
+ /**
+ * Maximum non-trigger based (non-TB) dynamic measurement time in milliseconds assigned by the
+ * IEEE 802.11az responder.
+ *
+ * After initial non-TB negotiation, if the next ranging request for this peer comes in between
+ * [ntbMinMeasurementTime, ntbMaxMeasurementTime], vendor software shall do the NDPA sounding
+ * sequence for dynamic non-TB measurement.
+ *
+ * If the ranging request for this peer comes later than the maximum measurement time, vendor
+ * software shall clean up any existing IEEE 802.11ax non-TB ranging session and re-do the
+ * non-TB ranging negotiation.
+ */
+ int ntbMaxMeasurementTimeMillis;
}
diff --git a/wifi/aidl/android/hardware/wifi/RttType.aidl b/wifi/aidl/android/hardware/wifi/RttType.aidl
index e95a928..3f1a2f1 100644
--- a/wifi/aidl/android/hardware/wifi/RttType.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttType.aidl
@@ -23,5 +23,18 @@
@Backing(type="int")
enum RttType {
ONE_SIDED = 1,
+ /**
+ * Two-sided RTT 11mc type.
+ *
+ * Note: TWO_SIDED was used for IEEE 802.11mc. Use TWO_SIDED_11MC for IEEE 802.11mc instead.
+ */
TWO_SIDED = 2,
+ /**
+ * Two-sided RTT 11mc type is same as two-sided.
+ */
+ TWO_SIDED_11MC = TWO_SIDED,
+ /**
+ * Two-sided RTT 11az non trigger based (non-TB) type.
+ */
+ TWO_SIDED_11AZ_NTB = 3,
}
diff --git a/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
index d75d323..6872a17 100644
--- a/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
+++ b/wifi/aidl/android/hardware/wifi/StaRoamingState.aidl
@@ -32,4 +32,9 @@
* the |StaRoamingConfig| parameters set using |configureRoaming|.
*/
ENABLED = 1,
+ /**
+ * Driver/Firmware is allowed to roam more aggressively. For instance,
+ * roaming can be triggered at higher RSSI thresholds than normal.
+ */
+ AGGRESSIVE = 2,
}
diff --git a/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
new file mode 100644
index 0000000..9007d0e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Capabilities supported.
+ */
+@VintfStability
+parcelable TwtCapabilities {
+ /**
+ * Whether the TWT requester mode supported.
+ */
+ boolean isTwtRequesterSupported;
+ /**
+ * Whether the TWT responder mode supported.
+ */
+ boolean isTwtResponderSupported;
+ /**
+ * Whether the Broadcast TWT mode (TWT scheduling STA) supported.
+ */
+ boolean isBroadcastTwtSupported;
+ /**
+ * Whether supports Flexible TWT schedules.
+ */
+ boolean isFlexibleTwtScheduleSupported;
+ /**
+ * Minimum TWT wake duration in microseconds.
+ */
+ int minWakeDurationMicros;
+ /**
+ * Maximum TWT wake duration in microseconds.
+ */
+ int maxWakeDurationMicros;
+ /**
+ * Minimum TWT wake interval in microseconds.
+ */
+ int minWakeIntervalMicros;
+ /**
+ * Maximum TWT wake interval in microseconds.
+ */
+ int maxWakeIntervalMicros;
+}
diff --git a/wifi/aidl/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
new file mode 100644
index 0000000..5191713
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Request
+ */
+@VintfStability
+parcelable TwtRequest {
+ /**
+ * MLO Link id in case TWT is requesting for MLO connection. Otherwise -1.
+ */
+ int mloLinkId;
+ /**
+ * Minimum TWT wake duration in microseconds.
+ */
+ int minWakeDurationMicros;
+ /**
+ * Maximum TWT wake duration in microseconds.
+ */
+ int maxWakeDurationMicros;
+ /**
+ * Minimum TWT wake interval in microseconds.
+ */
+ int minWakeIntervalMicros;
+ /**
+ * Maximum TWT wake interval in microseconds.
+ */
+ int maxWakeIntervalMicros;
+}
diff --git a/wifi/aidl/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
new file mode 100644
index 0000000..5a7ddb1
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Session
+ */
+@VintfStability
+parcelable TwtSession {
+ @VintfStability
+ @Backing(type="byte")
+ enum TwtNegotiationType {
+ INDIVIDUAL = 0,
+ BROADCAST = 1,
+ }
+
+ /**
+ * An unique identifier for the session.
+ */
+ int sessionId;
+
+ /**
+ * MLO Link id in case of MLO connection. Otherwise -1.
+ */
+ int mloLinkId;
+
+ /**
+ * TWT service period in microseconds.
+ */
+ int wakeDurationMicros;
+
+ /**
+ * Time interval in microseconds between two successive TWT service periods.
+ */
+ int wakeIntervalMicros;
+
+ /**
+ * TWT negotiation type.
+ */
+ TwtNegotiationType negotiationType;
+
+ /**
+ * Whether the TWT session is trigger enabled or non-trigger enabled.
+ */
+ boolean isTriggerEnabled;
+
+ /**
+ * Whether the TWT session is announced or unannounced.
+ */
+ boolean isAnnounced;
+
+ /**
+ * Whether the TWT session is implicit or explicit.
+ */
+ boolean isImplicit;
+
+ /**
+ * Whether the TWT session is protected or not.
+ */
+ boolean isProtected;
+
+ /**
+ * Whether the TWT session can be updated.
+ */
+ boolean isUpdatable;
+
+ /**
+ * Whether the TWT session can be suspended and then resumed.
+ */
+ boolean isSuspendable;
+
+ /**
+ * Whether AP (TWT responder) intends to go to doze state outside of TWT Service Periods.
+ *
+ * Refer IEEE 802.11 spec, Section 10.47.7 (TWT Sleep Setup).
+ */
+ boolean isResponderPmModeEnabled;
+}
diff --git a/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl b/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
new file mode 100644
index 0000000..e2e2d12
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Target Wake Time (TWT) Session Stats
+ */
+@VintfStability
+parcelable TwtSessionStats {
+ /**
+ * Average number of Tx packets in each wake duration.
+ */
+ int avgTxPktCount;
+
+ /**
+ * Average number of Rx packets in each wake duration.
+ */
+ int avgRxPktCount;
+
+ /**
+ * Average bytes per Tx packets in each wake duration.
+ */
+ int avgTxPktSize;
+
+ /**
+ * Average bytes per Rx packets in each wake duration.
+ */
+ int avgRxPktSize;
+
+ /**
+ * Average End of Service period in microseconds.
+ */
+ int avgEospDurationMicros;
+
+ /**
+ * Count of early terminations.
+ */
+ int eospCount;
+}
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 83e1193..b62b3a0 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -59,6 +59,8 @@
return IWifiChip::FeatureSetMask::P2P_RAND_MAC;
case WIFI_FEATURE_AFC_CHANNEL:
return IWifiChip::FeatureSetMask::SET_AFC_CHANNEL_ALLOWANCE;
+ case WIFI_FEATURE_SET_VOIP_MODE:
+ return IWifiChip::FeatureSetMask::SET_VOIP_MODE;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -92,6 +94,10 @@
return IWifiStaIface::FeatureSetMask::ND_OFFLOAD;
case WIFI_FEATURE_MKEEP_ALIVE:
return IWifiStaIface::FeatureSetMask::KEEP_ALIVE;
+ case WIFI_FEATURE_ROAMING_MODE_CONTROL:
+ return IWifiStaIface::FeatureSetMask::ROAMING_MODE_CONTROL;
+ case WIFI_FEATURE_CACHED_SCAN_RESULTS:
+ return IWifiStaIface::FeatureSetMask::CACHED_SCAN_DATA;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -109,7 +115,8 @@
WIFI_FEATURE_INFRA_60G,
WIFI_FEATURE_SET_LATENCY_MODE,
WIFI_FEATURE_P2P_RAND_MAC,
- WIFI_FEATURE_AFC_CHANNEL};
+ WIFI_FEATURE_AFC_CHANNEL,
+ WIFI_FEATURE_SET_VOIP_MODE};
for (const auto feature : features) {
if (feature & legacy_feature_set) {
*aidl_feature_set |= static_cast<uint32_t>(convertLegacyChipFeatureToAidl(feature));
@@ -457,7 +464,8 @@
{WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS, WIFI_FEATURE_RSSI_MONITOR,
WIFI_FEATURE_CONTROL_ROAMING, WIFI_FEATURE_IE_WHITELIST, WIFI_FEATURE_SCAN_RAND,
WIFI_FEATURE_INFRA_5G, WIFI_FEATURE_HOTSPOT, WIFI_FEATURE_PNO, WIFI_FEATURE_TDLS,
- WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE}) {
+ WIFI_FEATURE_TDLS_OFFCHANNEL, WIFI_FEATURE_CONFIG_NDO, WIFI_FEATURE_MKEEP_ALIVE,
+ WIFI_FEATURE_ROAMING_MODE_CONTROL, WIFI_FEATURE_CACHED_SCAN_RESULTS}) {
if (feature & legacy_feature_set) {
*aidl_feature_set |= static_cast<uint32_t>(convertLegacyStaIfaceFeatureToAidl(feature));
}
@@ -1147,6 +1155,8 @@
return legacy_hal::ROAMING_ENABLE;
case StaRoamingState::DISABLED:
return legacy_hal::ROAMING_DISABLE;
+ case StaRoamingState::AGGRESSIVE:
+ return legacy_hal::ROAMING_AGGRESSIVE;
};
CHECK(false);
}
@@ -2088,6 +2098,17 @@
memcpy(legacy_request->scid, aidl_request.securityConfig.scid.data(), legacy_request->scid_len);
legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForTksa ? 0x1 : 0x0;
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForGtksa ? 0x8 : 0x0;
+ if (aidl_request.securityConfig.supportGtkAndIgtk) {
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.supportBigtksa ? 0x4 : 0x2;
+ }
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.enableNcsBip256 ? 0x16 : 0x0;
+ legacy_request->gtk_protection =
+ aidl_request.securityConfig.requiresEnhancedFrameProtection ? 1 : 0;
+
return true;
}
@@ -2170,6 +2191,17 @@
memcpy(legacy_request->scid, aidl_request.securityConfig.scid.data(), legacy_request->scid_len);
legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForTksa ? 0x1 : 0x0;
+ legacy_request->csia_capabilities |=
+ aidl_request.securityConfig.enable16ReplyCountersForGtksa ? 0x8 : 0x0;
+ if (aidl_request.securityConfig.supportGtkAndIgtk) {
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.supportBigtksa ? 0x4 : 0x2;
+ }
+ legacy_request->csia_capabilities |= aidl_request.securityConfig.enableNcsBip256 ? 0x16 : 0x0;
+ legacy_request->gtk_protection =
+ aidl_request.securityConfig.requiresEnhancedFrameProtection ? 1 : 0;
+
return true;
}
@@ -2394,8 +2426,11 @@
switch (type) {
case RttType::ONE_SIDED:
return legacy_hal::RTT_TYPE_1_SIDED;
- case RttType::TWO_SIDED:
- return legacy_hal::RTT_TYPE_2_SIDED;
+ case RttType::TWO_SIDED_11MC:
+ // Same as RttType::TWO_SIDED
+ return legacy_hal::RTT_TYPE_2_SIDED_11MC;
+ case RttType::TWO_SIDED_11AZ_NTB:
+ return legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB;
};
CHECK(false);
}
@@ -2404,8 +2439,11 @@
switch (type) {
case legacy_hal::RTT_TYPE_1_SIDED:
return RttType::ONE_SIDED;
- case legacy_hal::RTT_TYPE_2_SIDED:
- return RttType::TWO_SIDED;
+ case legacy_hal::RTT_TYPE_2_SIDED_11MC:
+ // Same as legacy_hal::RTT_TYPE_2_SIDED
+ return RttType::TWO_SIDED_11MC;
+ case legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB:
+ return RttType::TWO_SIDED_11AZ_NTB;
};
CHECK(false) << "Unknown legacy type: " << type;
}
@@ -2485,6 +2523,8 @@
return legacy_hal::WIFI_RTT_PREAMBLE_HE;
case RttPreamble::EHT:
return legacy_hal::WIFI_RTT_PREAMBLE_EHT;
+ case RttPreamble::INVALID:
+ return legacy_hal::WIFI_RTT_PREAMBLE_INVALID;
};
CHECK(false);
}
@@ -2501,6 +2541,8 @@
return RttPreamble::HE;
case legacy_hal::WIFI_RTT_PREAMBLE_EHT:
return RttPreamble::EHT;
+ case legacy_hal::WIFI_RTT_PREAMBLE_INVALID:
+ return RttPreamble::INVALID;
};
CHECK(false) << "Unknown legacy type: " << type;
}
@@ -2690,6 +2732,21 @@
return true;
}
+bool convertAidlRttConfigToLegacyV3(const RttConfig& aidl_config,
+ legacy_hal::wifi_rtt_config_v3* legacy_config) {
+ if (!legacy_config) {
+ return false;
+ }
+ *legacy_config = {};
+ if (!convertAidlRttConfigToLegacy(aidl_config, &(legacy_config->rtt_config))) {
+ return false;
+ }
+ legacy_config->tx_ltf_repetition_count = aidl_config.txLtfRepetitionCount;
+ legacy_config->ntb_min_measurement_time_millis = aidl_config.ntbMinMeasurementTimeMillis;
+ legacy_config->ntb_max_measurement_time_millis = aidl_config.ntbMaxMeasurementTimeMillis;
+ return true;
+}
+
bool convertAidlVectorOfRttConfigToLegacy(
const std::vector<RttConfig>& aidl_configs,
std::vector<legacy_hal::wifi_rtt_config>* legacy_configs) {
@@ -2699,7 +2756,24 @@
*legacy_configs = {};
for (const auto& aidl_config : aidl_configs) {
legacy_hal::wifi_rtt_config legacy_config;
- if (!convertAidlRttConfigToLegacy(aidl_config, &legacy_config)) {
+ if (!convertAidlRttConfigToLegacy(aidl_config, &(legacy_config))) {
+ return false;
+ }
+ legacy_configs->push_back(legacy_config);
+ }
+ return true;
+}
+
+bool convertAidlVectorOfRttConfigToLegacyV3(
+ const std::vector<RttConfig>& aidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config_v3>* legacy_configs) {
+ if (!legacy_configs) {
+ return false;
+ }
+ *legacy_configs = {};
+ for (const auto& aidl_config : aidl_configs) {
+ legacy_hal::wifi_rtt_config_v3 legacy_config;
+ if (!convertAidlRttConfigToLegacyV3(aidl_config, &legacy_config)) {
return false;
}
legacy_configs->push_back(legacy_config);
@@ -2768,6 +2842,34 @@
return true;
}
+RttPreamble convertLegacyRttPreambleBitmapToAidl(byte legacyPreambleBitmap) {
+ int32_t aidlPreambleBitmap = 0;
+ for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
+ legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
+ legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
+ if (legacyPreambleBitmap & flag) {
+ aidlPreambleBitmap |= static_cast<std::underlying_type<RttPreamble>::type>(
+ convertLegacyRttPreambleToAidl(flag));
+ }
+ }
+
+ return static_cast<RttPreamble>(aidlPreambleBitmap);
+}
+
+RttBw convertLegacyRttBwBitmapToAidl(byte legacyBwBitmap) {
+ int32_t aidlBwBitmap = 0;
+ for (const auto flag :
+ {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
+ legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
+ legacy_hal::WIFI_RTT_BW_320}) {
+ if (legacyBwBitmap & flag) {
+ aidlBwBitmap |=
+ static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToAidl(flag));
+ }
+ }
+ return static_cast<RttBw>(aidlBwBitmap);
+}
+
bool convertLegacyRttCapabilitiesToAidl(
const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
RttCapabilities* aidl_capabilities) {
@@ -2780,28 +2882,44 @@
aidl_capabilities->lciSupported = legacy_capabilities.lci_support;
aidl_capabilities->lcrSupported = legacy_capabilities.lcr_support;
aidl_capabilities->responderSupported = legacy_capabilities.responder_supported;
- int32_t preambleSupport = 0;
- for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY, legacy_hal::WIFI_RTT_PREAMBLE_HT,
- legacy_hal::WIFI_RTT_PREAMBLE_VHT, legacy_hal::WIFI_RTT_PREAMBLE_HE,
- legacy_hal::WIFI_RTT_PREAMBLE_EHT}) {
- if (legacy_capabilities.preamble_support & flag) {
- preambleSupport |= static_cast<std::underlying_type<RttPreamble>::type>(
- convertLegacyRttPreambleToAidl(flag));
- }
- }
- aidl_capabilities->preambleSupport = static_cast<RttPreamble>(preambleSupport);
- int32_t bwSupport = 0;
- for (const auto flag :
- {legacy_hal::WIFI_RTT_BW_5, legacy_hal::WIFI_RTT_BW_10, legacy_hal::WIFI_RTT_BW_20,
- legacy_hal::WIFI_RTT_BW_40, legacy_hal::WIFI_RTT_BW_80, legacy_hal::WIFI_RTT_BW_160,
- legacy_hal::WIFI_RTT_BW_320}) {
- if (legacy_capabilities.bw_support & flag) {
- bwSupport |=
- static_cast<std::underlying_type<RttBw>::type>(convertLegacyRttBwToAidl(flag));
- }
- }
- aidl_capabilities->bwSupport = static_cast<RttBw>(bwSupport);
+ aidl_capabilities->preambleSupport =
+ convertLegacyRttPreambleBitmapToAidl(legacy_capabilities.preamble_support);
+ aidl_capabilities->bwSupport = convertLegacyRttBwBitmapToAidl(legacy_capabilities.bw_support);
aidl_capabilities->mcVersion = legacy_capabilities.mc_version;
+ // Initialize 11az parameters to default
+ aidl_capabilities->azPreambleSupport = RttPreamble::INVALID;
+ aidl_capabilities->azBwSupport = RttBw::BW_UNSPECIFIED;
+ aidl_capabilities->ntbInitiatorSupported = false;
+ aidl_capabilities->ntbResponderSupported = false;
+ aidl_capabilities->maxTxLtfRepetitionCount = 0;
+ return true;
+}
+
+bool convertLegacyRttCapabilitiesV3ToAidl(
+ const legacy_hal::wifi_rtt_capabilities_v3& legacy_capabilities_v3,
+ RttCapabilities* aidl_capabilities) {
+ if (!aidl_capabilities) {
+ return false;
+ }
+ *aidl_capabilities = {};
+ aidl_capabilities->rttOneSidedSupported =
+ legacy_capabilities_v3.rtt_capab.rtt_one_sided_supported;
+ aidl_capabilities->rttFtmSupported = legacy_capabilities_v3.rtt_capab.rtt_ftm_supported;
+ aidl_capabilities->lciSupported = legacy_capabilities_v3.rtt_capab.lci_support;
+ aidl_capabilities->lcrSupported = legacy_capabilities_v3.rtt_capab.lcr_support;
+ aidl_capabilities->responderSupported = legacy_capabilities_v3.rtt_capab.responder_supported;
+ aidl_capabilities->preambleSupport =
+ convertLegacyRttPreambleBitmapToAidl(legacy_capabilities_v3.rtt_capab.preamble_support);
+ aidl_capabilities->bwSupport =
+ convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.rtt_capab.bw_support);
+ aidl_capabilities->mcVersion = legacy_capabilities_v3.rtt_capab.mc_version;
+ aidl_capabilities->azPreambleSupport =
+ convertLegacyRttPreambleBitmapToAidl(legacy_capabilities_v3.az_preamble_support);
+ aidl_capabilities->azBwSupport =
+ convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.az_bw_support);
+ aidl_capabilities->ntbInitiatorSupported = legacy_capabilities_v3.ntb_initiator_supported;
+ aidl_capabilities->ntbResponderSupported = legacy_capabilities_v3.ntb_responder_supported;
+ aidl_capabilities->maxTxLtfRepetitionCount = legacy_capabilities_v3.max_tx_ltf_repetition_count;
return true;
}
@@ -2876,6 +2994,9 @@
}
aidl_result.channelFreqMHz = 0;
aidl_result.packetBw = RttBw::BW_UNSPECIFIED;
+ aidl_result.txLtfRepetitionCount = 0;
+ aidl_result.ntbMinMeasurementTimeMillis = 0;
+ aidl_result.ntbMaxMeasurementTimeMillis = 0;
aidl_results->push_back(aidl_result);
}
return true;
@@ -2896,6 +3017,33 @@
aidl_result.channelFreqMHz =
legacy_result->frequency != UNSPECIFIED ? legacy_result->frequency : 0;
aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->packet_bw);
+ aidl_result.txLtfRepetitionCount = 0;
+ aidl_result.ntbMinMeasurementTimeMillis = 0;
+ aidl_result.ntbMaxMeasurementTimeMillis = 0;
+ aidl_results->push_back(aidl_result);
+ }
+ return true;
+}
+
+bool convertLegacyVectorOfRttResultV3ToAidl(
+ const std::vector<const legacy_hal::wifi_rtt_result_v3*>& legacy_results,
+ std::vector<RttResult>* aidl_results) {
+ if (!aidl_results) {
+ return false;
+ }
+ *aidl_results = {};
+ for (const auto legacy_result : legacy_results) {
+ RttResult aidl_result;
+ if (!convertLegacyRttResultToAidl(legacy_result->rtt_result.rtt_result, &aidl_result)) {
+ return false;
+ }
+ aidl_result.channelFreqMHz = legacy_result->rtt_result.frequency != UNSPECIFIED
+ ? legacy_result->rtt_result.frequency
+ : 0;
+ aidl_result.packetBw = convertLegacyRttBwToAidl(legacy_result->rtt_result.packet_bw);
+ aidl_result.txLtfRepetitionCount = legacy_result->tx_ltf_repetition_count;
+ aidl_result.ntbMinMeasurementTimeMillis = legacy_result->ntb_min_measurement_time_millis;
+ aidl_result.ntbMaxMeasurementTimeMillis = legacy_result->ntb_max_measurement_time_millis;
aidl_results->push_back(aidl_result);
}
return true;
@@ -3178,6 +3326,8 @@
legacy_request->cookie_length = aidl_request.cookie.size();
memcpy(legacy_request->cookie, aidl_request.cookie.data(), legacy_request->cookie_length);
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
+ legacy_request->comeback = aidl_request.isComeback ? 0x1 : 0x0;
return true;
}
@@ -3195,6 +3345,7 @@
legacy_request->service_instance_id = aidl_request.bootstrappingInstanceId;
legacy_request->rsp_code = aidl_request.acceptRequest ? NAN_BOOTSTRAPPING_REQUEST_ACCEPT
: NAN_BOOTSTRAPPING_REQUEST_REJECT;
+ legacy_request->publish_subscribe_id = static_cast<uint8_t>(aidl_request.discoverySessionId);
return true;
}
@@ -3362,6 +3513,195 @@
return true;
}
+bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
+ CachedScanData* aidl_scan_data) {
+ if (!aidl_scan_data) {
+ return false;
+ }
+ *aidl_scan_data = {};
+
+ std::vector<CachedScanResult> aidl_scan_results;
+ for (const auto& result : report.results) {
+ CachedScanResult aidl_scan_result;
+ if (!convertCachedScanResultToAidl(result, report.ts, &aidl_scan_result)) {
+ return false;
+ }
+ aidl_scan_results.push_back(aidl_scan_result);
+ }
+ aidl_scan_data->cachedScanResults = aidl_scan_results;
+
+ aidl_scan_data->scannedFrequenciesMhz = report.scanned_freqs;
+ return true;
+}
+
+bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
+ uint64_t ts_us, CachedScanResult* aidl_scan_result) {
+ if (!aidl_scan_result) {
+ return false;
+ }
+ *aidl_scan_result = {};
+ aidl_scan_result->timeStampInUs = ts_us - legacy_scan_result.age_ms * 1000;
+ if (aidl_scan_result->timeStampInUs < 0) {
+ aidl_scan_result->timeStampInUs = 0;
+ return false;
+ }
+ size_t max_len_excluding_null = sizeof(legacy_scan_result.ssid) - 1;
+ size_t ssid_len = strnlen((const char*)legacy_scan_result.ssid, max_len_excluding_null);
+ aidl_scan_result->ssid =
+ std::vector<uint8_t>(legacy_scan_result.ssid, legacy_scan_result.ssid + ssid_len);
+ aidl_scan_result->bssid = std::array<uint8_t, 6>();
+ std::copy(legacy_scan_result.bssid, legacy_scan_result.bssid + 6,
+ std::begin(aidl_scan_result->bssid));
+ aidl_scan_result->frequencyMhz = legacy_scan_result.chanspec.primary_frequency;
+ aidl_scan_result->channelWidthMhz =
+ convertLegacyWifiChannelWidthToAidl(legacy_scan_result.chanspec.width);
+ aidl_scan_result->rssiDbm = legacy_scan_result.rssi;
+ aidl_scan_result->preambleType = convertScanResultFlagsToPreambleType(legacy_scan_result.flags);
+ return true;
+}
+
+WifiRatePreamble convertScanResultFlagsToPreambleType(int flags) {
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::EHT;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::HE;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::VHT;
+ }
+ if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT) > 0) {
+ return WifiRatePreamble::HT;
+ }
+ return WifiRatePreamble::OFDM;
+}
+
+bool convertTwtCapabilitiesToAidl(legacy_hal::wifi_twt_capabilities legacy_twt_capabs,
+ TwtCapabilities* aidl_twt_capabs) {
+ if (!aidl_twt_capabs) {
+ return false;
+ }
+ aidl_twt_capabs->isTwtRequesterSupported = legacy_twt_capabs.is_twt_requester_supported;
+ aidl_twt_capabs->isTwtResponderSupported = legacy_twt_capabs.is_twt_responder_supported;
+ aidl_twt_capabs->isBroadcastTwtSupported = legacy_twt_capabs.is_flexible_twt_supported;
+ if (legacy_twt_capabs.min_wake_duration_micros > legacy_twt_capabs.max_wake_duration_micros) {
+ return false;
+ }
+ aidl_twt_capabs->minWakeDurationMicros = legacy_twt_capabs.min_wake_duration_micros;
+ aidl_twt_capabs->maxWakeDurationMicros = legacy_twt_capabs.max_wake_duration_micros;
+ if (legacy_twt_capabs.min_wake_interval_micros > legacy_twt_capabs.max_wake_interval_micros) {
+ return false;
+ }
+ aidl_twt_capabs->minWakeIntervalMicros = legacy_twt_capabs.min_wake_interval_micros;
+ aidl_twt_capabs->maxWakeIntervalMicros = legacy_twt_capabs.max_wake_interval_micros;
+ return true;
+}
+
+bool convertAidlTwtRequestToLegacy(const TwtRequest aidl_twt_request,
+ legacy_hal::wifi_twt_request* legacy_twt_request) {
+ if (legacy_twt_request == nullptr) {
+ return false;
+ }
+ legacy_twt_request->mlo_link_id = aidl_twt_request.mloLinkId;
+ if (aidl_twt_request.minWakeDurationMicros > aidl_twt_request.maxWakeDurationMicros) {
+ return false;
+ }
+ legacy_twt_request->min_wake_duration_micros = aidl_twt_request.minWakeDurationMicros;
+ legacy_twt_request->max_wake_duration_micros = aidl_twt_request.maxWakeDurationMicros;
+ if (aidl_twt_request.minWakeIntervalMicros > aidl_twt_request.maxWakeIntervalMicros) {
+ return false;
+ }
+ legacy_twt_request->min_wake_interval_micros = aidl_twt_request.minWakeIntervalMicros;
+ legacy_twt_request->max_wake_interval_micros = aidl_twt_request.maxWakeIntervalMicros;
+ return true;
+}
+
+IWifiStaIfaceEventCallback::TwtErrorCode convertLegacyHalTwtErrorCodeToAidl(
+ legacy_hal::wifi_twt_error_code legacy_error_code) {
+ switch (legacy_error_code) {
+ case WIFI_TWT_ERROR_CODE_TIMEOUT:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::TIMEOUT;
+ case WIFI_TWT_ERROR_CODE_PEER_REJECTED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::PEER_REJECTED;
+ case WIFI_TWT_ERROR_CODE_PEER_NOT_SUPPORTED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::PEER_NOT_SUPPORTED;
+ case WIFI_TWT_ERROR_CODE_NOT_SUPPORTED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::NOT_SUPPORTED;
+ case WIFI_TWT_ERROR_CODE_NOT_AVAILABLE:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::NOT_AVAILABLE;
+ case WIFI_TWT_ERROR_CODE_MAX_SESSION_REACHED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::MAX_SESSION_REACHED;
+ case WIFI_TWT_ERROR_CODE_INVALID_PARAMS:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::INVALID_PARAMS;
+ case WIFI_TWT_ERROR_CODE_ALREADY_SUSPENDED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::ALREADY_SUSPENDED;
+ case WIFI_TWT_ERROR_CODE_ALREADY_RESUMED:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::ALREADY_RESUMED;
+ default:
+ return IWifiStaIfaceEventCallback::TwtErrorCode::FAILURE_UNKNOWN;
+ }
+}
+
+IWifiStaIfaceEventCallback::TwtTeardownReasonCode convertLegacyHalTwtReasonCodeToAidl(
+ legacy_hal::wifi_twt_teardown_reason_code legacy_reason_code) {
+ switch (legacy_reason_code) {
+ case WIFI_TWT_TEARDOWN_REASON_CODE_LOCALLY_REQUESTED:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::LOCALLY_REQUESTED;
+ case WIFI_TWT_TEARDOWN_REASON_CODE_INTERNALLY_INITIATED:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::INTERNALLY_INITIATED;
+ case WIFI_TWT_TEARDOWN_REASON_CODE_PEER_INITIATED:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::PEER_INITIATED;
+ default:
+ return IWifiStaIfaceEventCallback::TwtTeardownReasonCode::UNKNOWN;
+ }
+}
+
+bool convertLegacyHalTwtSessionToAidl(legacy_hal::wifi_twt_session twt_session,
+ TwtSession* aidl_twt_session) {
+ if (aidl_twt_session == nullptr) {
+ return false;
+ }
+
+ aidl_twt_session->sessionId = twt_session.session_id;
+ aidl_twt_session->mloLinkId = twt_session.mlo_link_id;
+ aidl_twt_session->wakeDurationMicros = twt_session.wake_duration_micros;
+ aidl_twt_session->wakeIntervalMicros = twt_session.wake_interval_micros;
+ switch (twt_session.negotiation_type) {
+ case WIFI_TWT_NEGO_TYPE_INDIVIDUAL:
+ aidl_twt_session->negotiationType = TwtSession::TwtNegotiationType::INDIVIDUAL;
+ break;
+ case WIFI_TWT_NEGO_TYPE_BROADCAST:
+ aidl_twt_session->negotiationType = TwtSession::TwtNegotiationType::BROADCAST;
+ break;
+ default:
+ return false;
+ }
+ aidl_twt_session->isTriggerEnabled = twt_session.is_trigger_enabled;
+ aidl_twt_session->isAnnounced = twt_session.is_announced;
+ aidl_twt_session->isImplicit = twt_session.is_implicit;
+ aidl_twt_session->isProtected = twt_session.is_protected;
+ aidl_twt_session->isUpdatable = twt_session.is_updatable;
+ aidl_twt_session->isSuspendable = twt_session.is_suspendable;
+ aidl_twt_session->isResponderPmModeEnabled = twt_session.is_responder_pm_mode_enabled;
+ return true;
+}
+
+bool convertLegacyHalTwtSessionStatsToAidl(legacy_hal::wifi_twt_session_stats twt_stats,
+ TwtSessionStats* aidl_twt_stats) {
+ if (aidl_twt_stats == nullptr) {
+ return false;
+ }
+
+ aidl_twt_stats->avgTxPktCount = twt_stats.avg_pkt_num_tx;
+ aidl_twt_stats->avgRxPktCount = twt_stats.avg_pkt_num_rx;
+ aidl_twt_stats->avgTxPktSize = twt_stats.avg_tx_pkt_size;
+ aidl_twt_stats->avgRxPktSize = twt_stats.avg_rx_pkt_size;
+ aidl_twt_stats->avgEospDurationMicros = twt_stats.avg_eosp_dur_us;
+ aidl_twt_stats->eospCount = twt_stats.eosp_count;
+
+ return true;
+}
+
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index e4ff963..7089363 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -148,6 +148,10 @@
// RTT controller conversion methods.
bool convertAidlVectorOfRttConfigToLegacy(const std::vector<RttConfig>& aidl_configs,
std::vector<legacy_hal::wifi_rtt_config>* legacy_configs);
+bool convertAidlVectorOfRttConfigToLegacyV3(
+ const std::vector<RttConfig>& aidl_configs,
+ std::vector<legacy_hal::wifi_rtt_config_v3>* legacy_configs);
+
bool convertAidlRttLciInformationToLegacy(const RttLciInformation& aidl_info,
legacy_hal::wifi_lci_information* legacy_info);
bool convertAidlRttLcrInformationToLegacy(const RttLcrInformation& aidl_info,
@@ -161,12 +165,19 @@
bool convertLegacyRttCapabilitiesToAidl(
const legacy_hal::wifi_rtt_capabilities& legacy_capabilities,
RttCapabilities* aidl_capabilities);
+bool convertLegacyRttCapabilitiesV3ToAidl(
+ const legacy_hal::wifi_rtt_capabilities_v3& legacy_capabilities_v3,
+ RttCapabilities* aidl_capabilities);
+
bool convertLegacyVectorOfRttResultToAidl(
const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
std::vector<RttResult>* aidl_results);
bool convertLegacyVectorOfRttResultV2ToAidl(
const std::vector<const legacy_hal::wifi_rtt_result_v2*>& legacy_results,
std::vector<RttResult>* aidl_results);
+bool convertLegacyVectorOfRttResultV3ToAidl(
+ const std::vector<const legacy_hal::wifi_rtt_result_v3*>& legacy_results,
+ std::vector<RttResult>* aidl_results);
uint32_t convertAidlWifiBandToLegacyMacBand(WifiBand band);
uint32_t convertAidlWifiIfaceModeToLegacy(uint32_t aidl_iface_mask);
uint32_t convertAidlUsableChannelFilterToLegacy(uint32_t aidl_filter_mask);
@@ -202,6 +213,23 @@
const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
NanBootstrappingConfirmInd* aidl_ind);
uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask);
+bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
+ CachedScanData* aidl_scan_data);
+bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
+ uint64_t ts_us, CachedScanResult* aidl_scan_result);
+WifiRatePreamble convertScanResultFlagsToPreambleType(int flags);
+bool convertTwtCapabilitiesToAidl(const legacy_hal::wifi_twt_capabilities legacy_twt_capabs,
+ TwtCapabilities* aidl_twt_capabs);
+bool convertAidlTwtRequestToLegacy(const TwtRequest aidl_twt_request,
+ legacy_hal::wifi_twt_request* legacy_twt_request);
+IWifiStaIfaceEventCallback::TwtErrorCode convertLegacyHalTwtErrorCodeToAidl(
+ legacy_hal::wifi_twt_error_code legacy_error_code);
+IWifiStaIfaceEventCallback::TwtTeardownReasonCode convertLegacyHalTwtReasonCodeToAidl(
+ legacy_hal::wifi_twt_teardown_reason_code legacy_reason_code);
+bool convertLegacyHalTwtSessionToAidl(legacy_hal::wifi_twt_session twt_session,
+ TwtSession* aidl_twt_session);
+bool convertLegacyHalTwtSessionStatsToAidl(legacy_hal::wifi_twt_session_stats twt_stats,
+ TwtSessionStats* aidl_twt_stats);
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
index 995a13d..2a030ee 100644
--- a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -35,6 +35,12 @@
0x2c, 0x00, 0x00, 0x41, 0x06, 0x03, 0x06, 0x00, 0x80};
byte LCR[] = {0x27, 0xE, 0x1, 0x00, 0xB, 0x01, 0x00, 0x0b, 0x00, 0x09,
0x55, 0x53, 0x18, 0x05, 0x39, 0x34, 0x30, 0x34, 0x33};
+
+constexpr int kNumScanResult = 2;
+constexpr int kRssi[] = {-60, -70};
+constexpr uint8_t kBssid[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0};
+constexpr uint8_t kSsidLen = 6;
+constexpr char kSsid[] = {'a', 'b', 'c', 'd', 'e', '\0'};
} // namespace
namespace aidl {
@@ -883,6 +889,51 @@
}
}
+TEST_F(AidlStructUtilTest, convertCachedScanReportToAidl) {
+ legacy_hal::WifiCachedScanReport hw_report;
+
+ hw_report.ts = 10000000;
+ std::vector<int> scanned_freqs{5260, 2437, 5200};
+ std::vector<wifi_cached_scan_result> results;
+ hw_report.scanned_freqs = scanned_freqs;
+
+ for (int i = 0; i < kNumScanResult; i++) {
+ wifi_cached_scan_result result;
+ result.age_ms = i * 1000;
+ result.capability = i;
+ memcpy(result.ssid, kSsid, kSsidLen);
+ result.ssid_len = kSsidLen;
+ memcpy(result.bssid, kBssid, 6);
+ result.flags = WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT;
+ result.rssi = kRssi[i];
+ result.chanspec = {legacy_hal::WIFI_CHAN_WIDTH_40, 0, 0, i};
+ results.push_back(result);
+ }
+ hw_report.results = results;
+
+ CachedScanData aidl_data;
+ aidl_struct_util::convertCachedScanReportToAidl(hw_report, &aidl_data);
+
+ EXPECT_EQ(scanned_freqs.size(), aidl_data.scannedFrequenciesMhz.size());
+ EXPECT_EQ(scanned_freqs[2], aidl_data.scannedFrequenciesMhz[2]);
+ EXPECT_EQ(5260, aidl_data.scannedFrequenciesMhz[0]);
+ EXPECT_EQ(kNumScanResult, (int)aidl_data.cachedScanResults.size());
+ for (int i = 0; i < kNumScanResult; i++) {
+ EXPECT_EQ(hw_report.results[i].rssi, aidl_data.cachedScanResults[i].rssiDbm);
+ EXPECT_EQ(i, aidl_data.cachedScanResults[i].frequencyMhz);
+ int64_t expected_ts = 10000000 - i * 1000 * 1000;
+ EXPECT_EQ(expected_ts, aidl_data.cachedScanResults[i].timeStampInUs);
+ EXPECT_EQ(WifiRatePreamble::HE, aidl_data.cachedScanResults[i].preambleType);
+ EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_40, aidl_data.cachedScanResults[i].channelWidthMhz);
+ for (int k = 0; k < 6; k++) {
+ EXPECT_EQ(kBssid[k], aidl_data.cachedScanResults[i].bssid[k]);
+ }
+ for (int k = 0; k < kSsidLen; k++) {
+ EXPECT_EQ(kSsid[k], aidl_data.cachedScanResults[i].ssid[k]);
+ }
+ }
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index d72775c..9b9c565 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -20,6 +20,7 @@
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
#include <fcntl.h>
+#include <hardware_legacy/wifi_hal.h>
#include <net/if.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
@@ -605,6 +606,11 @@
&WifiChip::setMloModeInternal, in_mode);
}
+ndk::ScopedAStatus WifiChip::setVoipMode(const VoipMode in_mode) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+ &WifiChip::setVoipModeInternal, in_mode);
+}
+
void WifiChip::invalidateAndRemoveAllIfaces() {
invalidateAndClearBridgedApAll();
invalidateAndClearAll(ap_ifaces_);
@@ -1913,6 +1919,23 @@
return createWifiStatusFromLegacyError(legacy_hal_.lock()->setMloMode(mode));
}
+ndk::ScopedAStatus WifiChip::setVoipModeInternal(const WifiChip::VoipMode in_mode) {
+ const auto ifname = getFirstActiveWlanIfaceName();
+ wifi_voip_mode mode;
+ switch (in_mode) {
+ case WifiChip::VoipMode::VOICE:
+ mode = wifi_voip_mode::WIFI_VOIP_MODE_VOICE;
+ break;
+ case WifiChip::VoipMode::OFF:
+ mode = wifi_voip_mode::WIFI_VOIP_MODE_OFF;
+ break;
+ default:
+ PLOG(ERROR) << "Error: invalid mode: " << toString(in_mode);
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ return createWifiStatusFromLegacyError(legacy_hal_.lock()->setVoipMode(ifname, mode));
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index c6517db..ffd507f 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -158,6 +158,7 @@
int32_t in_channelCategoryEnableFlag) override;
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
ndk::ScopedAStatus setMloMode(const ChipMloMode in_mode) override;
+ ndk::ScopedAStatus setVoipMode(const VoipMode in_mode) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -269,6 +270,7 @@
getSupportedRadioCombinationsInternal();
std::pair<WifiChipCapabilities, ndk::ScopedAStatus> getWifiChipCapabilitiesInternal();
ndk::ScopedAStatus setMloModeInternal(const ChipMloMode in_mode);
+ ndk::ScopedAStatus setVoipModeInternal(const VoipMode in_mode);
void retrieveDynamicIfaceCombination();
void setWeakPtr(std::weak_ptr<WifiChip> ptr);
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index 209670b..55d6f59 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -183,10 +183,13 @@
on_rtt_results_internal_callback;
std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v2* rtt_results_v2[])>
on_rtt_results_internal_callback_v2;
+std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v3* rtt_results_v3[])>
+ on_rtt_results_internal_callback_v3;
void invalidateRttResultsCallbacks() {
on_rtt_results_internal_callback = nullptr;
on_rtt_results_internal_callback_v2 = nullptr;
+ on_rtt_results_internal_callback_v3 = nullptr;
};
void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
@@ -206,6 +209,15 @@
}
}
+void onAsyncRttResultsV3(wifi_request_id id, unsigned num_results,
+ wifi_rtt_result_v3* rtt_results_v3[]) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_rtt_results_internal_callback_v3) {
+ on_rtt_results_internal_callback_v3(id, num_results, rtt_results_v3);
+ invalidateRttResultsCallbacks();
+ }
+}
+
// Callbacks for the various NAN operations.
// NOTE: These have very little conversions to perform before invoking the user
// callbacks.
@@ -439,11 +451,82 @@
// Callback to report cached scan results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
if (on_cached_scan_results_internal_callback) {
on_cached_scan_results_internal_callback(cache_report);
}
}
+// Callback to be invoked for TWT failure
+std::function<void((wifi_request_id, wifi_twt_error_code error_code))>
+ on_twt_failure_internal_callback;
+void onAsyncTwtError(wifi_request_id id, wifi_twt_error_code error_code) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_failure_internal_callback) {
+ on_twt_failure_internal_callback(id, error_code);
+ }
+}
+
+// Callback to be invoked for TWT session creation
+std::function<void((wifi_request_id, wifi_twt_session twt_session))>
+ on_twt_session_create_internal_callback;
+void onAsyncTwtSessionCreate(wifi_request_id id, wifi_twt_session twt_session) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_create_internal_callback) {
+ on_twt_session_create_internal_callback(id, twt_session);
+ }
+}
+
+// Callback to be invoked for TWT session update
+std::function<void((wifi_request_id, wifi_twt_session twt_session))>
+ on_twt_session_update_internal_callback;
+void onAsyncTwtSessionUpdate(wifi_request_id id, wifi_twt_session twt_session) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_update_internal_callback) {
+ on_twt_session_update_internal_callback(id, twt_session);
+ }
+}
+
+// Callback to be invoked for TWT session teardown
+std::function<void(
+ (wifi_request_id, int twt_session_id, wifi_twt_teardown_reason_code reason_code))>
+ on_twt_session_teardown_internal_callback;
+void onAsyncTwtSessionTeardown(wifi_request_id id, int twt_session_id,
+ wifi_twt_teardown_reason_code reason_code) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_teardown_internal_callback) {
+ on_twt_session_teardown_internal_callback(id, twt_session_id, reason_code);
+ }
+}
+
+// Callback to be invoked for TWT session get stats
+std::function<void((wifi_request_id, int twt_session_id, wifi_twt_session_stats stats))>
+ on_twt_session_stats_internal_callback;
+void onAsyncTwtSessionStats(wifi_request_id id, int twt_session_id, wifi_twt_session_stats stats) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_stats_internal_callback) {
+ on_twt_session_stats_internal_callback(id, twt_session_id, stats);
+ }
+}
+
+// Callback to be invoked for TWT session suspend
+std::function<void((wifi_request_id, int twt_session_id))> on_twt_session_suspend_internal_callback;
+void onAsyncTwtSessionSuspend(wifi_request_id id, int twt_session_id) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_suspend_internal_callback) {
+ on_twt_session_suspend_internal_callback(id, twt_session_id);
+ }
+}
+
+// Callback to be invoked for TWT session resume
+std::function<void((wifi_request_id, int twt_session_id))> on_twt_session_resume_internal_callback;
+void onAsyncTwtSessionResume(wifi_request_id id, int twt_session_id) {
+ const auto lock = aidl_sync_util::acquireGlobalLock();
+ if (on_twt_session_resume_internal_callback) {
+ on_twt_session_resume_internal_callback(id, twt_session_id);
+ }
+}
+
// End of the free-standing "C" style callbacks.
WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
@@ -1251,6 +1334,38 @@
return status;
}
+wifi_error WifiLegacyHal::startRttRangeRequestV3(
+ const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config_v3>& rtt_configs,
+ const on_rtt_results_callback_v3& on_results_user_callback_v3) {
+ if (on_rtt_results_internal_callback_v3) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_rtt_results_internal_callback_v3 = [on_results_user_callback_v3](
+ wifi_request_id id, unsigned num_results,
+ wifi_rtt_result_v3* rtt_results_v3[]) {
+ if (num_results > 0 && !rtt_results_v3) {
+ LOG(ERROR) << "Unexpected nullptr in RTT v3 results";
+ return;
+ }
+ std::vector<const wifi_rtt_result_v3*> rtt_results_vec_v3;
+ std::copy_if(rtt_results_v3, rtt_results_v3 + num_results,
+ back_inserter(rtt_results_vec_v3),
+ [](wifi_rtt_result_v3* rtt_result_v3) { return rtt_result_v3 != nullptr; });
+ on_results_user_callback_v3(id, rtt_results_vec_v3);
+ };
+
+ std::vector<wifi_rtt_config_v3> rtt_configs_internal(rtt_configs);
+ wifi_error status = global_func_table_.wifi_rtt_range_request_v3(
+ id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
+ {onAsyncRttResultsV3});
+ if (status != WIFI_SUCCESS) {
+ invalidateRttResultsCallbacks();
+ }
+ return status;
+}
+
wifi_error WifiLegacyHal::startRttRangeRequest(
const std::string& iface_name, wifi_request_id id,
const std::vector<wifi_rtt_config>& rtt_configs,
@@ -1327,6 +1442,14 @@
return {status, rtt_caps};
}
+std::pair<wifi_error, wifi_rtt_capabilities_v3> WifiLegacyHal::getRttCapabilitiesV3(
+ const std::string& iface_name) {
+ wifi_rtt_capabilities_v3 rtt_caps_v3;
+ wifi_error status = global_func_table_.wifi_get_rtt_capabilities_v3(getIfaceHandle(iface_name),
+ &rtt_caps_v3);
+ return {status, rtt_caps_v3};
+}
+
std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
const std::string& iface_name) {
wifi_rtt_responder rtt_responder;
@@ -1736,6 +1859,103 @@
return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
}
+std::pair<wifi_twt_capabilities, wifi_error> WifiLegacyHal::twtGetCapabilities(
+ const std::string& ifaceName) {
+ wifi_twt_capabilities capabs = {};
+ wifi_error status =
+ global_func_table_.wifi_twt_get_capabilities(getIfaceHandle(ifaceName), &capabs);
+ return {capabs, status};
+}
+
+wifi_error WifiLegacyHal::twtSessionSetup(
+ const std::string& ifaceName, uint32_t cmdId, const wifi_twt_request& request,
+ const on_twt_failure& on_twt_failure_user_callback,
+ const on_twt_session_create& on_twt_session_create_user_callback,
+ const on_twt_session_update& on_twt_session_update_user_callback,
+ const on_twt_session_teardown& on_twt_session_teardown_user_callback,
+ const on_twt_session_stats& on_twt_session_stats_user_callback,
+ const on_twt_session_suspend& on_twt_session_suspend_user_callback,
+ const on_twt_session_resume& on_twt_session_resume_user_callback) {
+ if (on_twt_failure_internal_callback || on_twt_session_create_internal_callback ||
+ on_twt_session_update_internal_callback || on_twt_session_teardown_internal_callback ||
+ on_twt_session_stats_internal_callback) {
+ return WIFI_ERROR_NOT_AVAILABLE;
+ }
+
+ on_twt_failure_internal_callback = [on_twt_failure_user_callback](
+ wifi_request_id id, wifi_twt_error_code error_code) {
+ on_twt_failure_user_callback(id, error_code);
+ };
+
+ on_twt_session_create_internal_callback = [on_twt_session_create_user_callback](
+ wifi_request_id id,
+ wifi_twt_session twt_session) {
+ on_twt_session_create_user_callback(id, twt_session);
+ };
+
+ on_twt_session_update_internal_callback = [on_twt_session_update_user_callback](
+ wifi_request_id id,
+ wifi_twt_session twt_session) {
+ on_twt_session_update_user_callback(id, twt_session);
+ };
+
+ on_twt_session_teardown_internal_callback = [on_twt_session_teardown_user_callback](
+ wifi_request_id id, int session_id,
+ wifi_twt_teardown_reason_code reason_code) {
+ on_twt_session_teardown_user_callback(id, session_id, reason_code);
+ };
+
+ on_twt_session_stats_internal_callback = [on_twt_session_stats_user_callback](
+ wifi_request_id id, int session_id,
+ wifi_twt_session_stats stats) {
+ on_twt_session_stats_user_callback(id, session_id, stats);
+ };
+
+ on_twt_session_suspend_internal_callback = [on_twt_session_suspend_user_callback](
+ wifi_request_id id, int session_id) {
+ on_twt_session_suspend_user_callback(id, session_id);
+ };
+
+ on_twt_session_resume_internal_callback = [on_twt_session_resume_user_callback](
+ wifi_request_id id, int session_id) {
+ on_twt_session_resume_user_callback(id, session_id);
+ };
+
+ return global_func_table_.wifi_twt_session_setup(
+ cmdId, getIfaceHandle(ifaceName), request,
+ {onAsyncTwtError, onAsyncTwtSessionCreate, onAsyncTwtSessionUpdate,
+ onAsyncTwtSessionTeardown, onAsyncTwtSessionStats, onAsyncTwtSessionSuspend,
+ onAsyncTwtSessionResume});
+}
+
+wifi_error WifiLegacyHal::twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId, const wifi_twt_request& request) {
+ return global_func_table_.wifi_twt_session_update(cmdId, getIfaceHandle(ifaceName), sessionId,
+ request);
+}
+
+wifi_error WifiLegacyHal::twtSessionSuspend(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_suspend(cmdId, getIfaceHandle(ifaceName), sessionId);
+}
+
+wifi_error WifiLegacyHal::twtSessionResume(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_resume(cmdId, getIfaceHandle(ifaceName), sessionId);
+}
+
+wifi_error WifiLegacyHal::twtSessionTeardown(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_teardown(cmdId, getIfaceHandle(ifaceName),
+ sessionId);
+}
+
+wifi_error WifiLegacyHal::twtSessionGetStats(const std::string& ifaceName, uint32_t cmdId,
+ uint32_t sessionId) {
+ return global_func_table_.wifi_twt_session_get_stats(cmdId, getIfaceHandle(ifaceName),
+ sessionId);
+}
+
wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
const TwtCallbackHandlers& user_callbacks) {
on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
@@ -1858,13 +2078,16 @@
return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
}
-wifi_error WifiLegacyHal::getWifiCachedScanResults(
- const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
- on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
-
+wifi_error WifiLegacyHal::getWifiCachedScanResults(const std::string& iface_name,
+ WifiCachedScanReport& report) {
+ on_cached_scan_results_internal_callback = [&report](wifi_cached_scan_report* report_ptr) {
+ report.results.assign(report_ptr->results, report_ptr->results + report_ptr->result_cnt);
+ report.scanned_freqs.assign(report_ptr->scanned_freq_list,
+ report_ptr->scanned_freq_list + report_ptr->scanned_freq_num);
+ report.ts = report_ptr->ts;
+ };
wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
{onSyncCachedScanResults});
-
on_cached_scan_results_internal_callback = nullptr;
return status;
}
@@ -1934,6 +2157,7 @@
on_twt_event_info_frame_received_callback = nullptr;
on_twt_event_device_notify_callback = nullptr;
on_chre_nan_rtt_internal_callback = nullptr;
+ on_cached_scan_results_internal_callback = nullptr;
}
} // namespace legacy_hal
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 5168a8b..121d1b5 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -186,6 +186,7 @@
using ::NanTxType;
using ::NpkSecurityAssociation;
using ::PASN;
+using ::ROAMING_AGGRESSIVE;
using ::ROAMING_DISABLE;
using ::ROAMING_ENABLE;
using ::RTT_PEER_AP;
@@ -214,6 +215,8 @@
using ::RTT_STATUS_SUCCESS;
using ::RTT_TYPE_1_SIDED;
using ::RTT_TYPE_2_SIDED;
+using ::RTT_TYPE_2_SIDED_11AZ_NTB;
+using ::RTT_TYPE_2_SIDED_11MC;
using ::RX_PKT_FATE_DRV_DROP_FILTER;
using ::RX_PKT_FATE_DRV_DROP_INVALID;
using ::RX_PKT_FATE_DRV_DROP_NOBUFS;
@@ -256,6 +259,7 @@
using ::WIFI_BAND_BG;
using ::WIFI_BAND_UNSPECIFIED;
using ::wifi_cached_scan_report;
+using ::wifi_cached_scan_result;
using ::wifi_cached_scan_results;
using ::WIFI_CHAN_WIDTH_10;
using ::WIFI_CHAN_WIDTH_160;
@@ -349,16 +353,20 @@
using ::WIFI_RTT_BW_80;
using ::WIFI_RTT_BW_UNSPECIFIED;
using ::wifi_rtt_capabilities;
+using ::wifi_rtt_capabilities_v3;
using ::wifi_rtt_config;
+using ::wifi_rtt_config_v3;
using ::wifi_rtt_preamble;
using ::WIFI_RTT_PREAMBLE_EHT;
using ::WIFI_RTT_PREAMBLE_HE;
using ::WIFI_RTT_PREAMBLE_HT;
+using ::WIFI_RTT_PREAMBLE_INVALID;
using ::WIFI_RTT_PREAMBLE_LEGACY;
using ::WIFI_RTT_PREAMBLE_VHT;
using ::wifi_rtt_responder;
using ::wifi_rtt_result;
using ::wifi_rtt_result_v2;
+using ::wifi_rtt_result_v3;
using ::wifi_rtt_status;
using ::wifi_rtt_type;
using ::wifi_rx_packet_fate;
@@ -368,6 +376,13 @@
using ::WIFI_SCAN_FLAG_INTERRUPTED;
using ::wifi_scan_result;
using ::WIFI_SUCCESS;
+using ::wifi_twt_capabilities;
+using ::wifi_twt_error_code;
+using ::wifi_twt_events;
+using ::wifi_twt_request;
+using ::wifi_twt_session;
+using ::wifi_twt_session_stats;
+using ::wifi_twt_teardown_reason_code;
using ::wifi_tx_packet_fate;
using ::wifi_tx_report;
using ::wifi_usable_channel;
@@ -422,6 +437,12 @@
bool valid;
};
+struct WifiCachedScanReport {
+ uint64_t ts;
+ std::vector<int> scanned_freqs;
+ std::vector<wifi_cached_scan_result> results;
+};
+
#pragma GCC diagnostic pop
// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
@@ -485,6 +506,8 @@
std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result*>&)>;
using on_rtt_results_callback_v2 =
std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result_v2*>&)>;
+using on_rtt_results_callback_v3 =
+ std::function<void(wifi_request_id, const std::vector<const wifi_rtt_result_v3*>&)>;
// Callback for ring buffer data.
using on_ring_buffer_data_callback = std::function<void(
@@ -532,12 +555,23 @@
std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
};
-// Cached Scan Results response and event callbacks struct.
-struct CachedScanResultsCallbackHandlers {
+using on_cached_scan_results_callback = std::function<void(wifi_cached_scan_report*)>;
+
+struct CachedScanResultsCallbfackHandlers {
// Callback for Cached Scan Results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
};
+using on_twt_failure = std::function<void(wifi_request_id id, wifi_twt_error_code error_code)>;
+using on_twt_session_create = std::function<void(wifi_request_id id, wifi_twt_session twt_session)>;
+using on_twt_session_update = std::function<void(wifi_request_id id, wifi_twt_session twt_session)>;
+using on_twt_session_teardown = std::function<void(wifi_request_id id, int session_id,
+ wifi_twt_teardown_reason_code reason_code)>;
+using on_twt_session_stats =
+ std::function<void(wifi_request_id id, int session_id, wifi_twt_session_stats stats)>;
+using on_twt_session_suspend = std::function<void(wifi_request_id id, int session_id)>;
+using on_twt_session_resume = std::function<void(wifi_request_id id, int session_id)>;
+
/**
* Class that encapsulates all legacy HAL interactions.
* This class manages the lifetime of the event loop thread used by legacy HAL.
@@ -659,9 +693,15 @@
const std::vector<wifi_rtt_config>& rtt_configs,
const on_rtt_results_callback& on_results_callback,
const on_rtt_results_callback_v2& on_results_callback_v2);
+ wifi_error startRttRangeRequestV3(const std::string& iface_name, wifi_request_id id,
+ const std::vector<wifi_rtt_config_v3>& rtt_configs,
+ const on_rtt_results_callback_v3& on_results_callback);
+
wifi_error cancelRttRangeRequest(const std::string& iface_name, wifi_request_id id,
const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs);
std::pair<wifi_error, wifi_rtt_capabilities> getRttCapabilities(const std::string& iface_name);
+ std::pair<wifi_error, wifi_rtt_capabilities_v3> getRttCapabilitiesV3(
+ const std::string& iface_name);
std::pair<wifi_error, wifi_rtt_responder> getRttResponderInfo(const std::string& iface_name);
wifi_error enableRttResponder(const std::string& iface_name, wifi_request_id id,
const wifi_channel_info& channel_hint, uint32_t max_duration_secs,
@@ -738,19 +778,39 @@
wifi_error setVoipMode(const std::string& iface_name, wifi_voip_mode mode);
+ // TWT functions
+ std::pair<wifi_twt_capabilities, wifi_error> twtGetCapabilities(const std::string& ifaceName);
+ wifi_error twtSessionSetup(const std::string& ifaceName, uint32_t cmdId,
+ const wifi_twt_request& request,
+ const on_twt_failure& on_twt_failure_user_callback,
+ const on_twt_session_create& on_twt_session_create_user_callback,
+ const on_twt_session_update& on_twt_session_update_user_callback,
+ const on_twt_session_teardown& on_twt_session_teardown_user_callback,
+ const on_twt_session_stats& on_twt_session_stats_user_callback,
+ const on_twt_session_suspend& on_twt_session_suspend_user_callback,
+ const on_twt_session_resume& on_twt_session_resume_user_callback);
+ wifi_error twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId,
+ const wifi_twt_request& request);
+ wifi_error twtSessionSuspend(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+ wifi_error twtSessionResume(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+ wifi_error twtSessionTeardown(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+ wifi_error twtSessionGetStats(const std::string& ifaceName, uint32_t cmdId, uint32_t sessionId);
+
+ // Note: Following TWT functions are deprecated
+ // Deprecated
wifi_error twtRegisterHandler(const std::string& iface_name,
const TwtCallbackHandlers& handler);
-
+ // Deprecated by twtGetCapabilities
std::pair<wifi_error, TwtCapabilitySet> twtGetCapability(const std::string& iface_name);
-
+ // Deprecated by twtSessionSetup
wifi_error twtSetupRequest(const std::string& iface_name, const TwtSetupRequest& msg);
-
+ // Deprecated by twtSessionTeardown
wifi_error twtTearDownRequest(const std::string& iface_name, const TwtTeardownRequest& msg);
-
+ // Deprecated by twtSessionSuspend and twtSessionResume
wifi_error twtInfoFrameRequest(const std::string& iface_name, const TwtInfoFrameRequest& msg);
-
+ // Deprecated by twtSessionGetStats
std::pair<wifi_error, TwtStats> twtGetStats(const std::string& iface_name, uint8_t configId);
-
+ // Deprecated
wifi_error twtClearStats(const std::string& iface_name, uint8_t configId);
wifi_error setScanMode(const std::string& iface_name, bool enable);
@@ -776,7 +836,7 @@
wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
wifi_error getWifiCachedScanResults(const std::string& iface_name,
- const CachedScanResultsCallbackHandlers& handler);
+ WifiCachedScanReport& report);
std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
wifi_error setMloMode(wifi_mlo_mode mode);
diff --git a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
index b5196c9..3e4afd0 100644
--- a/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal_stubs.cpp
@@ -179,6 +179,15 @@
populateStubFor(&hal_fn->wifi_set_scan_mode);
populateStubFor(&hal_fn->wifi_set_mlo_mode);
populateStubFor(&hal_fn->wifi_get_supported_iface_concurrency_matrix);
+ populateStubFor(&hal_fn->wifi_get_rtt_capabilities_v3);
+ populateStubFor(&hal_fn->wifi_rtt_range_request_v3);
+ populateStubFor(&hal_fn->wifi_twt_get_capabilities);
+ populateStubFor(&hal_fn->wifi_twt_session_setup);
+ populateStubFor(&hal_fn->wifi_twt_session_update);
+ populateStubFor(&hal_fn->wifi_twt_session_suspend);
+ populateStubFor(&hal_fn->wifi_twt_session_resume);
+ populateStubFor(&hal_fn->wifi_twt_session_teardown);
+ populateStubFor(&hal_fn->wifi_twt_session_get_stats);
return true;
}
diff --git a/wifi/aidl/default/wifi_rtt_controller.cpp b/wifi/aidl/default/wifi_rtt_controller.cpp
index a5f6768..9dee45c 100644
--- a/wifi/aidl/default/wifi_rtt_controller.cpp
+++ b/wifi/aidl/default/wifi_rtt_controller.cpp
@@ -136,11 +136,45 @@
ndk::ScopedAStatus WifiRttController::rangeRequestInternal(
int32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
+ // Try 11mc & 11az ranging (v3)
+ std::vector<legacy_hal::wifi_rtt_config_v3> legacy_configs_v3;
+ if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacyV3(rtt_configs,
+ &legacy_configs_v3)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
+ const auto& on_results_callback_v3 =
+ [weak_ptr_this](legacy_hal::wifi_request_id id,
+ const std::vector<const legacy_hal::wifi_rtt_result_v3*>& results) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "v3 Callback invoked on an invalid object";
+ return;
+ }
+ std::vector<RttResult> aidl_results;
+ if (!aidl_struct_util::convertLegacyVectorOfRttResultV3ToAidl(results,
+ &aidl_results)) {
+ LOG(ERROR) << "Failed to convert rtt results v3 to AIDL structs";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onResults(id, aidl_results).isOk()) {
+ LOG(ERROR) << "Failed to invoke the v3 callback";
+ }
+ }
+ };
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequestV3(
+ ifname_, cmd_id, legacy_configs_v3, on_results_callback_v3);
+
+ if (legacy_status != legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
+ return createWifiStatusFromLegacyError(legacy_status);
+ }
+
+ // Fallback to 11mc ranging.
std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
}
- std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
const auto& on_results_callback =
[weak_ptr_this](legacy_hal::wifi_request_id id,
const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
@@ -181,7 +215,7 @@
}
}
};
- legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequest(
+ legacy_status = legacy_hal_.lock()->startRttRangeRequest(
ifname_, cmd_id, legacy_configs, on_results_callback, on_results_callback_v2);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -201,13 +235,29 @@
std::pair<RttCapabilities, ndk::ScopedAStatus> WifiRttController::getCapabilitiesInternal() {
legacy_hal::wifi_error legacy_status;
- legacy_hal::wifi_rtt_capabilities legacy_caps;
- std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+ legacy_hal::wifi_rtt_capabilities_v3 legacy_caps_v3;
+ std::tie(legacy_status, legacy_caps_v3) = legacy_hal_.lock()->getRttCapabilitiesV3(ifname_);
+ // Try v3 API first, if it is not supported fallback.
+ if (legacy_status == legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
+ legacy_hal::wifi_rtt_capabilities legacy_caps;
+ std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+
+ RttCapabilities aidl_caps;
+ if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ return {aidl_caps, ndk::ScopedAStatus::ok()};
+ }
+
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
}
+
RttCapabilities aidl_caps;
- if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
+ if (!aidl_struct_util::convertLegacyRttCapabilitiesV3ToAidl(legacy_caps_v3, &aidl_caps)) {
return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
}
return {aidl_caps, ndk::ScopedAStatus::ok()};
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
index 800813f..f0509dc 100644
--- a/wifi/aidl/default/wifi_sta_iface.cpp
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -219,6 +219,49 @@
&WifiStaIface::setDtimMultiplierInternal, in_multiplier);
}
+ndk::ScopedAStatus WifiStaIface::getCachedScanData(CachedScanData* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::getCachedScanDataInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtGetCapabilities(TwtCapabilities* _aidl_return) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtGetCapabilitiesInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSetup(int32_t in_cmdId,
+ const TwtRequest& in_twtRequest) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionSetupInternal, in_cmdId, in_twtRequest);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionUpdate(int32_t in_cmdId, int32_t in_sessionId,
+ const TwtRequest& in_twtRequest) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionUpdateInternal, in_cmdId, in_sessionId,
+ in_twtRequest);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSuspend(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionSuspendInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionResume(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionResumeInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionTeardown(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionTeardownInternal, in_cmdId, in_sessionId);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionGetStats(int32_t in_cmdId, int32_t in_sessionId) {
+ return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
+ &WifiStaIface::twtSessionGetStatsInternal, in_cmdId, in_sessionId);
+}
+
std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
return {ifname_, ndk::ScopedAStatus::ok()};
}
@@ -540,6 +583,209 @@
return createWifiStatusFromLegacyError(legacy_status);
}
+std::pair<CachedScanData, ndk::ScopedAStatus> WifiStaIface::getCachedScanDataInternal() {
+ legacy_hal::WifiCachedScanReport cached_scan_report;
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->getWifiCachedScanResults(ifname_, cached_scan_report);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {CachedScanData{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ CachedScanData aidl_scan_data;
+ if (!aidl_struct_util::convertCachedScanReportToAidl(cached_scan_report, &aidl_scan_data)) {
+ return {CachedScanData{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+
+ return {aidl_scan_data, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<TwtCapabilities, ndk::ScopedAStatus> WifiStaIface::twtGetCapabilitiesInternal() {
+ legacy_hal::wifi_twt_capabilities legacyHaltwtCapabilities;
+ legacy_hal::wifi_error legacy_status;
+ std::tie(legacyHaltwtCapabilities, legacy_status) =
+ legacy_hal_.lock()->twtGetCapabilities(ifname_);
+ if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+ return {TwtCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
+ }
+ TwtCapabilities aidlTwtCapabilities;
+ if (!aidl_struct_util::convertTwtCapabilitiesToAidl(legacyHaltwtCapabilities,
+ &aidlTwtCapabilities)) {
+ return {TwtCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+ }
+ return {aidlTwtCapabilities, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSetupInternal(int32_t cmdId,
+ const TwtRequest& aidlTwtRequest) {
+ legacy_hal::wifi_twt_request legacyHalTwtRequest;
+ if (!aidl_struct_util::convertAidlTwtRequestToLegacy(aidlTwtRequest, &legacyHalTwtRequest)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ std::weak_ptr<WifiStaIface> weak_ptr_this = weak_ptr_this_;
+
+ // onTwtFailure callback
+ const auto& on_twt_failure = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ legacy_hal::wifi_twt_error_code error_code) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ IWifiStaIfaceEventCallback::TwtErrorCode aidl_error_code =
+ aidl_struct_util::convertLegacyHalTwtErrorCodeToAidl(error_code);
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtFailure(id, aidl_error_code).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtFailure callback";
+ }
+ }
+ };
+ // onTwtSessionCreate callback
+ const auto& on_twt_session_create = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ legacy_hal::wifi_twt_session twt_session) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ TwtSession aidl_twt_session;
+ if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
+ LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
+ return;
+ }
+
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionCreate(id, aidl_twt_session).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionCreate callback";
+ }
+ }
+ };
+ // onTwtSessionUpdate callback
+ const auto& on_twt_session_update = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ legacy_hal::wifi_twt_session twt_session) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ TwtSession aidl_twt_session;
+ if (!aidl_struct_util::convertLegacyHalTwtSessionToAidl(twt_session, &aidl_twt_session)) {
+ LOG(ERROR) << "convertLegacyHalTwtSessionToAidl failed";
+ return;
+ }
+
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionUpdate(id, aidl_twt_session).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionUpdate callback";
+ }
+ }
+ };
+ // onTwtSessionTeardown callback
+ const auto& on_twt_session_teardown =
+ [weak_ptr_this](legacy_hal::wifi_request_id id, int session_id,
+ legacy_hal::wifi_twt_teardown_reason_code reason_code) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ IWifiStaIfaceEventCallback::TwtTeardownReasonCode aidl_reason_code =
+ aidl_struct_util::convertLegacyHalTwtReasonCodeToAidl(reason_code);
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionTeardown(id, session_id, aidl_reason_code).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionTeardown callback";
+ }
+ }
+ };
+ // onTwtSessionStats callback
+ const auto& on_twt_session_stats = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ int session_id,
+ legacy_hal::wifi_twt_session_stats stats) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ TwtSessionStats aidl_session_stats;
+ if (!aidl_struct_util::convertLegacyHalTwtSessionStatsToAidl(stats, &aidl_session_stats)) {
+ LOG(ERROR) << "convertLegacyHalTwtSessionStatsToAidl failed";
+ return;
+ }
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionStats(id, session_id, aidl_session_stats).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionStats callback";
+ }
+ }
+ };
+ // onTwtSessionSuspend callback
+ const auto& on_twt_session_suspend = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ int session_id) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionSuspend(id, session_id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionSuspend callback";
+ }
+ }
+ };
+ // onTwtSessionResume callback
+ const auto& on_twt_session_resume = [weak_ptr_this](legacy_hal::wifi_request_id id,
+ int session_id) {
+ const auto shared_ptr_this = weak_ptr_this.lock();
+ if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+ LOG(ERROR) << "Callback invoked on an invalid object";
+ return;
+ }
+ for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+ if (!callback->onTwtSessionResume(id, session_id).isOk()) {
+ LOG(ERROR) << "Failed to invoke onTwtSessionResume callback";
+ }
+ }
+ };
+
+ legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->twtSessionSetup(
+ ifname_, cmdId, legacyHalTwtRequest, on_twt_failure, on_twt_session_create,
+ on_twt_session_update, on_twt_session_teardown, on_twt_session_stats,
+ on_twt_session_suspend, on_twt_session_resume);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionUpdateInternal(int32_t cmdId, int32_t sessionId,
+ const TwtRequest& aidlTwtRequest) {
+ legacy_hal::wifi_twt_request legacyHalTwtRequest;
+ if (!aidl_struct_util::convertAidlTwtRequestToLegacy(aidlTwtRequest, &legacyHalTwtRequest)) {
+ return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+ }
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionUpdate(ifname_, cmdId, sessionId, legacyHalTwtRequest);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionSuspendInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionSuspend(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionResumeInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionResume(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionTeardownInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionTeardown(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
+ndk::ScopedAStatus WifiStaIface::twtSessionGetStatsInternal(int32_t cmdId, int32_t sessionId) {
+ legacy_hal::wifi_error legacy_status =
+ legacy_hal_.lock()->twtSessionGetStats(ifname_, cmdId, sessionId);
+ return createWifiStatusFromLegacyError(legacy_status);
+}
+
} // namespace wifi
} // namespace hardware
} // namespace android
diff --git a/wifi/aidl/default/wifi_sta_iface.h b/wifi/aidl/default/wifi_sta_iface.h
index 3d7ec4d..eb8f745 100644
--- a/wifi/aidl/default/wifi_sta_iface.h
+++ b/wifi/aidl/default/wifi_sta_iface.h
@@ -90,6 +90,15 @@
ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
ndk::ScopedAStatus setScanMode(bool in_enable) override;
ndk::ScopedAStatus setDtimMultiplier(int32_t in_multiplier) override;
+ ndk::ScopedAStatus getCachedScanData(CachedScanData* _aidl_return) override;
+ ndk::ScopedAStatus twtGetCapabilities(TwtCapabilities* _aidl_return) override;
+ ndk::ScopedAStatus twtSessionSetup(int in_cmdId, const TwtRequest& in_twtRequest) override;
+ ndk::ScopedAStatus twtSessionUpdate(int in_cmdId, int32_t in_sessionId,
+ const TwtRequest& in_twtRequest) override;
+ ndk::ScopedAStatus twtSessionSuspend(int in_cmdId, int32_t in_sessionId) override;
+ ndk::ScopedAStatus twtSessionResume(int in_cmdId, int32_t in_sessionId) override;
+ ndk::ScopedAStatus twtSessionTeardown(int in_cmdId, int32_t in_sessionId) override;
+ ndk::ScopedAStatus twtSessionGetStats(int in_cmdId, int32_t in_sessionId) override;
private:
// Corresponding worker functions for the AIDL methods.
@@ -130,6 +139,15 @@
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
ndk::ScopedAStatus setScanModeInternal(bool enable);
ndk::ScopedAStatus setDtimMultiplierInternal(const int multiplier);
+ std::pair<CachedScanData, ndk::ScopedAStatus> getCachedScanDataInternal();
+ std::pair<TwtCapabilities, ndk::ScopedAStatus> twtGetCapabilitiesInternal();
+ ndk::ScopedAStatus twtSessionSetupInternal(int cmdId, const TwtRequest& twtRequest);
+ ndk::ScopedAStatus twtSessionUpdateInternal(int cmdId, int32_t sessionId,
+ const TwtRequest& twtRequest);
+ ndk::ScopedAStatus twtSessionSuspendInternal(int cmdId, int32_t sessionId);
+ ndk::ScopedAStatus twtSessionResumeInternal(int cmdId, int32_t sessionId);
+ ndk::ScopedAStatus twtSessionTeardownInternal(int cmdId, int32_t sessionId);
+ ndk::ScopedAStatus twtSessionGetStatsInternal(int cmdId, int32_t sessionId);
void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index 76b0902..632927d 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -27,6 +27,9 @@
srcs: [
"android/hardware/wifi/supplicant/*.aidl",
],
+ imports: [
+ "android.hardware.wifi.common-V1",
+ ],
stability: "vintf",
backend: {
java: {
@@ -45,6 +48,9 @@
ndk: {
gen_trace: true,
},
+ cpp: {
+ enabled: false,
+ },
},
versions_with_info: [
{
@@ -58,5 +64,4 @@
],
frozen: false,
-
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 553cbc8..a0dd32f 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -40,4 +40,5 @@
int maxNumberRxSpatialStreams;
android.hardware.wifi.supplicant.LegacyMode legacyMode;
boolean apTidToLinkMapNegotiationSupported;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 19e6728..0729646 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -43,10 +43,16 @@
void cancelServiceDiscovery(in long identifier);
void cancelWps(in String groupIfName);
void configureExtListen(in int periodInMillis, in int intervalInMillis);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use connectWithParams.
+ */
String connect(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod, in String preSelectedPin, in boolean joinExistingGroup, in boolean persistent, in int goIntent);
byte[] createNfcHandoverRequestMessage();
byte[] createNfcHandoverSelectMessage();
void enableWfd(in boolean enable);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use findWithParams.
+ */
void find(in int timeoutInSec);
void flush();
void flushServices();
@@ -93,8 +99,16 @@
String startWpsPinDisplay(in String groupIfName, in byte[] bssid);
void startWpsPinKeypad(in String groupIfName, in String pin);
void stopFind();
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use findWithParams.
+ */
void findOnSocialChannels(in int timeoutInSec);
+ /**
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use findWithParams.
+ */
void findOnSpecificFrequency(in int freqInHz, in int timeoutInSec);
void setVendorElements(in android.hardware.wifi.supplicant.P2pFrameTypeMask frameTypeMask, in byte[] vendorElemBytes);
void configureEapolIpAddressAllocationParams(in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
+ String connectWithParams(in android.hardware.wifi.supplicant.P2pConnectInfo connectInfo);
+ void findWithParams(in android.hardware.wifi.supplicant.P2pDiscoveryInfo discoveryInfo);
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 8aa593f..851e851 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -34,6 +34,9 @@
package android.hardware.wifi.supplicant;
@VintfStability
interface ISupplicantP2pIfaceCallback {
+ /**
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onDeviceFoundWithParams.
+ */
oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo);
oneway void onDeviceLost(in byte[] p2pDeviceAddress);
oneway void onFindStopped();
@@ -60,9 +63,13 @@
*/
oneway void onStaDeauthorized(in byte[] srcAddress, in byte[] p2pDeviceAddress);
oneway void onGroupFrequencyChanged(in String groupIfname, in int frequency);
+ /**
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call onDeviceFoundWithParams.
+ */
oneway void onDeviceFoundWithVendorElements(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo, in byte[] wfdR2DeviceInfo, in byte[] vendorElemBytes);
oneway void onGroupStartedWithParams(in android.hardware.wifi.supplicant.P2pGroupStartedEventParams groupStartedEventParams);
oneway void onPeerClientJoined(in android.hardware.wifi.supplicant.P2pPeerClientJoinedEventParams clientJoinedEventParams);
oneway void onPeerClientDisconnected(in android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams clientDisconnectedEventParams);
oneway void onProvisionDiscoveryCompletedEvent(in android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
+ oneway void onDeviceFoundWithParams(in android.hardware.wifi.supplicant.P2pDeviceFoundEventParams deviceFoundEventParams);
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 1f3aa48..917668e 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -101,5 +101,7 @@
android.hardware.wifi.supplicant.SignalPollResult[] getSignalPollResults();
android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] addQosPolicyRequestForScs(in android.hardware.wifi.supplicant.QosPolicyScsData[] qosPolicyData);
android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
+ void configureMscs(in android.hardware.wifi.supplicant.MscsParams params);
+ void disableMscs();
const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index bfc05a4..488037f 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -129,6 +129,8 @@
void setRoamingConsortiumSelection(in byte[] selectedRcoi);
void setMinimumTlsVersionEapPhase1Param(android.hardware.wifi.supplicant.TlsVersion tlsVersion);
void setStrictConservativePeerMode(in boolean enable);
+ void disableEht();
+ void setVendorData(in android.hardware.wifi.common.OuiKeyedData[] vendorData);
const int SSID_MAX_LEN_IN_BYTES = 32;
const int PSK_PASSPHRASE_MIN_LEN_IN_BYTES = 8;
const int PSK_PASSPHRASE_MAX_LEN_IN_BYTES = 63;
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MscsParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MscsParams.aidl
new file mode 100644
index 0000000..aeed408
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MscsParams.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable MscsParams {
+ byte upBitmap;
+ byte upLimit;
+ int streamTimeoutUs;
+ byte frameClassifierMask;
+ @Backing(type="int") @VintfStability
+ enum FrameClassifierFields {
+ IP_VERSION = (1 << 0) /* 1 */,
+ SRC_IP_ADDR = (1 << 1) /* 2 */,
+ DST_IP_ADDR = (1 << 2) /* 4 */,
+ SRC_PORT = (1 << 3) /* 8 */,
+ DST_PORT = (1 << 4) /* 16 */,
+ DSCP = (1 << 5) /* 32 */,
+ PROTOCOL_NEXT_HDR = (1 << 6) /* 64 */,
+ FLOW_LABEL = (1 << 7) /* 128 */,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
new file mode 100644
index 0000000..792e08d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable MsduDeliveryInfo {
+ android.hardware.wifi.supplicant.MsduDeliveryInfo.DeliveryRatio deliveryRatio;
+ byte countExponent;
+ @Backing(type="byte") @VintfStability
+ enum DeliveryRatio {
+ RATIO_95 = 1,
+ RATIO_96 = 2,
+ RATIO_97 = 3,
+ RATIO_98 = 4,
+ RATIO_99 = 5,
+ RATIO_99_9 = 6,
+ RATIO_99_99 = 7,
+ RATIO_99_999 = 8,
+ RATIO_99_9999 = 9,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
new file mode 100644
index 0000000..f4662de
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable P2pConnectInfo {
+ byte[6] peerAddress;
+ android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod;
+ String preSelectedPin;
+ boolean joinExistingGroup;
+ boolean persistent;
+ int goIntent;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
new file mode 100644
index 0000000..ee8e6dc
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable P2pDeviceFoundEventParams {
+ byte[6] srcAddress;
+ byte[6] p2pDeviceAddress;
+ byte[] primaryDeviceType;
+ String deviceName;
+ int configMethods;
+ byte deviceCapabilities;
+ int groupCapabilities;
+ byte[] wfdDeviceInfo;
+ byte[] wfdR2DeviceInfo;
+ byte[] vendorElemBytes;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
new file mode 100644
index 0000000..5b7dd3f
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable P2pDiscoveryInfo {
+ android.hardware.wifi.supplicant.P2pScanType scanType;
+ int frequencyMhz;
+ int timeoutInSec;
+ @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pScanType.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pScanType.aidl
new file mode 100644
index 0000000..ff3efd2
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pScanType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum P2pScanType {
+ FULL,
+ SOCIAL,
+ SPECIFIC_FREQ,
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl
new file mode 100644
index 0000000..dacac8c
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosCharacteristics.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.wifi.supplicant;
+@VintfStability
+parcelable QosCharacteristics {
+ int minServiceIntervalUs;
+ int maxServiceIntervalUs;
+ int minDataRateKbps;
+ int delayBoundUs;
+ int optionalFieldMask;
+ char maxMsduSizeOctets;
+ int serviceStartTimeUs;
+ byte serviceStartTimeLinkId;
+ int meanDataRateKbps;
+ int burstSizeOctets;
+ char msduLifetimeMs;
+ android.hardware.wifi.supplicant.MsduDeliveryInfo msduDeliveryInfo;
+ @Backing(type="int") @VintfStability
+ enum QosCharacteristicsMask {
+ MAX_MSDU_SIZE = (1 << 0) /* 1 */,
+ SERVICE_START_TIME = (1 << 1) /* 2 */,
+ SERVICE_START_TIME_LINK_ID = (1 << 2) /* 4 */,
+ MEAN_DATA_RATE = (1 << 3) /* 8 */,
+ BURST_SIZE = (1 << 4) /* 16 */,
+ MSDU_LIFETIME = (1 << 5) /* 32 */,
+ MSDU_DELIVERY_INFO = (1 << 6) /* 64 */,
+ }
+}
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
index 4e5e8ae..20be616 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -22,4 +22,11 @@
byte policyId;
byte userPriority;
android.hardware.wifi.supplicant.QosPolicyClassifierParams classifierParams;
+ android.hardware.wifi.supplicant.QosPolicyScsData.LinkDirection direction;
+ @nullable android.hardware.wifi.supplicant.QosCharacteristics QosCharacteristics;
+ @Backing(type="byte") @VintfStability
+ enum LinkDirection {
+ DOWNLINK,
+ UPLINK,
+ }
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
index 4921a67..64a515f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ConnectionCapabilities.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.LegacyMode;
import android.hardware.wifi.supplicant.WifiTechnology;
@@ -48,4 +49,9 @@
* Indicates the AP support for TID-to-link mapping negotiation.
*/
boolean apTidToLinkMapNegotiationSupported;
+ /**
+ * Additional vendor-specific data. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index e58422c..983ed15 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -16,11 +16,14 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.FreqRange;
import android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback;
import android.hardware.wifi.supplicant.ISupplicantP2pNetwork;
import android.hardware.wifi.supplicant.IfaceType;
import android.hardware.wifi.supplicant.MiracastMode;
+import android.hardware.wifi.supplicant.P2pConnectInfo;
+import android.hardware.wifi.supplicant.P2pDiscoveryInfo;
import android.hardware.wifi.supplicant.P2pFrameTypeMask;
import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
import android.hardware.wifi.supplicant.WpsConfigMethods;
@@ -176,6 +179,9 @@
* Start P2P group formation with a discovered P2P peer. This includes
* optional group owner negotiation, group interface setup, provisioning,
* and establishing data connection.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * connectWithParams.
*
* @param peerAddress MAC address of the device to connect to.
* @param provisionMethod Provisioning method to use.
@@ -236,6 +242,9 @@
/**
* Initiate a P2P service discovery with an optional timeout.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * findWithParams.
*
* @param timeoutInSec Max time to be spent is performing discovery.
* Set to 0 to indefinitely continue discovery until an explicit
@@ -782,8 +791,9 @@
/**
* Initiate a P2P device discovery only on social channels.
- *
- * Full P2P discovery is performed through |ISupplicantP2pIface.find| method.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * findWithParams.
*
* @param timeoutInSec The maximum amount of time that should be spent in performing device
* discovery.
@@ -798,8 +808,9 @@
/**
* Initiate a P2P device discovery on a specific frequency.
- *
- * Full P2P discovery is performed through |ISupplicantP2pIface.find| method.
+ * <p>
+ * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+ * findWithParams.
*
* @param freqInHz the frequency to be scanned.
* @param timeoutInSec Max time to be spent is performing discovery.
@@ -845,4 +856,30 @@
*/
void configureEapolIpAddressAllocationParams(
in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
+
+ /**
+ * Start P2P group formation with a discovered P2P peer. This includes
+ * optional group owner negotiation, group interface setup, provisioning,
+ * and establishing data connection.
+ *
+ * @param connectInfo Parameters associated with this connection request.
+ * @return Pin generated, if |provisionMethod| uses one of the
+ * generated |PIN*| methods.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ */
+ String connectWithParams(in P2pConnectInfo connectInfo);
+
+ /**
+ * Initiate a P2P service discovery with an optional timeout.
+ *
+ * @param discoveryInfo Parameters associated with this discovery request.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+ * |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
+ */
+ void findWithParams(in P2pDiscoveryInfo discoveryInfo);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 8befc0d..11cd867 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.supplicant.P2pDeviceFoundEventParams;
import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
import android.hardware.wifi.supplicant.P2pGroupStartedEventParams;
import android.hardware.wifi.supplicant.P2pPeerClientDisconnectedEventParams;
@@ -38,6 +39,9 @@
oneway interface ISupplicantP2pIfaceCallback {
/**
* Used to indicate that a P2P device has been found.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+ * onDeviceFoundWithParams.
*
* @param srcAddress MAC address of the device found. This must either
* be the P2P device address or the P2P interface address.
@@ -228,6 +232,9 @@
/**
* Used to indicate that a P2P device has been found.
+ * <p>
+ * @deprecated This callback is deprecated from AIDL v3, newer HAL should call
+ * onDeviceFoundWithParams.
*
* @param srcAddress MAC address of the device found. This must either
* be the P2P device address for a peer which is not in a group,
@@ -288,4 +295,11 @@
*/
void onProvisionDiscoveryCompletedEvent(
in P2pProvisionDiscoveryCompletedEventParams provisionDiscoveryCompletedEventParams);
+
+ /**
+ * Used to indicate that a P2P device has been found.
+ *
+ * @param deviceFoundEventParams Parameters associated with the device found event.
+ */
+ void onDeviceFoundWithParams(in P2pDeviceFoundEventParams deviceFoundEventParams);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index d7b4e62..fb1673e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -29,6 +29,7 @@
import android.hardware.wifi.supplicant.IfaceType;
import android.hardware.wifi.supplicant.KeyMgmtMask;
import android.hardware.wifi.supplicant.MloLinksInfo;
+import android.hardware.wifi.supplicant.MscsParams;
import android.hardware.wifi.supplicant.QosPolicyScsData;
import android.hardware.wifi.supplicant.QosPolicyScsRequestStatus;
import android.hardware.wifi.supplicant.QosPolicyStatus;
@@ -852,4 +853,28 @@
* being processed. Supplicant will only handle one request at a time.
*/
QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
+
+ /**
+ * Enable Mirrored Stream Classification Service (MSCS) and configure using
+ * the provided configuration values.
+ *
+ * If MSCS has already been enabled/configured, this will overwrite the
+ * existing configuration.
+ *
+ * @param params |MscsParams| object containing the configuration.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_ARGS_INVALID| if the configuration is invalid.
+ * |SupplicantStatusCode.FAILURE_UNKNOWN| if the configuration could not be set.
+ */
+ void configureMscs(in MscsParams params);
+
+ /**
+ * Disable Mirrored Stream Classification Service (MSCS).
+ *
+ * If MSCS is enabled/configured, this will send a remove request to the AP.
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|
+ */
+ void disableMscs();
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
index 750cf72..fc7babf 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.aidl
@@ -16,6 +16,7 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.common.OuiKeyedData;
import android.hardware.wifi.supplicant.AuthAlgMask;
import android.hardware.wifi.supplicant.DppConnectionKeys;
import android.hardware.wifi.supplicant.EapMethod;
@@ -1141,4 +1142,27 @@
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
void setStrictConservativePeerMode(in boolean enable);
+
+ /**
+ * Disables Extremely High Throughput (EHT) mode, aka Wi-Fi 7 support, for the network. When
+ * EHT is disabled, the device ceases to transmit EHT related Information Elements (IEs),
+ * including multi-link IEs and EHT capability, in subsequent messages such as (Re)Association
+ * requests to the Access Point (AP).
+ *
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void disableEht();
+
+ /**
+ * Set additional vendor-provided configuration data.
+ *
+ * @param vendorData List of |OuiKeyedData| containing the vendor-provided
+ * configuration data.
+ * @throws ServiceSpecificException with one of the following values:
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ * |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
+ */
+ void setVendorData(in OuiKeyedData[] vendorData);
}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MscsParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MscsParams.aidl
new file mode 100644
index 0000000..b1731ac
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MscsParams.aidl
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Mirrored Stream Classification Service (MSCS) parameters.
+ * Refer to section 3.1 of the Wi-Fi QoS Management Specification v3.0.
+ */
+@VintfStability
+parcelable MscsParams {
+ /**
+ * Bitmap indicating which User Priorities should be classified using MSCS.
+ * The least significant bit corresponds to UP 0, and the most significant
+ * bit to UP 7. Setting a bit to 1 indicates that UP should be used.
+ */
+ byte upBitmap;
+
+ /**
+ * Maximum user priority that can be assigned using the MSCS service.
+ * Value must be between 0 and 7 (inclusive).
+ */
+ byte upLimit;
+
+ /**
+ * Stream timeout in μs. Must be equivalent to 60 sec or less.
+ */
+ int streamTimeoutUs;
+
+ /**
+ * Bitmask of available fields for a Type 4 TCLAS frame classifier.
+ * See Figures 9-309 and 9-310 in the IEEE Std 802.11-2020 Standard.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum FrameClassifierFields {
+ IP_VERSION = 1 << 0,
+ SRC_IP_ADDR = 1 << 1,
+ DST_IP_ADDR = 1 << 2,
+ SRC_PORT = 1 << 3,
+ DST_PORT = 1 << 4,
+ DSCP = 1 << 5,
+ /** Indicates Protocol if using IPv4, or Next Header if using IPv6. */
+ PROTOCOL_NEXT_HDR = 1 << 6,
+ /** Only applicable if using IPv6. */
+ FLOW_LABEL = 1 << 7,
+ }
+
+ /**
+ * Bitmask of |FrameClassifierFields| for a Type 4 TCLAS frame classifier.
+ */
+ byte frameClassifierMask;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
new file mode 100644
index 0000000..8065f63
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MsduDeliveryInfo.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * MSDU delivery information.
+ * See Section 9.4.2.316 of the IEEE P802.11be/D4.0 Standard.
+ */
+@VintfStability
+parcelable MsduDeliveryInfo {
+ /**
+ * Enums for the |deliveryRatio| field.
+ * See Table 9-404t of the IEEE P802.11be/D4.0 Standard.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum DeliveryRatio {
+ RATIO_95 = 1, // 95%
+ RATIO_96 = 2, // 96%
+ RATIO_97 = 3, // 97%
+ RATIO_98 = 4, // 98%
+ RATIO_99 = 5, // 99%
+ RATIO_99_9 = 6, // 99.9%
+ RATIO_99_99 = 7, // 99.99%
+ RATIO_99_999 = 8, // 99.999%
+ RATIO_99_9999 = 9, // 99.9999%
+ }
+
+ /**
+ * Percentage of the MSDUs that are expected to be delivered successfully.
+ */
+ DeliveryRatio deliveryRatio;
+
+ /**
+ * Exponent from which the number of incoming MSDUs is computed. The number of incoming
+ * MSDUs is 10^countExponent, and is used to determine the MSDU delivery ratio.
+ * Must be a number between 0 and 15 (inclusive).
+ */
+ byte countExponent;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
new file mode 100644
index 0000000..f09b476
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.WpsProvisionMethod;
+
+/**
+ * Request parameters used for |ISupplicantP2pIface.connectWithParams|
+ */
+@VintfStability
+parcelable P2pConnectInfo {
+ /**
+ * MAC address of the device to connect to.
+ */
+ byte[6] peerAddress;
+
+ /**
+ * Provisioning method to use.
+ */
+ WpsProvisionMethod provisionMethod;
+
+ /**
+ * Pin to be used, if |provisionMethod| uses one of the
+ * preselected |PIN*| methods.
+ */
+ String preSelectedPin;
+
+ /**
+ * Indicates that this is a command to join an existing group as a client.
+ * This means that the group owner negotiation step can be skipped.
+ * This must send a Provision Discovery Request message to the
+ * target group owner before associating for WPS provisioning.
+ */
+ boolean joinExistingGroup;
+
+ /**
+ * Used to request a persistent group to be formed.
+ */
+ boolean persistent;
+
+ /**
+ * Used to override the default Intent for this group owner
+ * negotiation (Values from 1-15). Refer to section 4.1.6 in
+ * Wi-Fi Peer-to-Peer (P2P) Technical Specification Version 1.7.
+ */
+ int goIntent;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
new file mode 100644
index 0000000..15917b6
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters passed as a part of a P2P Device found event.
+ */
+@VintfStability
+parcelable P2pDeviceFoundEventParams {
+ /**
+ * MAC address of the device found. This must either be the P2P device address
+ * for a peer which is not in a group, or the P2P interface address for
+ * a peer which is a Group Owner.
+ */
+ byte[6] srcAddress;
+
+ /**
+ * P2P device address.
+ */
+ byte[6] p2pDeviceAddress;
+
+ /**
+ * Type of device. Refer to section B.1 of the Wifi P2P Technical
+ * specification v1.2.
+ */
+ byte[] primaryDeviceType;
+
+ /**
+ * Name of the device.
+ */
+ String deviceName;
+
+ /**
+ * Mask of |WpsConfigMethods| indicating the WPS configuration methods
+ * supported by the device.
+ */
+ int configMethods;
+
+ /**
+ * Refer to section 4.1.4 of the Wifi P2P Technical specification v1.2.
+ */
+ byte deviceCapabilities;
+
+ /**
+ * Mask of |P2pGroupCapabilityMask| indicating the group capabilities.
+ * Refer to section 4.1.4 of the Wifi P2P Technical specification v1.2.
+ */
+ int groupCapabilities;
+
+ /**
+ * WFD device info as described in section 5.1.2 of the WFD technical
+ * specification v1.0.0.
+ */
+ byte[] wfdDeviceInfo;
+
+ /**
+ * WFD R2 device info as described in section 5.1.12 of WFD technical
+ * specification v2.1.
+ */
+ byte[] wfdR2DeviceInfo;
+
+ /**
+ * Vendor-specific information element bytes. The format of an
+ * information element is EID (1 byte) + Length (1 Byte) + Payload which is
+ * defined in Section 9.4.4 TLV encodings of 802.11-2016 IEEE Standard for
+ * Information technology. The length indicates the size of the payload.
+ * Multiple information elements may be appended within the byte array.
+ */
+ byte[] vendorElemBytes;
+
+ /**
+ * Optional vendor-specific data.
+ * Null value indicates that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
new file mode 100644
index 0000000..ddb8a3d
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDiscoveryInfo.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.P2pScanType;
+
+/**
+ * Request parameters used for |ISupplicantP2pIface.findWithParams|
+ */
+@VintfStability
+parcelable P2pDiscoveryInfo {
+ /**
+ * P2P scan type.
+ */
+ P2pScanType scanType;
+
+ /**
+ * Frequency to scan in MHz. Only valid the scan type is |P2pScanType.SPECIFIC_FREQ|
+ */
+ int frequencyMhz;
+
+ /**
+ * Max time, in seconds, to be spent in performing discovery.
+ * Set to 0 to indefinitely continue discovery until an explicit
+ * |stopFind| is sent.
+ */
+ int timeoutInSec;
+
+ /**
+ * Optional vendor-specific parameters. Null value indicates
+ * that no vendor data is provided.
+ */
+ @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pScanType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pScanType.aidl
new file mode 100644
index 0000000..1ab14c4
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pScanType.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Scan types used in P2P.
+ */
+@VintfStability
+@Backing(type="int")
+enum P2pScanType {
+ /**
+ * All channels.
+ */
+ FULL,
+ /**
+ * Social channels.
+ */
+ SOCIAL,
+ /**
+ * Specific channel.
+ */
+ SPECIFIC_FREQ,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl
new file mode 100644
index 0000000..be5ef91
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosCharacteristics.aidl
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.MsduDeliveryInfo;
+
+/**
+ * Additional QoS parameters as defined in Section 9.4.2.316
+ * of the IEEE P802.11be/D4.0 Standard.
+ */
+@VintfStability
+parcelable QosCharacteristics {
+ /**
+ * Unsigned integer specifying the minimum interval (in microseconds) between the start of
+ * two consecutive service periods (SPs) that are allocated for frame exchanges.
+ * The value must be non-zero.
+ */
+ int minServiceIntervalUs;
+
+ /**
+ * Unsigned integer specifying the maximum interval (in microseconds) between the start of two
+ * consecutive SPs that are allocated for frame exchanges. The value must be non-zero.
+ */
+ int maxServiceIntervalUs;
+
+ /**
+ * Unsigned integer specifying the lowest data rate (in kilobits/sec)
+ * for the transport of MSDUs or A-MSDUs belonging to the traffic flow.
+ * The value must be non-zero.
+ */
+ int minDataRateKbps;
+
+ /**
+ * Unsigned integer specifying the maximum amount of time (in microseconds)
+ * targeted to transport an MSDU or A-MSDU belonging to the traffic flow.
+ * The value must be non-zero.
+ */
+ int delayBoundUs;
+
+ /**
+ * Enum values indicating which optional fields are provided.
+ * See Figure 9-1001au of the IEEE P802.11be/D4.0 Standard.
+ */
+ @VintfStability
+ @Backing(type="int")
+ enum QosCharacteristicsMask {
+ MAX_MSDU_SIZE = 1 << 0,
+ SERVICE_START_TIME = 1 << 1,
+ SERVICE_START_TIME_LINK_ID = 1 << 2,
+ MEAN_DATA_RATE = 1 << 3,
+ BURST_SIZE = 1 << 4,
+ MSDU_LIFETIME = 1 << 5,
+ MSDU_DELIVERY_INFO = 1 << 6,
+ }
+
+ /**
+ * Mask of |QosCharacteristicsMask| indicating which optional fields are provided.
+ */
+ int optionalFieldMask;
+
+ /**
+ * Unsigned 16-bit value specifying the maximum size (in octets) of an MSDU
+ * belonging to the traffic flow. The value must be non-zero if provided.
+ */
+ char maxMsduSizeOctets;
+
+ /**
+ * Unsigned integer specifying the anticipated time (in microseconds) when
+ * the traffic starts for the associated TID.
+ */
+ int serviceStartTimeUs;
+
+ /**
+ * The four LSBs indicate the link identifier that corresponds to the link for which the
+ * TSF timer is used to indicate the Service Start Time. The four MSBs should not be used.
+ * This field is present if |serviceStartTimeUs| is included and is not present otherwise.
+ */
+ byte serviceStartTimeLinkId;
+
+ /**
+ * Unsigned integer indicating the data rate specified (in kilobits/sec) for transport of MSDUs
+ * or A-MSDUs belonging to the traffic flow. The value must be non-zero if provided.
+ */
+ int meanDataRateKbps;
+
+ /**
+ * Unsigned integer specififying the maximum burst (in octets) of the MSDUs or A-MSDUs
+ * belonging to the traffic flow that arrive at the MAC SAP within any time duration equal
+ * to the value specified in the |delayBound| field. The value must be non-zero if provided.
+ */
+ int burstSizeOctets;
+
+ /**
+ * Unsigned 16-bit integer specifying the maximum amount of time (in milliseconds) since the
+ * arrival of the MSDU at the MAC data service interface beyond which the MSDU is not useful
+ * even if received by the receiver. The amount of time specified in this field is larger than
+ * or equal to the amount of time specified in the |delayBound| field, if present. The value
+ * must be non-zero if provided.
+ */
+ char msduLifetimeMs;
+
+ /**
+ * MSDU delivery information. See |MsduDeliveryInfo| for more details.
+ */
+ MsduDeliveryInfo msduDeliveryInfo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
index 86a4dac..76f5a9a 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/QosPolicyScsData.aidl
@@ -1,5 +1,6 @@
package android.hardware.wifi.supplicant;
+import android.hardware.wifi.supplicant.QosCharacteristics;
import android.hardware.wifi.supplicant.QosPolicyClassifierParams;
/**
@@ -21,4 +22,24 @@
* QoS policy SCS classifier type information.
*/
QosPolicyClassifierParams classifierParams;
+
+ /**
+ * Enum values for the |direction| field.
+ */
+ @VintfStability
+ @Backing(type="byte")
+ enum LinkDirection {
+ DOWNLINK,
+ UPLINK, // Only applies to trigger-based traffic (Wi-Fi 6+)
+ }
+
+ /**
+ * Direction of data described by this element.
+ */
+ LinkDirection direction;
+
+ /**
+ * Additional parameters available in QoS R3.
+ */
+ @nullable QosCharacteristics QosCharacteristics;
}
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 4eec180..b2356a0 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -42,6 +42,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi.common-V1-ndk",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V3-ndk",
@@ -78,6 +79,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi.common-V1-ndk",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V3-ndk",
@@ -114,6 +116,7 @@
"android.hardware.wifi@1.3",
"android.hardware.wifi@1.4",
"android.hardware.wifi@1.5",
+ "android.hardware.wifi.common-V1-ndk",
"android.hardware.wifi.supplicant@1.0",
"android.hardware.wifi.supplicant@1.1",
"android.hardware.wifi.supplicant-V3-ndk",
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index 0db1653..3f96414 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -35,6 +35,7 @@
using aidl::android::hardware::wifi::supplicant::ISupplicant;
using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::MiracastMode;
+using aidl::android::hardware::wifi::supplicant::P2pDeviceFoundEventParams;
using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
@@ -199,6 +200,10 @@
/* provisionDiscoveryCompletedEventParams */) override {
return ndk::ScopedAStatus::ok();
}
+ ::ndk::ScopedAStatus onDeviceFoundWithParams(
+ const P2pDeviceFoundEventParams& /* deviceFoundEventParams */) override {
+ return ndk::ScopedAStatus::ok();
+ }
};
class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
index 973b56a..7574141 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_network_aidl_test.cpp
@@ -822,6 +822,13 @@
tlsV13Supported);
}
+/*
+ * disableEht
+ */
+TEST_P(SupplicantStaNetworkAidlTest, DisableEht) {
+ EXPECT_TRUE(sta_network_->disableEht().isOk());
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantStaNetworkAidlTest);
INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantStaNetworkAidlTest,
testing::ValuesIn(android::getAidlHalInstanceNames(